From 0714a8d2ef16bceb81e278ab62a5754224b51854 Mon Sep 17 00:00:00 2001 From: nabenabe0928 Date: Thu, 28 Dec 2023 06:01:19 +0100 Subject: [PATCH 01/98] Refactor value comparator --- optuna_dashboard/ts/components/TrialTable.tsx | 93 ++++++++----------- 1 file changed, 37 insertions(+), 56 deletions(-) diff --git a/optuna_dashboard/ts/components/TrialTable.tsx b/optuna_dashboard/ts/components/TrialTable.tsx index efc79626..c2e4a650 100644 --- a/optuna_dashboard/ts/components/TrialTable.tsx +++ b/optuna_dashboard/ts/components/TrialTable.tsx @@ -23,29 +23,37 @@ export const TrialTable: FC<{ toCellValue: (i) => trials[i].state.toString(), }, ] + const valueComparator = ( + firstVal?: TrialValueNumber, + secondVal?: TrialValueNumber, + ascending: boolean = true + ): number => { + if (firstVal === secondVal) { + return 0 + } + if (firstVal === undefined) { + return ascending ? -1 : 1 + } else if (secondVal === undefined) { + return ascending ? 1 : -1 + } + if (firstVal === "-inf" || secondVal === "inf") { + return 1 + } else if (secondVal === "-inf" || firstVal === "inf") { + return -1 + } + return firstVal < secondVal ? 1 : -1 + } if (studyDetail === null || studyDetail.directions.length === 1) { columns.push({ field: "values", label: "Value", sortable: true, less: (firstEl, secondEl, ascending): number => { - const firstVal = firstEl.values?.[0] - const secondVal = secondEl.values?.[0] - - if (firstVal === secondVal) { - return 0 - } - if (firstVal === undefined) { - return ascending ? -1 : 1 - } else if (secondVal === undefined) { - return ascending ? 1 : -1 - } - if (firstVal === "-inf" || secondVal === "inf") { - return 1 - } else if (secondVal === "-inf" || firstVal === "inf") { - return -1 - } - return firstVal < secondVal ? 1 : -1 + return valueComparator( + firstEl.values?.[0], + secondEl.values?.[0], + ascending + ) }, toCellValue: (i) => { if (trials[i].values === undefined) { @@ -64,23 +72,11 @@ export const TrialTable: FC<{ : `Objective ${objectiveId}`, sortable: true, less: (firstEl, secondEl, ascending): number => { - const firstVal = firstEl.values?.[objectiveId] - const secondVal = secondEl.values?.[objectiveId] - - if (firstVal === secondVal) { - return 0 - } - if (firstVal === undefined) { - return ascending ? -1 : 1 - } else if (secondVal === undefined) { - return ascending ? 1 : -1 - } - if (firstVal === "-inf" || secondVal === "inf") { - return 1 - } else if (secondVal === "-inf" || firstVal === "inf") { - return -1 - } - return firstVal < secondVal ? 1 : -1 + return valueComparator( + firstEl.values?.[objectiveId], + secondEl.values?.[objectiveId], + ascending + ) }, toCellValue: (i) => { if (trials[i].values === undefined) { @@ -117,16 +113,7 @@ export const TrialTable: FC<{ const secondVal = secondEl.params.find( (p) => p.name === s.name )?.param_internal_value - - if (firstVal === secondVal) { - return 0 - } else if (firstVal && secondVal) { - return firstVal < secondVal ? 1 : -1 - } else if (firstVal) { - return -1 - } else { - return 1 - } + return valueComparator(firstVal, secondVal) }, }) }) @@ -151,22 +138,16 @@ export const TrialTable: FC<{ sortable: attr_spec.sortable, // eslint-disable-next-line @typescript-eslint/no-unused-vars less: (firstEl, secondEl, _): number => { - const firstVal = firstEl.user_attrs.find( + const firstValString = firstEl.user_attrs.find( (attr) => attr.key === attr_spec.key )?.value - const secondVal = secondEl.user_attrs.find( + const secondValString = secondEl.user_attrs.find( (attr) => attr.key === attr_spec.key )?.value - - if (firstVal === secondVal) { - return 0 - } else if (firstVal && secondVal) { - return Number(firstVal) < Number(secondVal) ? 1 : -1 - } else if (firstVal) { - return -1 - } else { - return 1 - } + return valueComparator( + Number(firstValString) ?? firstValString, + Number(secondValString) ?? secondValString + ) }, }) }) From 8e86bc6c0e51ae81b03271b9b1978e860a1dc841 Mon Sep 17 00:00:00 2001 From: nabenabe0928 Date: Thu, 28 Dec 2023 06:58:46 +0100 Subject: [PATCH 02/98] Adapt to categorical dynamic without null --- optuna_dashboard/ts/components/DataGrid.tsx | 2 +- optuna_dashboard/ts/components/TrialTable.tsx | 58 +++++++------------ 2 files changed, 23 insertions(+), 37 deletions(-) diff --git a/optuna_dashboard/ts/components/DataGrid.tsx b/optuna_dashboard/ts/components/DataGrid.tsx index adf64e77..9763d103 100644 --- a/optuna_dashboard/ts/components/DataGrid.tsx +++ b/optuna_dashboard/ts/components/DataGrid.tsx @@ -33,7 +33,7 @@ interface DataGridColumn { label: string sortable?: boolean less?: (a: T, b: T, ascending: boolean) => number - filterChoices?: string[] + filterChoices?: (string | null)[] toCellValue?: (rowIndex: number) => string | React.ReactNode padding?: "normal" | "checkbox" | "none" } diff --git a/optuna_dashboard/ts/components/TrialTable.tsx b/optuna_dashboard/ts/components/TrialTable.tsx index c2e4a650..daf39439 100644 --- a/optuna_dashboard/ts/components/TrialTable.tsx +++ b/optuna_dashboard/ts/components/TrialTable.tsx @@ -87,46 +87,32 @@ export const TrialTable: FC<{ })) columns.push(...objectiveColumns) } - if ( - studyDetail?.union_search_space.length === - studyDetail?.intersection_search_space.length - ) { - studyDetail?.intersection_search_space.forEach((s) => { - const sortable = s.distribution.type !== "CategoricalDistribution" - const filterChoices = - s.distribution.type === "CategoricalDistribution" - ? s.distribution.choices.map((c) => c.value) - : undefined - columns.push({ - field: "params", - label: `Param ${s.name}`, - toCellValue: (i) => - trials[i].params.find((p) => p.name === s.name) - ?.param_external_value || null, - sortable: sortable, - filterChoices: filterChoices, - // eslint-disable-next-line @typescript-eslint/no-unused-vars - less: (firstEl, secondEl, _): number => { - const firstVal = firstEl.params.find( - (p) => p.name === s.name - )?.param_internal_value - const secondVal = secondEl.params.find( - (p) => p.name === s.name - )?.param_internal_value - return valueComparator(firstVal, secondVal) - }, - }) - }) - } else { + studyDetail?.union_search_space.forEach((s) => { + const sortable = s.distribution.type !== "CategoricalDistribution" + const filterChoices = + s.distribution.type === "CategoricalDistribution" + ? s.distribution.choices.map((c) => c.value) + : undefined columns.push({ field: "params", - label: "Params", + label: `Param ${s.name}`, toCellValue: (i) => - trials[i].params - .map((p) => p.name + ": " + p.param_external_value) - .join(", "), + trials[i].params.find((p) => p.name === s.name) + ?.param_external_value || null, + sortable: sortable, + filterChoices: filterChoices, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + less: (firstEl, secondEl, _): number => { + const firstVal = firstEl.params.find( + (p) => p.name === s.name + )?.param_internal_value + const secondVal = secondEl.params.find( + (p) => p.name === s.name + )?.param_internal_value + return valueComparator(firstVal, secondVal) + }, }) - } + }) studyDetail?.union_user_attrs.forEach((attr_spec) => { columns.push({ From 797a8cdce5c1541e25f8ec96a913432444fdf123 Mon Sep 17 00:00:00 2001 From: nabenabe0928 Date: Thu, 28 Dec 2023 07:37:39 +0100 Subject: [PATCH 03/98] Add missing value filter --- optuna_dashboard/ts/components/DataGrid.tsx | 2 +- optuna_dashboard/ts/components/TrialTable.tsx | 12 +++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/optuna_dashboard/ts/components/DataGrid.tsx b/optuna_dashboard/ts/components/DataGrid.tsx index 9763d103..93c95eb2 100644 --- a/optuna_dashboard/ts/components/DataGrid.tsx +++ b/optuna_dashboard/ts/components/DataGrid.tsx @@ -282,7 +282,7 @@ function DataGridHeaderColumn(props: { )} - {choice} + {choice ?? "(missing value)"} ))} diff --git a/optuna_dashboard/ts/components/TrialTable.tsx b/optuna_dashboard/ts/components/TrialTable.tsx index daf39439..bd26921b 100644 --- a/optuna_dashboard/ts/components/TrialTable.tsx +++ b/optuna_dashboard/ts/components/TrialTable.tsx @@ -87,20 +87,26 @@ export const TrialTable: FC<{ })) columns.push(...objectiveColumns) } + const isDynamicSpace = + studyDetail?.union_search_space.length !== + studyDetail?.intersection_search_space.length studyDetail?.union_search_space.forEach((s) => { const sortable = s.distribution.type !== "CategoricalDistribution" const filterChoices = s.distribution.type === "CategoricalDistribution" ? s.distribution.choices.map((c) => c.value) : undefined + const filterChoicesWithNull: (string | null)[] | undefined = filterChoices + ? [...filterChoices, null] + : undefined columns.push({ field: "params", label: `Param ${s.name}`, toCellValue: (i) => - trials[i].params.find((p) => p.name === s.name) - ?.param_external_value || null, + trials[i].params.find((p) => p.name === s.name)?.param_external_value || + null, sortable: sortable, - filterChoices: filterChoices, + filterChoices: isDynamicSpace ? filterChoicesWithNull : filterChoices, // eslint-disable-next-line @typescript-eslint/no-unused-vars less: (firstEl, secondEl, _): number => { const firstVal = firstEl.params.find( From 0dfe9a7cabb99df411322bcce46cb12e1e12017e Mon Sep 17 00:00:00 2001 From: keisuke-umezawa Date: Sat, 27 Jan 2024 14:41:14 +0900 Subject: [PATCH 04/98] Add e2e test for loading journal storage --- e2e_tests/test_standalone/test_study_list.py | 50 +++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/e2e_tests/test_standalone/test_study_list.py b/e2e_tests/test_standalone/test_study_list.py index e84a7f5a..3c588aed 100644 --- a/e2e_tests/test_standalone/test_study_list.py +++ b/e2e_tests/test_standalone/test_study_list.py @@ -25,7 +25,7 @@ def test_home( assert title == "Optuna Dashboard (Wasm ver.)" -def test_load_storage( +def test_load_rdb_storage( page: Page, server_url: str, ) -> None: @@ -69,3 +69,51 @@ def test_load_storage( count = count_components(page, "MuiCard-root") assert count == 4 + + +def test_load_journal_storage( + page: Page, + server_url: str, +) -> None: + study_name = "single-objective" + url = f"{server_url}" + + def create_storage_file(filename: str): + import optuna + + storage = optuna.storages.JournalStorage( + optuna.storages.JournalFileStorage(f"{filename}"), + ) + study = optuna.create_study(study_name=study_name, storage=storage) + + def objective(trial: optuna.Trial) -> float: + x1 = trial.suggest_float("x1", 0, 10) + x2 = trial.suggest_float("x2", 0, 10) + return (x1 - 2) ** 2 + (x2 - 5) ** 2 + + study.optimize(objective, n_trials=100) + + with tempfile.TemporaryDirectory() as dir: + with tempfile.NamedTemporaryFile() as fp: + filename = fp.name + path = os.path.join(dir, filename) + create_storage_file(filename) + page.goto(url) + with page.expect_file_chooser() as fc_info: + page.get_by_role("button").nth(2).click() + file_chooser = fc_info.value + file_chooser.set_files(path) + + page.get_by_role("link", name=study_name).click() + + def count_components(page: Page, component_name: str): + component_count = page.evaluate( + f"""() => {{ + const components = document.querySelectorAll('.{component_name}'); + return components.length; + }}""" + ) + return component_count + + count = count_components(page, "MuiCard-root") + assert count == 4 From f0751b8d4808917fe4993e88c2139e6e46213461 Mon Sep 17 00:00:00 2001 From: keisuke-umezawa Date: Mon, 5 Feb 2024 23:03:30 +0900 Subject: [PATCH 05/98] Follow review comments --- e2e_tests/test_standalone/test_study_list.py | 108 +++++++------------ e2e_tests/utils.py | 11 ++ 2 files changed, 47 insertions(+), 72 deletions(-) diff --git a/e2e_tests/test_standalone/test_study_list.py b/e2e_tests/test_standalone/test_study_list.py index 3c588aed..18c57e08 100644 --- a/e2e_tests/test_standalone/test_study_list.py +++ b/e2e_tests/test_standalone/test_study_list.py @@ -1,10 +1,13 @@ import os import tempfile +from typing import Callable +import optuna from playwright.sync_api import Page import pytest from ..test_server import make_standalone_server +from ..utils import count_components @pytest.fixture @@ -25,31 +28,49 @@ def test_home( assert title == "Optuna Dashboard (Wasm ver.)" -def test_load_rdb_storage( +def create_rdb_storage_sqlite_file(filename: str, study_name: str): + storage = optuna.storages.RDBStorage(f"sqlite:///{filename}") + study = optuna.create_study(study_name=study_name, storage=storage) + + def objective(trial: optuna.Trial) -> float: + x1 = trial.suggest_float("x1", 0, 10) + x2 = trial.suggest_float("x2", 0, 10) + return (x1 - 2) ** 2 + (x2 - 5) ** 2 + + study.optimize(objective, n_trials=100) + + +def create_journal_storage_local_file(filename: str, study_name: str): + storage = optuna.storages.JournalStorage( + optuna.storages.JournalFileStorage(f"{filename}"), + ) + study = optuna.create_study(study_name=study_name, storage=storage) + + def objective(trial: optuna.Trial) -> float: + x1 = trial.suggest_float("x1", 0, 10) + x2 = trial.suggest_float("x2", 0, 10) + return (x1 - 2) ** 2 + (x2 - 5) ** 2 + + study.optimize(objective, n_trials=100) + + +@pytest.mark.parametrize( + "create_storage_file", + [create_rdb_storage_sqlite_file, create_journal_storage_local_file], +) +def test_load_storage( page: Page, server_url: str, + create_storage_file: Callable[[str, str], optuna.storages.BaseStorage], ) -> None: study_name = "single-objective" url = f"{server_url}" - def create_storage_file(filename: str): - import optuna - - storage = optuna.storages.RDBStorage(f"sqlite:///{filename}") - study = optuna.create_study(study_name=study_name, storage=storage) - - def objective(trial: optuna.Trial) -> float: - x1 = trial.suggest_float("x1", 0, 10) - x2 = trial.suggest_float("x2", 0, 10) - return (x1 - 2) ** 2 + (x2 - 5) ** 2 - - study.optimize(objective, n_trials=100) - with tempfile.TemporaryDirectory() as dir: with tempfile.NamedTemporaryFile() as fp: filename = fp.name path = os.path.join(dir, filename) - create_storage_file(filename) + create_storage_file(filename, study_name) page.goto(url) with page.expect_file_chooser() as fc_info: page.get_by_role("button").nth(2).click() @@ -58,62 +79,5 @@ def test_load_rdb_storage( page.get_by_role("link", name=study_name).click() - def count_components(page: Page, component_name: str): - component_count = page.evaluate( - f"""() => {{ - const components = document.querySelectorAll('.{component_name}'); - return components.length; - }}""" - ) - return component_count - - count = count_components(page, "MuiCard-root") - assert count == 4 - - -def test_load_journal_storage( - page: Page, - server_url: str, -) -> None: - study_name = "single-objective" - url = f"{server_url}" - - def create_storage_file(filename: str): - import optuna - - storage = optuna.storages.JournalStorage( - optuna.storages.JournalFileStorage(f"{filename}"), - ) - study = optuna.create_study(study_name=study_name, storage=storage) - - def objective(trial: optuna.Trial) -> float: - x1 = trial.suggest_float("x1", 0, 10) - x2 = trial.suggest_float("x2", 0, 10) - return (x1 - 2) ** 2 + (x2 - 5) ** 2 - - study.optimize(objective, n_trials=100) - - with tempfile.TemporaryDirectory() as dir: - with tempfile.NamedTemporaryFile() as fp: - filename = fp.name - path = os.path.join(dir, filename) - create_storage_file(filename) - page.goto(url) - with page.expect_file_chooser() as fc_info: - page.get_by_role("button").nth(2).click() - file_chooser = fc_info.value - file_chooser.set_files(path) - - page.get_by_role("link", name=study_name).click() - - def count_components(page: Page, component_name: str): - component_count = page.evaluate( - f"""() => {{ - const components = document.querySelectorAll('.{component_name}'); - return components.length; - }}""" - ) - return component_count - count = count_components(page, "MuiCard-root") assert count == 4 diff --git a/e2e_tests/utils.py b/e2e_tests/utils.py index 68952ae9..2520fc65 100644 --- a/e2e_tests/utils.py +++ b/e2e_tests/utils.py @@ -1,9 +1,20 @@ from optuna_dashboard._storage import trials_cache from optuna_dashboard._storage import trials_cache_lock from optuna_dashboard._storage import trials_last_fetched_at +from playwright.sync_api import Page def clear_inmemory_cache() -> None: with trials_cache_lock: trials_cache.clear() trials_last_fetched_at.clear() + + +def count_components(page: Page, component_name: str): + component_count = page.evaluate( + f"""() => {{ + const components = document.querySelectorAll('.{component_name}'); + return components.length; + }}""" + ) + return component_count From f2ede0044bbb0b6f3a3dfbd588fb0cb8646c0b80 Mon Sep 17 00:00:00 2001 From: ET <57718207+turbotimon@users.noreply.github.com> Date: Thu, 8 Feb 2024 08:35:45 +0000 Subject: [PATCH 06/98] improve ux when trying to open sqlite without protocol --- optuna_dashboard/_storage_url.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/optuna_dashboard/_storage_url.py b/optuna_dashboard/_storage_url.py index 351f9f54..a9b49d87 100644 --- a/optuna_dashboard/_storage_url.py +++ b/optuna_dashboard/_storage_url.py @@ -1,6 +1,7 @@ from __future__ import annotations import os.path +from pathlib import Path import re from typing import TYPE_CHECKING @@ -58,11 +59,22 @@ def get_storage( return guess_storage_from_url(storage) +def _has_sqlite_suffix(storage_url: str) -> bool: + storage_path = Path(storage_url) + SQLITE_EXTENSIONS = (".db", ".sqlite3") + return storage_path.suffix in SQLITE_EXTENSIONS + + def guess_storage_from_url(storage_url: str) -> BaseStorage: if storage_url.startswith("redis"): return get_journal_redis_storage(storage_url) if os.path.isfile(storage_url): + if _has_sqlite_suffix(storage_url): + raise ValueError( + "It looks like you are trying to open a sqlite db. " + + "Please make sure you specify the driver, e.g.: sqlite:///example.db" + ) return get_journal_file_storage(storage_url) if rfc1738_pattern.match(storage_url) is not None: From 506a775cdf781a91fb35596fe43c570ca4753628 Mon Sep 17 00:00:00 2001 From: porink0424 Date: Fri, 9 Feb 2024 10:08:18 +0900 Subject: [PATCH 07/98] Add @tanstack/react-query package --- package-lock.json | 38 ++++++++++++++++++++++++++++++++++++++ package.json | 1 + 2 files changed, 39 insertions(+) diff --git a/package-lock.json b/package-lock.json index f6a8bdc3..ea4f2825 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,6 +16,7 @@ "@mui/material": "^5.15.6", "@react-three/drei": "^9.96.4", "@react-three/fiber": "^8.15.15", + "@tanstack/react-query": "^5.18.1", "@types/three": "^0.160.0", "axios": "^1.6.7", "elkjs": "^0.9.1", @@ -4247,6 +4248,30 @@ "@sinonjs/commons": "^3.0.0" } }, + "node_modules/@tanstack/query-core": { + "version": "5.18.1", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.18.1.tgz", + "integrity": "sha512-fYhrG7bHgSNbnkIJF2R4VUXb4lF7EBiQjKkDc5wOlB7usdQOIN4LxxHpDxyE3qjqIst1WBGvDtL48T0sHJGKCw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/react-query": { + "version": "5.18.1", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.18.1.tgz", + "integrity": "sha512-PdI07BbsahZ+04PxSuDQsQvBWe008eWFk/YYWzt8fvzt2sALUM0TpAJa/DFpqa7+SSo7j1EQR6Jx6znXNHyaXw==", + "dependencies": { + "@tanstack/query-core": "5.18.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^18.0.0" + } + }, "node_modules/@testing-library/dom": { "version": "9.3.4", "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-9.3.4.tgz", @@ -18499,6 +18524,19 @@ "@sinonjs/commons": "^3.0.0" } }, + "@tanstack/query-core": { + "version": "5.18.1", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.18.1.tgz", + "integrity": "sha512-fYhrG7bHgSNbnkIJF2R4VUXb4lF7EBiQjKkDc5wOlB7usdQOIN4LxxHpDxyE3qjqIst1WBGvDtL48T0sHJGKCw==" + }, + "@tanstack/react-query": { + "version": "5.18.1", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.18.1.tgz", + "integrity": "sha512-PdI07BbsahZ+04PxSuDQsQvBWe008eWFk/YYWzt8fvzt2sALUM0TpAJa/DFpqa7+SSo7j1EQR6Jx6znXNHyaXw==", + "requires": { + "@tanstack/query-core": "5.18.1" + } + }, "@testing-library/dom": { "version": "9.3.4", "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-9.3.4.tgz", diff --git a/package.json b/package.json index 08bd980d..bfefbb00 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "@mui/material": "^5.15.6", "@react-three/drei": "^9.96.4", "@react-three/fiber": "^8.15.15", + "@tanstack/react-query": "^5.18.1", "@types/three": "^0.160.0", "axios": "^1.6.7", "elkjs": "^0.9.1", From 87b50f5acd84de3290efa72733408a9479ad2539 Mon Sep 17 00:00:00 2001 From: porink0424 Date: Fri, 9 Feb 2024 11:27:45 +0900 Subject: [PATCH 08/98] Replaced recoil with react-query for Hyperparameter Importance --- optuna_dashboard/ts/action.ts | 30 --- optuna_dashboard/ts/components/App.tsx | 196 ++++++++++-------- .../GraphHyperparameterImportances.tsx | 16 +- .../ts/hooks/useParamImportance.ts | 37 ++++ optuna_dashboard/ts/state.ts | 13 -- optuna_dashboard/ts/types/index.d.ts | 3 - 6 files changed, 150 insertions(+), 145 deletions(-) create mode 100644 optuna_dashboard/ts/hooks/useParamImportance.ts diff --git a/optuna_dashboard/ts/action.ts b/optuna_dashboard/ts/action.ts index 0c448c2e..a0037f46 100644 --- a/optuna_dashboard/ts/action.ts +++ b/optuna_dashboard/ts/action.ts @@ -3,7 +3,6 @@ import { useSnackbar } from "notistack" import { getStudyDetailAPI, getStudySummariesAPI, - getParamImportances, createNewStudyAPI, deleteStudyAPI, saveStudyNoteAPI, @@ -25,7 +24,6 @@ import { import { studyDetailsState, studySummariesState, - paramImportanceState, isFileUploading, artifactIsAvailable, plotlypyIsAvailableState, @@ -43,8 +41,6 @@ export const actionCreator = () => { const [studyDetails, setStudyDetails] = useRecoilState(studyDetailsState) const setReloadInterval = useSetRecoilState(reloadIntervalState) - const [paramImportance, setParamImportance] = - useRecoilState(paramImportanceState) const setUploading = useSetRecoilState(isFileUploading) const setTrialsUpdating = useSetRecoilState(trialsUpdatingState) const setArtifactIsAvailable = useSetRecoilState(artifactIsAvailable) @@ -207,15 +203,6 @@ export const actionCreator = () => { setStudyDetailState(studyId, newStudy) } - const setStudyParamImportanceState = ( - studyId: number, - importance: ParamImportance[][] - ) => { - const newVal = Object.assign({}, paramImportance) - newVal[studyId] = importance - setParamImportance(newVal) - } - const updateAPIMeta = () => { getMetaInfoAPI().then((r) => { setArtifactIsAvailable(r.artifact_is_available) @@ -273,22 +260,6 @@ export const actionCreator = () => { }) } - const updateParamImportance = (studyId: number) => { - getParamImportances(studyId) - .then((importance) => { - setStudyParamImportanceState(studyId, importance) - }) - .catch((err) => { - const reason = err.response?.data.reason - enqueueSnackbar( - `Failed to load hyperparameter importance (reason=${reason})`, - { - variant: "error", - } - ) - }) - } - const createNewStudy = (studyName: string, directions: StudyDirection[]) => { createNewStudyAPI(studyName, directions) .then((study_summary) => { @@ -714,7 +685,6 @@ export const actionCreator = () => { updateAPIMeta, updateStudyDetail, updateStudySummaries, - updateParamImportance, createNewStudy, deleteStudy, renameStudy, diff --git a/optuna_dashboard/ts/components/App.tsx b/optuna_dashboard/ts/components/App.tsx index 4772687d..7c0cbff6 100644 --- a/optuna_dashboard/ts/components/App.tsx +++ b/optuna_dashboard/ts/components/App.tsx @@ -15,6 +15,18 @@ import { import { CompareStudies } from "./CompareStudies" import { StudyDetail } from "./StudyDetail" import { StudyList } from "./StudyList" +import { QueryClient, QueryClientProvider } from "@tanstack/react-query" + +const queryClient = new QueryClient({ + defaultOptions: { + queries: { + retry: false, + refetchOnMount: false, + refetchOnReconnect: false, + refetchOnWindowFocus: false, + }, + }, +}) export const App: FC = () => { const prefersDarkMode = useMediaQuery("(prefers-color-scheme: dark)") @@ -38,95 +50,99 @@ export const App: FC = () => { } return ( - - - - - - - - - } - /> - - } - /> - - } - /> - - } - /> - - } - /> - - } - /> - - } - /> - } - /> - } - /> - - - - - - + + + + + + + + + + } + /> + + } + /> + + } + /> + + } + /> + + } + /> + + } + /> + + } + /> + + } + /> + } + /> + + + + + + + ) } diff --git a/optuna_dashboard/ts/components/GraphHyperparameterImportances.tsx b/optuna_dashboard/ts/components/GraphHyperparameterImportances.tsx index 0621670b..5cb15ee0 100644 --- a/optuna_dashboard/ts/components/GraphHyperparameterImportances.tsx +++ b/optuna_dashboard/ts/components/GraphHyperparameterImportances.tsx @@ -3,8 +3,8 @@ import React, { FC, useEffect } from "react" import { Typography, useTheme, Box, Card, CardContent } from "@mui/material" import { plotlyDarkTemplate } from "./PlotlyDarkMode" -import { actionCreator } from "../action" -import { useParamImportanceValue, useStudyDirections } from "../state" +import { useStudyDirections } from "../state" +import { useParamImportance } from "../hooks/useParamImportance" const plotDomId = "graph-hyperparameter-importances" export const GraphHyperparameterImportance: FC<{ @@ -13,10 +13,12 @@ export const GraphHyperparameterImportance: FC<{ graphHeight: string }> = ({ studyId, study = null, graphHeight }) => { const theme = useTheme() - const action = actionCreator() - const importances = useParamImportanceValue(studyId) const numCompletedTrials = study?.trials.filter((t) => t.state === "Complete").length || 0 + const { importances } = useParamImportance({ + numCompletedTrials, + studyId, + }) const nObjectives = useStudyDirections(studyId)?.length const objectiveNames: string[] = study?.objective_names || @@ -24,11 +26,7 @@ export const GraphHyperparameterImportance: FC<{ [] useEffect(() => { - action.updateParamImportance(studyId) - }, [numCompletedTrials]) - - useEffect(() => { - if (importances !== null && nObjectives === importances.length) { + if (importances !== undefined && nObjectives === importances.length) { plotParamImportance(importances, objectiveNames, theme.palette.mode) } }, [nObjectives, importances, theme.palette.mode]) diff --git a/optuna_dashboard/ts/hooks/useParamImportance.ts b/optuna_dashboard/ts/hooks/useParamImportance.ts new file mode 100644 index 00000000..8b145b2b --- /dev/null +++ b/optuna_dashboard/ts/hooks/useParamImportance.ts @@ -0,0 +1,37 @@ +import { useEffect } from "react" +import { useSnackbar } from "notistack" +import { getParamImportances } from "../../ts/apiClient" +import { useQuery } from "@tanstack/react-query" +import { AxiosError } from "axios" + +export const useParamImportance = ({ + numCompletedTrials, + studyId, +}: { numCompletedTrials: number; studyId: number }) => { + const { enqueueSnackbar } = useSnackbar() + + const { data, isLoading, error } = useQuery>({ + queryKey: ["paramImportance", studyId, numCompletedTrials], + queryFn: () => getParamImportances(studyId), + staleTime: Infinity, + gcTime: Infinity, + }) + + useEffect(() => { + if (error) { + const reason = error.response?.data.reason + enqueueSnackbar( + `Failed to load hyperparameter importance (reason=${reason})`, + { + variant: "error", + } + ) + } + }, [error]) + + return { + importances: data, + isLoading, + error, + } +} diff --git a/optuna_dashboard/ts/state.ts b/optuna_dashboard/ts/state.ts index 20f75c2d..0493d44f 100644 --- a/optuna_dashboard/ts/state.ts +++ b/optuna_dashboard/ts/state.ts @@ -18,11 +18,6 @@ export const trialsUpdatingState = atom<{ default: {}, }) -export const paramImportanceState = atom({ - key: "paramImportance", - default: {}, -}) - // TODO(c-bata): Consider representing the state as boolean. export const reloadIntervalState = atom({ key: "reloadInterval", @@ -69,14 +64,6 @@ export const useTrialUpdatingValue = (trialId: number): boolean => { return updating[trialId] || false } -export const useParamImportanceValue = ( - studyId: number -): ParamImportance[][] | null => { - const studyParamImportance = - useRecoilValue(paramImportanceState) - return studyParamImportance[studyId] || null -} - export const useStudyDirections = ( studyId: number ): StudyDirection[] | null => { diff --git a/optuna_dashboard/ts/types/index.d.ts b/optuna_dashboard/ts/types/index.d.ts index 67182ff8..9ea5444b 100644 --- a/optuna_dashboard/ts/types/index.d.ts +++ b/optuna_dashboard/ts/types/index.d.ts @@ -226,9 +226,6 @@ type StudyDetails = { [study_id: string]: StudyDetail } -type StudyParamImportance = { - [study_id: string]: ParamImportance[][] -} type PreferenceHistory = { id: string candidates: number[] From 99177b98c65b7d749bf88003f3129f268c7bf1f5 Mon Sep 17 00:00:00 2001 From: porink0424 Date: Fri, 9 Feb 2024 15:21:51 +0900 Subject: [PATCH 09/98] Replaced recoil with react-query for GraphRank --- optuna_dashboard/ts/components/GraphRank.tsx | 28 ++++++++------ .../ts/hooks/useParamImportance.ts | 5 ++- optuna_dashboard/ts/hooks/usePlot.ts | 37 +++++++++++++++++++ 3 files changed, 58 insertions(+), 12 deletions(-) create mode 100644 optuna_dashboard/ts/hooks/usePlot.ts diff --git a/optuna_dashboard/ts/components/GraphRank.tsx b/optuna_dashboard/ts/components/GraphRank.tsx index d1ce9d19..b288874c 100644 --- a/optuna_dashboard/ts/components/GraphRank.tsx +++ b/optuna_dashboard/ts/components/GraphRank.tsx @@ -14,8 +14,9 @@ import { import { plotlyDarkTemplate } from "./PlotlyDarkMode" import { getAxisInfo, makeHovertext } from "../graphUtil" import { useMergedUnionSearchSpace } from "../searchSpace" -import { getPlotAPI, PlotType } from "../apiClient" +import { PlotType } from "../apiClient" import { useBackendRender } from "../state" +import { usePlot } from "../hooks/usePlot" const plotDomId = "graph-rank" @@ -47,18 +48,23 @@ const GraphRankBackend: FC<{ const studyId = study?.id const numCompletedTrials = study?.trials.filter((t) => t.state === "Complete").length || 0 + const { data, layout, error } = usePlot({ + numCompletedTrials, + studyId, + plotType: PlotType.Rank, + }) + useEffect(() => { - if (studyId === undefined) { - return + if (data && layout) { + plotly.react(plotDomId, data, layout) } - getPlotAPI(studyId, PlotType.Rank) - .then(({ data, layout }) => { - plotly.react(plotDomId, data, layout) - }) - .catch((err) => { - console.error(err) - }) - }, [studyId, numCompletedTrials]) + }, [data, layout]) + useEffect(() => { + if (error) { + console.error(error) + } + }, [error]) + return } diff --git a/optuna_dashboard/ts/hooks/useParamImportance.ts b/optuna_dashboard/ts/hooks/useParamImportance.ts index 8b145b2b..3728320f 100644 --- a/optuna_dashboard/ts/hooks/useParamImportance.ts +++ b/optuna_dashboard/ts/hooks/useParamImportance.ts @@ -10,7 +10,10 @@ export const useParamImportance = ({ }: { numCompletedTrials: number; studyId: number }) => { const { enqueueSnackbar } = useSnackbar() - const { data, isLoading, error } = useQuery>({ + const { data, isLoading, error } = useQuery< + ParamImportance[][], + AxiosError<{ reason: string }> + >({ queryKey: ["paramImportance", studyId, numCompletedTrials], queryFn: () => getParamImportances(studyId), staleTime: Infinity, diff --git a/optuna_dashboard/ts/hooks/usePlot.ts b/optuna_dashboard/ts/hooks/usePlot.ts new file mode 100644 index 00000000..3c3036ad --- /dev/null +++ b/optuna_dashboard/ts/hooks/usePlot.ts @@ -0,0 +1,37 @@ +import * as plotly from "plotly.js-dist-min" +import { useQuery } from "@tanstack/react-query" +import { AxiosError } from "axios" +import { PlotType, getPlotAPI } from "../apiClient" + +export const usePlot = ({ + numCompletedTrials, + studyId, + plotType, +}: { + numCompletedTrials: number + studyId: number | undefined + plotType: PlotType +}) => { + const { data, isLoading, error } = useQuery< + { data: plotly.Data[]; layout: plotly.Layout }, + AxiosError + >({ + enabled: studyId !== undefined, + queryKey: ["plot", studyId, numCompletedTrials], + queryFn: () => { + if (studyId === undefined) { + return Promise.reject(new Error("Invalid studyId")) + } + return getPlotAPI(studyId, plotType) + }, + staleTime: Infinity, + gcTime: Infinity, + }) + + return { + data: data?.data, + layout: data?.layout, + isLoading, + error, + } +} From a40fc7f76db04f58233d3a77e4ee5e426f923476 Mon Sep 17 00:00:00 2001 From: porink0424 Date: Fri, 9 Feb 2024 15:28:51 +0900 Subject: [PATCH 10/98] Replaced recoil with react-query for GraphContour, GraphParallelCoordinate, GraphSlice --- .../ts/components/GraphContour.tsx | 28 +++++++++++------- .../ts/components/GraphParallelCoordinate.tsx | 29 ++++++++++++------- optuna_dashboard/ts/components/GraphSlice.tsx | 29 ++++++++++++------- optuna_dashboard/ts/hooks/usePlot.ts | 2 +- 4 files changed, 54 insertions(+), 34 deletions(-) diff --git a/optuna_dashboard/ts/components/GraphContour.tsx b/optuna_dashboard/ts/components/GraphContour.tsx index c0c296de..f2e64a91 100644 --- a/optuna_dashboard/ts/components/GraphContour.tsx +++ b/optuna_dashboard/ts/components/GraphContour.tsx @@ -15,8 +15,9 @@ import blue from "@mui/material/colors/blue" import { plotlyDarkTemplate } from "./PlotlyDarkMode" import { useMergedUnionSearchSpace } from "../searchSpace" import { getAxisInfo } from "../graphUtil" -import { getPlotAPI, PlotType } from "../apiClient" +import { PlotType } from "../apiClient" import { useBackendRender } from "../state" +import { usePlot } from "../hooks/usePlot" const plotDomId = "graph-contour" @@ -36,18 +37,23 @@ const ContourBackend: FC<{ const studyId = study?.id const numCompletedTrials = study?.trials.filter((t) => t.state === "Complete").length || 0 + const { data, layout, error } = usePlot({ + numCompletedTrials, + studyId, + plotType: PlotType.Contour, + }) + useEffect(() => { - if (studyId === undefined) { - return + if (data && layout) { + plotly.react(plotDomId, data, layout) } - getPlotAPI(studyId, PlotType.Contour) - .then(({ data, layout }) => { - plotly.react(plotDomId, data, layout) - }) - .catch((err) => { - console.error(err) - }) - }, [studyId, numCompletedTrials]) + }, [data, layout]) + useEffect(() => { + if (error) { + console.error(error) + } + }, [error]) + return } diff --git a/optuna_dashboard/ts/components/GraphParallelCoordinate.tsx b/optuna_dashboard/ts/components/GraphParallelCoordinate.tsx index 22d4852a..889a5097 100644 --- a/optuna_dashboard/ts/components/GraphParallelCoordinate.tsx +++ b/optuna_dashboard/ts/components/GraphParallelCoordinate.tsx @@ -17,8 +17,9 @@ import { useParamTargets, } from "../trialFilter" import { useMergedUnionSearchSpace } from "../searchSpace" -import { getPlotAPI, PlotType } from "../apiClient" +import { PlotType } from "../apiClient" import { useBackendRender } from "../state" +import { usePlot } from "../hooks/usePlot" const plotDomId = "graph-parallel-coordinate" @@ -102,18 +103,24 @@ const GraphParallelCoordinateBackend: FC<{ const studyId = study?.id const numCompletedTrials = study?.trials.filter((t) => t.state === "Complete").length || 0 + + const { data, layout, error } = usePlot({ + numCompletedTrials, + studyId, + plotType: PlotType.ParallelCoordinate, + }) + useEffect(() => { - if (studyId === undefined) { - return + if (data && layout) { + plotly.react(plotDomId, data, layout) } - getPlotAPI(studyId, PlotType.ParallelCoordinate) - .then(({ data, layout }) => { - plotly.react(plotDomId, data, layout) - }) - .catch((err) => { - console.error(err) - }) - }, [studyId, numCompletedTrials]) + }, [data, layout]) + useEffect(() => { + if (error) { + console.error(error) + } + }, [error]) + return } diff --git a/optuna_dashboard/ts/components/GraphSlice.tsx b/optuna_dashboard/ts/components/GraphSlice.tsx index 6abaca50..e59a369d 100644 --- a/optuna_dashboard/ts/components/GraphSlice.tsx +++ b/optuna_dashboard/ts/components/GraphSlice.tsx @@ -20,8 +20,9 @@ import { useParamTargets, } from "../trialFilter" import { useMergedUnionSearchSpace } from "../searchSpace" -import { getPlotAPI, PlotType } from "../apiClient" +import { PlotType } from "../apiClient" import { useBackendRender } from "../state" +import { usePlot } from "../hooks/usePlot" const plotDomId = "graph-slice" @@ -48,18 +49,24 @@ const GraphSliceBackend: FC<{ const studyId = study?.id const numCompletedTrials = study?.trials.filter((t) => t.state === "Complete").length || 0 + + const { data, layout, error } = usePlot({ + numCompletedTrials, + studyId, + plotType: PlotType.Slice, + }) + useEffect(() => { - if (studyId === undefined) { - return + if (data && layout) { + plotly.react(plotDomId, data, layout) } - getPlotAPI(studyId, PlotType.Slice) - .then(({ data, layout }) => { - plotly.react(plotDomId, data, layout) - }) - .catch((err) => { - console.error(err) - }) - }, [studyId, numCompletedTrials]) + }, [data, layout]) + useEffect(() => { + if (error) { + console.error(error) + } + }, [error]) + return } diff --git a/optuna_dashboard/ts/hooks/usePlot.ts b/optuna_dashboard/ts/hooks/usePlot.ts index 3c3036ad..594fce3f 100644 --- a/optuna_dashboard/ts/hooks/usePlot.ts +++ b/optuna_dashboard/ts/hooks/usePlot.ts @@ -17,7 +17,7 @@ export const usePlot = ({ AxiosError >({ enabled: studyId !== undefined, - queryKey: ["plot", studyId, numCompletedTrials], + queryKey: ["plot", studyId, numCompletedTrials, plotType], queryFn: () => { if (studyId === undefined) { return Promise.reject(new Error("Invalid studyId")) From 7ac744af195ffb3efe071cbe9eff1f5553cf4653 Mon Sep 17 00:00:00 2001 From: porink0424 Date: Fri, 9 Feb 2024 15:32:21 +0900 Subject: [PATCH 11/98] fix format --- optuna_dashboard/ts/components/GraphRank.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/optuna_dashboard/ts/components/GraphRank.tsx b/optuna_dashboard/ts/components/GraphRank.tsx index b288874c..63746c43 100644 --- a/optuna_dashboard/ts/components/GraphRank.tsx +++ b/optuna_dashboard/ts/components/GraphRank.tsx @@ -48,6 +48,7 @@ const GraphRankBackend: FC<{ const studyId = study?.id const numCompletedTrials = study?.trials.filter((t) => t.state === "Complete").length || 0 + const { data, layout, error } = usePlot({ numCompletedTrials, studyId, From 99168e9b128538aff4c07c15a18b8cd40b884eed Mon Sep 17 00:00:00 2001 From: porink0424 Date: Fri, 9 Feb 2024 15:58:06 +0900 Subject: [PATCH 12/98] lint --- .../ts/components/GraphHyperparameterImportances.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/optuna_dashboard/ts/components/GraphHyperparameterImportances.tsx b/optuna_dashboard/ts/components/GraphHyperparameterImportances.tsx index f5274d8e..88cce45f 100644 --- a/optuna_dashboard/ts/components/GraphHyperparameterImportances.tsx +++ b/optuna_dashboard/ts/components/GraphHyperparameterImportances.tsx @@ -3,7 +3,6 @@ import React, { FC, useEffect } from "react" import { Typography, useTheme, Box, Card, CardContent } from "@mui/material" import { useParamImportance } from "../hooks/useParamImportance" -import { actionCreator } from "../action" import { useStudyDirections, usePlotlyColorTheme } from "../state" const plotDomId = "graph-hyperparameter-importances" From 3880129988922eb57f9755b765a29c6a5cee4792 Mon Sep 17 00:00:00 2001 From: porink0424 Date: Fri, 9 Feb 2024 17:29:39 +0900 Subject: [PATCH 13/98] Change gcTime: infinity -> 30min --- optuna_dashboard/ts/hooks/useParamImportance.ts | 2 +- optuna_dashboard/ts/hooks/usePlot.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/optuna_dashboard/ts/hooks/useParamImportance.ts b/optuna_dashboard/ts/hooks/useParamImportance.ts index 3728320f..173f1d32 100644 --- a/optuna_dashboard/ts/hooks/useParamImportance.ts +++ b/optuna_dashboard/ts/hooks/useParamImportance.ts @@ -17,7 +17,7 @@ export const useParamImportance = ({ queryKey: ["paramImportance", studyId, numCompletedTrials], queryFn: () => getParamImportances(studyId), staleTime: Infinity, - gcTime: Infinity, + gcTime: 30 * 60 * 1000, // 30 minutes }) useEffect(() => { diff --git a/optuna_dashboard/ts/hooks/usePlot.ts b/optuna_dashboard/ts/hooks/usePlot.ts index 594fce3f..9ce6edd9 100644 --- a/optuna_dashboard/ts/hooks/usePlot.ts +++ b/optuna_dashboard/ts/hooks/usePlot.ts @@ -25,7 +25,7 @@ export const usePlot = ({ return getPlotAPI(studyId, plotType) }, staleTime: Infinity, - gcTime: Infinity, + gcTime: 30 * 60 * 1000, // 30 minutes }) return { From 18e01d4d37801d14ef14c091f817597200f9f22f Mon Sep 17 00:00:00 2001 From: Kenshin Abe Date: Fri, 9 Feb 2024 18:32:55 +0900 Subject: [PATCH 14/98] Implement backend rendering of timeline plot --- optuna_dashboard/_app.py | 2 ++ optuna_dashboard/ts/apiClient.ts | 1 + .../ts/components/GraphTimeline.tsx | 33 +++++++++++++++++++ 3 files changed, 36 insertions(+) diff --git a/optuna_dashboard/_app.py b/optuna_dashboard/_app.py index ac0e1cf0..997c89b6 100644 --- a/optuna_dashboard/_app.py +++ b/optuna_dashboard/_app.py @@ -283,6 +283,8 @@ def create_app( fig = optuna.visualization.plot_rank(study) elif plot_type == "edf": fig = optuna.visualization.plot_edf(study) + elif plot_type == "timeline": + fig = optuna.visualization.plot_timeline(study) else: response.status = 404 # Not found return {"reason": f"plot_type={plot_type} is not supported."} diff --git a/optuna_dashboard/ts/apiClient.ts b/optuna_dashboard/ts/apiClient.ts index 14566a07..b6b25171 100644 --- a/optuna_dashboard/ts/apiClient.ts +++ b/optuna_dashboard/ts/apiClient.ts @@ -452,6 +452,7 @@ export enum PlotType { ParallelCoordinate = "parallel_coordinate", Rank = "rank", EDF = "edf", + Timeline = "timeline", } export const getPlotAPI = ( studyId: number, diff --git a/optuna_dashboard/ts/components/GraphTimeline.tsx b/optuna_dashboard/ts/components/GraphTimeline.tsx index e9de2c71..f048a696 100644 --- a/optuna_dashboard/ts/components/GraphTimeline.tsx +++ b/optuna_dashboard/ts/components/GraphTimeline.tsx @@ -3,12 +3,45 @@ import React, { FC, useEffect } from "react" import { Card, CardContent, Grid, Typography, useTheme } from "@mui/material" import { makeHovertext } from "../graphUtil" import { usePlotlyColorTheme } from "../state" +import { getPlotAPI, PlotType } from "../apiClient" +import { useBackendRender } from "../state" const plotDomId = "graph-timeline" const maxBars = 100 export const GraphTimeline: FC<{ study: StudyDetail | null +}> = ({ study }) => { + if (useBackendRender()) { + return + } else { + return + } +} + +const GraphTimelineBackend: FC<{ + study: StudyDetail | null +}> = ({ study }) => { + const studyId = study?.id + const numCompletedTrials = + study?.trials.filter((t) => t.state === "Complete").length || 0 + useEffect(() => { + if (studyId === undefined) { + return + } + getPlotAPI(studyId, PlotType.Timeline) + .then(({ data, layout }) => { + plotly.react(plotDomId, data, layout) + }) + .catch((err) => { + console.error(err) + }) + }, [studyId, numCompletedTrials]) + return
+} + +const GraphTimelineFrontend: FC<{ + study: StudyDetail | null }> = ({ study }) => { const theme = useTheme() const colorTheme = usePlotlyColorTheme(theme.palette.mode) From f443fa750260bfe5f43f1840b1a20de78e19e9ad Mon Sep 17 00:00:00 2001 From: Kenshin Abe Date: Fri, 9 Feb 2024 18:33:34 +0900 Subject: [PATCH 15/98] Implement backend rendering of importance plot --- optuna_dashboard/_app.py | 2 + optuna_dashboard/ts/apiClient.ts | 1 + .../GraphHyperparameterImportances.tsx | 37 ++++++++++++++++++- 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/optuna_dashboard/_app.py b/optuna_dashboard/_app.py index 997c89b6..2f87c833 100644 --- a/optuna_dashboard/_app.py +++ b/optuna_dashboard/_app.py @@ -285,6 +285,8 @@ def create_app( fig = optuna.visualization.plot_edf(study) elif plot_type == "timeline": fig = optuna.visualization.plot_timeline(study) + elif plot_type == "param_importances": + fig = optuna.visualization.plot_param_importances(study) else: response.status = 404 # Not found return {"reason": f"plot_type={plot_type} is not supported."} diff --git a/optuna_dashboard/ts/apiClient.ts b/optuna_dashboard/ts/apiClient.ts index b6b25171..9bf76f92 100644 --- a/optuna_dashboard/ts/apiClient.ts +++ b/optuna_dashboard/ts/apiClient.ts @@ -453,6 +453,7 @@ export enum PlotType { Rank = "rank", EDF = "edf", Timeline = "timeline", + ParamImportances = "param_importances", } export const getPlotAPI = ( studyId: number, diff --git a/optuna_dashboard/ts/components/GraphHyperparameterImportances.tsx b/optuna_dashboard/ts/components/GraphHyperparameterImportances.tsx index 88cce45f..098b030b 100644 --- a/optuna_dashboard/ts/components/GraphHyperparameterImportances.tsx +++ b/optuna_dashboard/ts/components/GraphHyperparameterImportances.tsx @@ -3,7 +3,8 @@ import React, { FC, useEffect } from "react" import { Typography, useTheme, Box, Card, CardContent } from "@mui/material" import { useParamImportance } from "../hooks/useParamImportance" -import { useStudyDirections, usePlotlyColorTheme } from "../state" +import { useStudyDirections, usePlotlyColorTheme, useBackendRender } from "../state" +import { getPlotAPI, PlotType } from "../apiClient" const plotDomId = "graph-hyperparameter-importances" @@ -11,6 +12,40 @@ export const GraphHyperparameterImportance: FC<{ studyId: number study: StudyDetail | null graphHeight: string +}> = ({ studyId, study = null, graphHeight }) => { + if (useBackendRender()) { + return + } else { + return + } +} + +const GraphHyperparameterImportanceBackend: FC<{ + studyId: number + study: StudyDetail | null + graphHeight: string +}> = ({ studyId, study = null, graphHeight }) => { + const numCompletedTrials = + study?.trials.filter((t) => t.state === "Complete").length || 0 + useEffect(() => { + if (studyId === undefined) { + return + } + getPlotAPI(studyId, PlotType.ParamImportances) + .then(({ data, layout }) => { + plotly.react(plotDomId, data, layout) + }) + .catch((err) => { + console.error(err) + }) + }, [studyId, numCompletedTrials]) + return +} + +const GraphHyperparameterImportanceFrontend: FC<{ + studyId: number + study: StudyDetail | null + graphHeight: string }> = ({ studyId, study = null, graphHeight }) => { const theme = useTheme() const colorTheme = usePlotlyColorTheme(theme.palette.mode) From af6b028eea45849ee2877a72c0fa73e4b3349b5e Mon Sep 17 00:00:00 2001 From: Kenshin Abe Date: Fri, 9 Feb 2024 18:33:59 +0900 Subject: [PATCH 16/98] Implement backend rendering of pareto front plot --- optuna_dashboard/_app.py | 2 ++ optuna_dashboard/ts/apiClient.ts | 1 + .../ts/components/GraphParetoFront.tsx | 33 +++++++++++++++++++ 3 files changed, 36 insertions(+) diff --git a/optuna_dashboard/_app.py b/optuna_dashboard/_app.py index 2f87c833..1d4c9f7c 100644 --- a/optuna_dashboard/_app.py +++ b/optuna_dashboard/_app.py @@ -287,6 +287,8 @@ def create_app( fig = optuna.visualization.plot_timeline(study) elif plot_type == "param_importances": fig = optuna.visualization.plot_param_importances(study) + elif plot_type == "pareto_front": + fig = optuna.visualization.plot_pareto_front(study) else: response.status = 404 # Not found return {"reason": f"plot_type={plot_type} is not supported."} diff --git a/optuna_dashboard/ts/apiClient.ts b/optuna_dashboard/ts/apiClient.ts index 9bf76f92..cf775fd6 100644 --- a/optuna_dashboard/ts/apiClient.ts +++ b/optuna_dashboard/ts/apiClient.ts @@ -454,6 +454,7 @@ export enum PlotType { EDF = "edf", Timeline = "timeline", ParamImportances = "param_importances", + ParetoFront = "pareto_front", } export const getPlotAPI = ( studyId: number, diff --git a/optuna_dashboard/ts/components/GraphParetoFront.tsx b/optuna_dashboard/ts/components/GraphParetoFront.tsx index 61ad7b9e..de5bb5dc 100644 --- a/optuna_dashboard/ts/components/GraphParetoFront.tsx +++ b/optuna_dashboard/ts/components/GraphParetoFront.tsx @@ -14,11 +14,44 @@ import { import { makeHovertext } from "../graphUtil" import { usePlotlyColorTheme } from "../state" import { useNavigate } from "react-router-dom" +import { getPlotAPI, PlotType } from "../apiClient" +import { useBackendRender } from "../state" const plotDomId = "graph-pareto-front" export const GraphParetoFront: FC<{ study: StudyDetail | null +}> = ({ study = null }) => { + if (useBackendRender()) { + return + } else { + return + } +} + +const GraphParetoFrontBackend: FC<{ + study: StudyDetail | null +}> = ({ study = null }) => { + const studyId = study?.id + const numCompletedTrials = + study?.trials.filter((t) => t.state === "Complete").length || 0 + useEffect(() => { + if (studyId === undefined) { + return + } + getPlotAPI(studyId, PlotType.ParetoFront) + .then(({ data, layout }) => { + plotly.react(plotDomId, data, layout) + }) + .catch((err) => { + console.error(err) + }) + }, [studyId, numCompletedTrials]) + return +} + +const GraphParetoFrontFrontend: FC<{ + study: StudyDetail | null }> = ({ study = null }) => { const theme = useTheme() const colorTheme = usePlotlyColorTheme(theme.palette.mode) From 16ee07d4d8ff7f085fc025de98ac1c2b0de9d55e Mon Sep 17 00:00:00 2001 From: Kenshin Abe Date: Fri, 9 Feb 2024 19:04:12 +0900 Subject: [PATCH 17/98] Add "use plotlypy" button --- optuna_dashboard/ts/components/Settings.tsx | 23 +++++++++++++++++++-- optuna_dashboard/ts/state.ts | 9 ++++++-- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/optuna_dashboard/ts/components/Settings.tsx b/optuna_dashboard/ts/components/Settings.tsx index 328521c0..5598b9ca 100644 --- a/optuna_dashboard/ts/components/Settings.tsx +++ b/optuna_dashboard/ts/components/Settings.tsx @@ -3,13 +3,14 @@ import React, { FC, useState } from "react" import { Typography, Select, + Switch, MenuItem, Grid, SelectChangeEvent, } from "@mui/material" -import { useRecoilValue, useSetRecoilState } from "recoil" -import { plotlyColorTheme } from "../state" +import { useRecoilValue, useSetRecoilState, useRecoilState } from "recoil" +import { plotlyColorTheme, plotBackendRenderingState } from "../state" export const Settings: FC = () => { const colorTheme = useRecoilValue(plotlyColorTheme) @@ -28,6 +29,11 @@ export const Settings: FC = () => { setPlotlyColorTheme({ dark: darkModeColor, light: event.target.value }) } + const [plotBackendRendering, setPlotBackendRendering] = useRecoilState(plotBackendRenderingState) + const handleBackendRenderingChange = () => { + setPlotBackendRendering(!plotBackendRendering) + } + return ( @@ -68,6 +74,19 @@ export const Settings: FC = () => { GGPlot2 + + + + Use Plotlypy + + + + + ) } diff --git a/optuna_dashboard/ts/state.ts b/optuna_dashboard/ts/state.ts index dd07319e..1954c98e 100644 --- a/optuna_dashboard/ts/state.ts +++ b/optuna_dashboard/ts/state.ts @@ -51,6 +51,11 @@ export const plotlyColorTheme = atom({ }, }) +export const plotBackendRenderingState = atom({ + key: "plotBackendRendering", + default: false, +}) + export const plotlypyIsAvailableState = atom({ key: "plotlypyIsAvailable", default: true, @@ -115,10 +120,10 @@ export const usePlotlyColorTheme = (mode: string): Partial => { } export const useBackendRender = (): boolean => { - const query = useQuery() + const plotBackendRendering = useRecoilValue(plotBackendRenderingState) const plotlypyIsAvailable = useRecoilValue(plotlypyIsAvailableState) - if (query.get("plotlypy_rendering") === "true") { + if (plotBackendRendering) { if (plotlypyIsAvailable) { return true } From 3fd6fd9ccf93f3503d5701f42d761fe18f12a451 Mon Sep 17 00:00:00 2001 From: Kenshin Abe Date: Fri, 9 Feb 2024 19:07:06 +0900 Subject: [PATCH 18/98] Remove unused import --- optuna_dashboard/ts/state.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/optuna_dashboard/ts/state.ts b/optuna_dashboard/ts/state.ts index 1954c98e..f63fd1e4 100644 --- a/optuna_dashboard/ts/state.ts +++ b/optuna_dashboard/ts/state.ts @@ -3,7 +3,6 @@ import { LightColorTemplates, DarkColorTemplates, } from "./components/PlotlyColorTemplates" -import { useQuery } from "./urlQuery" export const studySummariesState = atom({ key: "studySummaries", From 1f718d9ec9f6a2093b9ffa93c13901a967c90ae4 Mon Sep 17 00:00:00 2001 From: Kenshin Abe Date: Fri, 9 Feb 2024 19:08:23 +0900 Subject: [PATCH 19/98] Apply fmt --- optuna_dashboard/ts/components/Settings.tsx | 3 ++- optuna_dashboard/ts/state.ts | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/optuna_dashboard/ts/components/Settings.tsx b/optuna_dashboard/ts/components/Settings.tsx index 5598b9ca..78ec883f 100644 --- a/optuna_dashboard/ts/components/Settings.tsx +++ b/optuna_dashboard/ts/components/Settings.tsx @@ -29,7 +29,8 @@ export const Settings: FC = () => { setPlotlyColorTheme({ dark: darkModeColor, light: event.target.value }) } - const [plotBackendRendering, setPlotBackendRendering] = useRecoilState(plotBackendRenderingState) + const [plotBackendRendering, setPlotBackendRendering] = + useRecoilState(plotBackendRenderingState) const handleBackendRenderingChange = () => { setPlotBackendRendering(!plotBackendRendering) } diff --git a/optuna_dashboard/ts/state.ts b/optuna_dashboard/ts/state.ts index f63fd1e4..44c9341a 100644 --- a/optuna_dashboard/ts/state.ts +++ b/optuna_dashboard/ts/state.ts @@ -119,7 +119,9 @@ export const usePlotlyColorTheme = (mode: string): Partial => { } export const useBackendRender = (): boolean => { - const plotBackendRendering = useRecoilValue(plotBackendRenderingState) + const plotBackendRendering = useRecoilValue( + plotBackendRenderingState + ) const plotlypyIsAvailable = useRecoilValue(plotlypyIsAvailableState) if (plotBackendRendering) { From 32ea832d5313a5231b1d689ceb14e41469003956 Mon Sep 17 00:00:00 2001 From: Kenshin Abe Date: Fri, 9 Feb 2024 19:09:21 +0900 Subject: [PATCH 20/98] Apply fmt --- .../GraphHyperparameterImportances.tsx | 22 ++++++++++++++++--- .../ts/components/GraphTimeline.tsx | 7 +++++- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/optuna_dashboard/ts/components/GraphHyperparameterImportances.tsx b/optuna_dashboard/ts/components/GraphHyperparameterImportances.tsx index 098b030b..a41f85c0 100644 --- a/optuna_dashboard/ts/components/GraphHyperparameterImportances.tsx +++ b/optuna_dashboard/ts/components/GraphHyperparameterImportances.tsx @@ -3,7 +3,11 @@ import React, { FC, useEffect } from "react" import { Typography, useTheme, Box, Card, CardContent } from "@mui/material" import { useParamImportance } from "../hooks/useParamImportance" -import { useStudyDirections, usePlotlyColorTheme, useBackendRender } from "../state" +import { + useStudyDirections, + usePlotlyColorTheme, + useBackendRender, +} from "../state" import { getPlotAPI, PlotType } from "../apiClient" const plotDomId = "graph-hyperparameter-importances" @@ -14,9 +18,21 @@ export const GraphHyperparameterImportance: FC<{ graphHeight: string }> = ({ studyId, study = null, graphHeight }) => { if (useBackendRender()) { - return + return ( + + ) } else { - return + return ( + + ) } } diff --git a/optuna_dashboard/ts/components/GraphTimeline.tsx b/optuna_dashboard/ts/components/GraphTimeline.tsx index f048a696..3fba8fe1 100644 --- a/optuna_dashboard/ts/components/GraphTimeline.tsx +++ b/optuna_dashboard/ts/components/GraphTimeline.tsx @@ -37,7 +37,12 @@ const GraphTimelineBackend: FC<{ console.error(err) }) }, [studyId, numCompletedTrials]) - return
+ return ( + + {" "} +
{" "} + + ) } const GraphTimelineFrontend: FC<{ From 9e94da03323d8c510e87981788b78b8d4609fe12 Mon Sep 17 00:00:00 2001 From: ET <57718207+turbotimon@users.noreply.github.com> Date: Mon, 12 Feb 2024 09:57:48 +0000 Subject: [PATCH 21/98] change to check sqlite header --- optuna_dashboard/_storage_url.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/optuna_dashboard/_storage_url.py b/optuna_dashboard/_storage_url.py index a9b49d87..2d660d3d 100644 --- a/optuna_dashboard/_storage_url.py +++ b/optuna_dashboard/_storage_url.py @@ -59,10 +59,12 @@ def get_storage( return guess_storage_from_url(storage) -def _has_sqlite_suffix(storage_url: str) -> bool: +def _has_sqlite_header(storage_url: str) -> bool: storage_path = Path(storage_url) - SQLITE_EXTENSIONS = (".db", ".sqlite3") - return storage_path.suffix in SQLITE_EXTENSIONS + SQLITE_HEADER = b"SQLite format 3\x00" # see https://github.com/optuna/optuna-dashboard/pull/800 + with storage_path.open(mode="rb") as f: + header = f.read(len(SQLITE_HEADER)) + return header == SQLITE_HEADER def guess_storage_from_url(storage_url: str) -> BaseStorage: @@ -70,12 +72,10 @@ def guess_storage_from_url(storage_url: str) -> BaseStorage: return get_journal_redis_storage(storage_url) if os.path.isfile(storage_url): - if _has_sqlite_suffix(storage_url): - raise ValueError( - "It looks like you are trying to open a sqlite db. " - + "Please make sure you specify the driver, e.g.: sqlite:///example.db" - ) - return get_journal_file_storage(storage_url) + if _has_sqlite_header(storage_url): + return get_rdb_storage("sqlite:///" + storage_url) + else: + return get_journal_file_storage(storage_url) if rfc1738_pattern.match(storage_url) is not None: return get_rdb_storage(storage_url) From c13654f19bcb3b248d18bb58b65b0f6cfa5e1ae5 Mon Sep 17 00:00:00 2001 From: nabenabe0928 Date: Tue, 13 Feb 2024 17:17:41 +0100 Subject: [PATCH 22/98] Apply the change suggested by umezawa --- optuna_dashboard/ts/components/TrialTable.tsx | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/optuna_dashboard/ts/components/TrialTable.tsx b/optuna_dashboard/ts/components/TrialTable.tsx index bd26921b..667fc934 100644 --- a/optuna_dashboard/ts/components/TrialTable.tsx +++ b/optuna_dashboard/ts/components/TrialTable.tsx @@ -92,13 +92,16 @@ export const TrialTable: FC<{ studyDetail?.intersection_search_space.length studyDetail?.union_search_space.forEach((s) => { const sortable = s.distribution.type !== "CategoricalDistribution" - const filterChoices = + const filterChoices: (string | null)[] | undefined = s.distribution.type === "CategoricalDistribution" ? s.distribution.choices.map((c) => c.value) : undefined - const filterChoicesWithNull: (string | null)[] | undefined = filterChoices - ? [...filterChoices, null] - : undefined + const hasMissingValue = trials.some( + (t) => !t.params.some((p) => p.name === s.name) + ) + if (filterChoices !== undefined && isDynamicSpace && hasMissingValue) { + filterChoices.push(null) + } columns.push({ field: "params", label: `Param ${s.name}`, @@ -106,7 +109,7 @@ export const TrialTable: FC<{ trials[i].params.find((p) => p.name === s.name)?.param_external_value || null, sortable: sortable, - filterChoices: isDynamicSpace ? filterChoicesWithNull : filterChoices, + filterChoices: filterChoices, // eslint-disable-next-line @typescript-eslint/no-unused-vars less: (firstEl, secondEl, _): number => { const firstVal = firstEl.params.find( From c0a63bbbbc2114239158d93f02773e79d76c9fd8 Mon Sep 17 00:00:00 2001 From: porink0424 Date: Wed, 14 Feb 2024 09:39:42 +0900 Subject: [PATCH 23/98] Improve modal position and size & add close button --- optuna_dashboard/ts/components/AppDrawer.tsx | 13 ++- optuna_dashboard/ts/components/Settings.tsx | 115 ++++++++++++------- optuna_dashboard/ts/types/index.d.ts | 7 +- 3 files changed, 88 insertions(+), 47 deletions(-) diff --git a/optuna_dashboard/ts/components/AppDrawer.tsx b/optuna_dashboard/ts/components/AppDrawer.tsx index 1d4d9c78..068dcff2 100644 --- a/optuna_dashboard/ts/components/AppDrawer.tsx +++ b/optuna_dashboard/ts/components/AppDrawer.tsx @@ -361,15 +361,16 @@ export const AppDrawer: FC<{ - + diff --git a/optuna_dashboard/ts/components/Settings.tsx b/optuna_dashboard/ts/components/Settings.tsx index 328521c0..f3d5b2af 100644 --- a/optuna_dashboard/ts/components/Settings.tsx +++ b/optuna_dashboard/ts/components/Settings.tsx @@ -1,17 +1,25 @@ -import React, { FC, useState } from "react" +import React, { useState } from "react" import { Typography, Select, MenuItem, - Grid, SelectChangeEvent, + Stack, + useTheme, + IconButton, } from "@mui/material" +import ClearIcon from "@mui/icons-material/Clear" import { useRecoilValue, useSetRecoilState } from "recoil" import { plotlyColorTheme } from "../state" -export const Settings: FC = () => { +interface SettingsProps { + handleClose: () => void +} + +export const Settings = ({ handleClose }: SettingsProps) => { + const theme = useTheme() const colorTheme = useRecoilValue(plotlyColorTheme) const setPlotlyColorTheme = useSetRecoilState(plotlyColorTheme) @@ -29,45 +37,74 @@ export const Settings: FC = () => { } return ( - - - - Settings - - - - + + + + + + + Settings + + + + Plotly Color Scales - - - - - Dark Mode + + Dark Mode + + + + Only the "Default" color scale is supported in dark mode - - - - - - - Light Mode - - - - - - + + Light Mode + + + + ) } diff --git a/optuna_dashboard/ts/types/index.d.ts b/optuna_dashboard/ts/types/index.d.ts index 30d6708f..78ca0386 100644 --- a/optuna_dashboard/ts/types/index.d.ts +++ b/optuna_dashboard/ts/types/index.d.ts @@ -240,7 +240,10 @@ type PreferenceHistory = { is_removed: boolean } +type PlotlyColorThemeDark = "default" +type PlotlyColorThemeLight = "default" | "seaborn" | "presentation" | "ggplot2" + type PlotlyColorTheme = { - dark: string - light: string + dark: PlotlyColorThemeDark + light: PlotlyColorThemeLight } From 704a5900242550cc80b316e948eaa8a0840a833a Mon Sep 17 00:00:00 2001 From: porink0424 Date: Wed, 14 Feb 2024 09:53:28 +0900 Subject: [PATCH 24/98] Fix plotlyColorTheme state in Settings component --- optuna_dashboard/ts/components/Settings.tsx | 31 ++++++++++----------- optuna_dashboard/ts/state.ts | 6 ++-- 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/optuna_dashboard/ts/components/Settings.tsx b/optuna_dashboard/ts/components/Settings.tsx index f3d5b2af..e8420094 100644 --- a/optuna_dashboard/ts/components/Settings.tsx +++ b/optuna_dashboard/ts/components/Settings.tsx @@ -1,5 +1,4 @@ -import React, { useState } from "react" - +import React from "react" import { Typography, Select, @@ -10,9 +9,8 @@ import { IconButton, } from "@mui/material" import ClearIcon from "@mui/icons-material/Clear" - -import { useRecoilValue, useSetRecoilState } from "recoil" -import { plotlyColorTheme } from "../state" +import { useRecoilState } from "recoil" +import { plotlyColorThemeState } from "../state" interface SettingsProps { handleClose: () => void @@ -20,20 +18,18 @@ interface SettingsProps { export const Settings = ({ handleClose }: SettingsProps) => { const theme = useTheme() - const colorTheme = useRecoilValue(plotlyColorTheme) - const setPlotlyColorTheme = useSetRecoilState(plotlyColorTheme) - - const [darkModeColor, setDarkModeColor] = useState(colorTheme.dark) - const [lightModeColor, setLightModeColor] = useState(colorTheme.light) + const [plotlyColorTheme, setPlotlyColorTheme] = useRecoilState( + plotlyColorThemeState + ) const handleDarkModeColorChange = (event: SelectChangeEvent) => { - setDarkModeColor(event.target.value) - setPlotlyColorTheme({ dark: event.target.value, light: lightModeColor }) + const dark = event.target.value as PlotlyColorThemeDark + setPlotlyColorTheme((prev) => ({ ...prev, dark })) } const handleLightModeColorChange = (event: SelectChangeEvent) => { - setLightModeColor(event.target.value) - setPlotlyColorTheme({ dark: darkModeColor, light: event.target.value }) + const light = event.target.value as PlotlyColorThemeLight + setPlotlyColorTheme((prev) => ({ ...prev, light })) } return ( @@ -75,7 +71,7 @@ export const Settings = ({ handleClose }: SettingsProps) => { Dark Mode + - - Default - - - - - Only the "Default" color scale is supported in dark mode - - - - Light Mode - - + {theme.palette.mode === "dark" ? ( + <> + + Dark Mode + + + + Only the "Default" color scale is supported in dark mode + + + ) : ( + + Light Mode + + + )} ) From 372f4fc64890984f10e3f4cf3933328bccdf989e Mon Sep 17 00:00:00 2001 From: porink0424 Date: Wed, 14 Feb 2024 10:12:07 +0900 Subject: [PATCH 26/98] Remove redundant repetitions --- optuna_dashboard/ts/components/Settings.tsx | 42 +++++++++++++-------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/optuna_dashboard/ts/components/Settings.tsx b/optuna_dashboard/ts/components/Settings.tsx index 50ad1213..6b58453d 100644 --- a/optuna_dashboard/ts/components/Settings.tsx +++ b/optuna_dashboard/ts/components/Settings.tsx @@ -55,7 +55,7 @@ export const Settings = ({ handleClose }: SettingsProps) => { Settings @@ -76,9 +76,16 @@ export const Settings = ({ handleClose }: SettingsProps) => { value={plotlyColorTheme.dark} onChange={handleDarkModeColorChange} > - - Default - + {( + [{ value: "default", label: "Default" }] as { + value: PlotlyColorThemeDark + label: string + }[] + ).map((v) => ( + + {v.label} + + ))} @@ -92,18 +99,21 @@ export const Settings = ({ handleClose }: SettingsProps) => { value={plotlyColorTheme.light} onChange={handleLightModeColorChange} > - - Default - - - Seaborn - - - Presentation - - - GGPlot2 - + {( + [ + { value: "default", label: "Default" }, + { value: "seaborn", label: "Seaborn" }, + { value: "presentation", label: "Presentation" }, + { value: "ggplot2", label: "GGPlot2" }, + ] as { + value: PlotlyColorThemeLight + label: string + }[] + ).map((v) => ( + + {v.label} + + ))} )} From e60967397938ab1a562b74a1d7f702ea1b65d52f Mon Sep 17 00:00:00 2001 From: porink0424 Date: Wed, 14 Feb 2024 11:45:59 +0900 Subject: [PATCH 27/98] Follow-up of #806 --- optuna_dashboard/ts/components/Settings.tsx | 186 ++++++++++---------- optuna_dashboard/ts/state.ts | 6 +- 2 files changed, 99 insertions(+), 93 deletions(-) diff --git a/optuna_dashboard/ts/components/Settings.tsx b/optuna_dashboard/ts/components/Settings.tsx index 23ac647e..4e7a38dd 100644 --- a/optuna_dashboard/ts/components/Settings.tsx +++ b/optuna_dashboard/ts/components/Settings.tsx @@ -8,6 +8,7 @@ import { Stack, useTheme, IconButton, + Box, } from "@mui/material" import ClearIcon from "@mui/icons-material/Clear" import { useRecoilState } from "recoil" @@ -22,31 +23,113 @@ export const Settings = ({ handleClose }: SettingsProps) => { const [plotlyColorTheme, setPlotlyColorTheme] = useRecoilState( plotlyColorThemeState ) + const [plotBackendRendering, setPlotBackendRendering] = useRecoilState( + plotBackendRenderingState + ) const handleDarkModeColorChange = (event: SelectChangeEvent) => { const dark = event.target.value as PlotlyColorThemeDark - setPlotlyColorTheme((prev) => ({ ...prev, dark })) + setPlotlyColorTheme((cur) => ({ ...cur, dark })) } const handleLightModeColorChange = (event: SelectChangeEvent) => { const light = event.target.value as PlotlyColorThemeLight - setPlotlyColorTheme((prev) => ({ ...prev, light })) + setPlotlyColorTheme((cur) => ({ ...cur, light })) } - const [plotBackendRendering, setPlotBackendRendering] = - useRecoilState(plotBackendRenderingState) - const handleBackendRenderingChange = () => { - setPlotBackendRendering(!plotBackendRendering) + const togglePlotBackendRendering = () => { + setPlotBackendRendering((cur) => !cur) } return ( - + + + + Settings + + + + + Plotly Color Scales + + {theme.palette.mode === "dark" ? ( + <> + + Dark Mode + + + + Only the "Default" color scale is supported in dark mode + + + ) : ( + + Light Mode + + + )} + + + + + Use Plotlypy + + + + + { > - - - Settings - - - - - Plotly Color Scales - - {theme.palette.mode === "dark" ? ( - <> - - Dark Mode - - - - Only the "Default" color scale is supported in dark mode - - - ) : ( - - Light Mode - - - )} - - - Use Plotlypy - - - - + ) } diff --git a/optuna_dashboard/ts/state.ts b/optuna_dashboard/ts/state.ts index f8d51e64..5828985f 100644 --- a/optuna_dashboard/ts/state.ts +++ b/optuna_dashboard/ts/state.ts @@ -119,10 +119,8 @@ export const usePlotlyColorTheme = (mode: string): Partial => { } export const useBackendRender = (): boolean => { - const plotBackendRendering = useRecoilValue( - plotBackendRenderingState - ) - const plotlypyIsAvailable = useRecoilValue(plotlypyIsAvailableState) + const plotBackendRendering = useRecoilValue(plotBackendRenderingState) + const plotlypyIsAvailable = useRecoilValue(plotlypyIsAvailableState) if (plotBackendRendering) { if (plotlypyIsAvailable) { From 4ceeb1bc7a056eebabd458860b914b5b40b31d8a Mon Sep 17 00:00:00 2001 From: Kenshin Abe Date: Wed, 14 Feb 2024 18:15:34 +0900 Subject: [PATCH 28/98] Introduce usePlot --- .../GraphHyperparameterImportances.tsx | 28 +++++++++++-------- .../ts/components/GraphParetoFront.tsx | 28 +++++++++++-------- .../ts/components/GraphTimeline.tsx | 28 +++++++++++-------- 3 files changed, 51 insertions(+), 33 deletions(-) diff --git a/optuna_dashboard/ts/components/GraphHyperparameterImportances.tsx b/optuna_dashboard/ts/components/GraphHyperparameterImportances.tsx index a41f85c0..12ef8d2c 100644 --- a/optuna_dashboard/ts/components/GraphHyperparameterImportances.tsx +++ b/optuna_dashboard/ts/components/GraphHyperparameterImportances.tsx @@ -8,7 +8,8 @@ import { usePlotlyColorTheme, useBackendRender, } from "../state" -import { getPlotAPI, PlotType } from "../apiClient" +import { PlotType } from "../apiClient" +import { usePlot } from "../hooks/usePlot" const plotDomId = "graph-hyperparameter-importances" @@ -43,18 +44,23 @@ const GraphHyperparameterImportanceBackend: FC<{ }> = ({ studyId, study = null, graphHeight }) => { const numCompletedTrials = study?.trials.filter((t) => t.state === "Complete").length || 0 + const { data, layout, error } = usePlot({ + numCompletedTrials, + studyId, + plotType: PlotType.ParamImportances, + }) + useEffect(() => { - if (studyId === undefined) { - return + if (data && layout) { + plotly.react(plotDomId, data, layout) } - getPlotAPI(studyId, PlotType.ParamImportances) - .then(({ data, layout }) => { - plotly.react(plotDomId, data, layout) - }) - .catch((err) => { - console.error(err) - }) - }, [studyId, numCompletedTrials]) + }, [data, layout]) + useEffect(() => { + if (error) { + console.error(error) + } + }, [error]) + return } diff --git a/optuna_dashboard/ts/components/GraphParetoFront.tsx b/optuna_dashboard/ts/components/GraphParetoFront.tsx index de5bb5dc..9ddec25b 100644 --- a/optuna_dashboard/ts/components/GraphParetoFront.tsx +++ b/optuna_dashboard/ts/components/GraphParetoFront.tsx @@ -14,8 +14,9 @@ import { import { makeHovertext } from "../graphUtil" import { usePlotlyColorTheme } from "../state" import { useNavigate } from "react-router-dom" -import { getPlotAPI, PlotType } from "../apiClient" +import { PlotType } from "../apiClient" import { useBackendRender } from "../state" +import { usePlot } from "../hooks/usePlot" const plotDomId = "graph-pareto-front" @@ -35,18 +36,23 @@ const GraphParetoFrontBackend: FC<{ const studyId = study?.id const numCompletedTrials = study?.trials.filter((t) => t.state === "Complete").length || 0 + const { data, layout, error } = usePlot({ + numCompletedTrials, + studyId, + plotType: PlotType.ParetoFront, + }) + useEffect(() => { - if (studyId === undefined) { - return + if (data && layout) { + plotly.react(plotDomId, data, layout) } - getPlotAPI(studyId, PlotType.ParetoFront) - .then(({ data, layout }) => { - plotly.react(plotDomId, data, layout) - }) - .catch((err) => { - console.error(err) - }) - }, [studyId, numCompletedTrials]) + }, [data, layout]) + useEffect(() => { + if (error) { + console.error(error) + } + }, [error]) + return } diff --git a/optuna_dashboard/ts/components/GraphTimeline.tsx b/optuna_dashboard/ts/components/GraphTimeline.tsx index 3fba8fe1..f7e2db65 100644 --- a/optuna_dashboard/ts/components/GraphTimeline.tsx +++ b/optuna_dashboard/ts/components/GraphTimeline.tsx @@ -3,8 +3,9 @@ import React, { FC, useEffect } from "react" import { Card, CardContent, Grid, Typography, useTheme } from "@mui/material" import { makeHovertext } from "../graphUtil" import { usePlotlyColorTheme } from "../state" -import { getPlotAPI, PlotType } from "../apiClient" +import { PlotType } from "../apiClient" import { useBackendRender } from "../state" +import { usePlot } from "../hooks/usePlot" const plotDomId = "graph-timeline" const maxBars = 100 @@ -25,18 +26,23 @@ const GraphTimelineBackend: FC<{ const studyId = study?.id const numCompletedTrials = study?.trials.filter((t) => t.state === "Complete").length || 0 + const { data, layout, error } = usePlot({ + numCompletedTrials, + studyId, + plotType: PlotType.Timeline, + }) + useEffect(() => { - if (studyId === undefined) { - return + if (data && layout) { + plotly.react(plotDomId, data, layout) } - getPlotAPI(studyId, PlotType.Timeline) - .then(({ data, layout }) => { - plotly.react(plotDomId, data, layout) - }) - .catch((err) => { - console.error(err) - }) - }, [studyId, numCompletedTrials]) + }, [data, layout]) + useEffect(() => { + if (error) { + console.error(error) + } + }, [error]) + return ( {" "} From 9256a1baac70de11d086e2b1598dfef5c3913120 Mon Sep 17 00:00:00 2001 From: Kenshin Abe Date: Wed, 14 Feb 2024 18:19:34 +0900 Subject: [PATCH 29/98] Remove unnecessary space --- optuna_dashboard/ts/components/GraphTimeline.tsx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/optuna_dashboard/ts/components/GraphTimeline.tsx b/optuna_dashboard/ts/components/GraphTimeline.tsx index f7e2db65..abe4effd 100644 --- a/optuna_dashboard/ts/components/GraphTimeline.tsx +++ b/optuna_dashboard/ts/components/GraphTimeline.tsx @@ -1,6 +1,6 @@ import * as plotly from "plotly.js-dist-min" import React, { FC, useEffect } from "react" -import { Card, CardContent, Grid, Typography, useTheme } from "@mui/material" +import { Card, CardContent, Grid, Typography, useTheme, Box } from "@mui/material" import { makeHovertext } from "../graphUtil" import { usePlotlyColorTheme } from "../state" import { PlotType } from "../apiClient" @@ -45,8 +45,7 @@ const GraphTimelineBackend: FC<{ return ( - {" "} -
{" "} +
) } From ead77a957811b2a6a62c4e010cdd43dc38343c96 Mon Sep 17 00:00:00 2001 From: Kenshin Abe Date: Wed, 14 Feb 2024 18:33:44 +0900 Subject: [PATCH 30/98] Remove unused import --- optuna_dashboard/ts/components/GraphTimeline.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/optuna_dashboard/ts/components/GraphTimeline.tsx b/optuna_dashboard/ts/components/GraphTimeline.tsx index abe4effd..519399bb 100644 --- a/optuna_dashboard/ts/components/GraphTimeline.tsx +++ b/optuna_dashboard/ts/components/GraphTimeline.tsx @@ -1,6 +1,6 @@ import * as plotly from "plotly.js-dist-min" import React, { FC, useEffect } from "react" -import { Card, CardContent, Grid, Typography, useTheme, Box } from "@mui/material" +import { Card, CardContent, Grid, Typography, useTheme } from "@mui/material" import { makeHovertext } from "../graphUtil" import { usePlotlyColorTheme } from "../state" import { PlotType } from "../apiClient" From d425b2f586485f52ff95e18c2442ed7823f8b80f Mon Sep 17 00:00:00 2001 From: ET <57718207+turbotimon@users.noreply.github.com> Date: Wed, 14 Feb 2024 11:22:50 +0000 Subject: [PATCH 31/98] lint --- optuna_dashboard/_storage_url.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/optuna_dashboard/_storage_url.py b/optuna_dashboard/_storage_url.py index 2d660d3d..e272236e 100644 --- a/optuna_dashboard/_storage_url.py +++ b/optuna_dashboard/_storage_url.py @@ -61,7 +61,9 @@ def get_storage( def _has_sqlite_header(storage_url: str) -> bool: storage_path = Path(storage_url) - SQLITE_HEADER = b"SQLite format 3\x00" # see https://github.com/optuna/optuna-dashboard/pull/800 + SQLITE_HEADER = ( + b"SQLite format 3\x00" # see https://github.com/optuna/optuna-dashboard/pull/800 + ) with storage_path.open(mode="rb") as f: header = f.read(len(SQLITE_HEADER)) return header == SQLITE_HEADER From 8be7600ec88684275c5c17940ac70196a9111521 Mon Sep 17 00:00:00 2001 From: porink0424 Date: Fri, 16 Feb 2024 18:57:37 +0900 Subject: [PATCH 32/98] Drop inf & -inf from TrialValueNumber --- standalone_app/src/components/PlotHistory.tsx | 6 +++--- standalone_app/src/components/PlotImportance.tsx | 4 ++-- standalone_app/src/components/TrialTable.tsx | 10 ---------- standalone_app/src/sqlite3.ts | 6 +++--- standalone_app/src/types/index.d.ts | 2 +- 5 files changed, 9 insertions(+), 19 deletions(-) diff --git a/standalone_app/src/components/PlotHistory.tsx b/standalone_app/src/components/PlotHistory.tsx index 24f90034..b94c5ac8 100644 --- a/standalone_app/src/components/PlotHistory.tsx +++ b/standalone_app/src/components/PlotHistory.tsx @@ -178,8 +178,8 @@ const filterFunc = (trial: Trial, objectiveId: number): boolean => { } return ( trial.values.length > objectiveId && - trial.values[objectiveId] !== "inf" && - trial.values[objectiveId] !== "-inf" + trial.values[objectiveId] !== Infinity && + trial.values[objectiveId] !== -Infinity ) } @@ -244,7 +244,7 @@ const plotHistory = ( return null } const value = trial.values[objectiveId] - if (value === "inf" || value === "-inf") { + if (value === Infinity || value === -Infinity) { return null } return value diff --git a/standalone_app/src/components/PlotImportance.tsx b/standalone_app/src/components/PlotImportance.tsx index 8135be26..5b4baf02 100644 --- a/standalone_app/src/components/PlotImportance.tsx +++ b/standalone_app/src/components/PlotImportance.tsx @@ -80,8 +80,8 @@ const filterFunc = (trial: Trial, objectiveId: number): boolean => { } return ( trial.values.length > objectiveId && - trial.values[objectiveId] !== "inf" && - trial.values[objectiveId] !== "-inf" + trial.values[objectiveId] !== Infinity && + trial.values[objectiveId] !== -Infinity ) } diff --git a/standalone_app/src/components/TrialTable.tsx b/standalone_app/src/components/TrialTable.tsx index d8b4f163..41cabdd4 100644 --- a/standalone_app/src/components/TrialTable.tsx +++ b/standalone_app/src/components/TrialTable.tsx @@ -37,11 +37,6 @@ export const TrialTable: FC<{ } else if (secondVal === undefined) { return ascending ? 1 : -1 } - if (firstVal === "-inf" || secondVal === "inf") { - return 1 - } else if (secondVal === "-inf" || firstVal === "inf") { - return -1 - } return firstVal < secondVal ? 1 : -1 }, toCellValue: (i) => { @@ -69,11 +64,6 @@ export const TrialTable: FC<{ } else if (secondVal === undefined) { return ascending ? 1 : -1 } - if (firstVal === "-inf" || secondVal === "inf") { - return 1 - } else if (secondVal === "-inf" || firstVal === "inf") { - return -1 - } return firstVal < secondVal ? 1 : -1 }, toCellValue: (i) => { diff --git a/standalone_app/src/sqlite3.ts b/standalone_app/src/sqlite3.ts index a0bf018b..682bf803 100644 --- a/standalone_app/src/sqlite3.ts +++ b/standalone_app/src/sqlite3.ts @@ -389,11 +389,11 @@ const getTrialIntermediateValues = ( step: vals[0], value: vals[2] === "INF_NEG" - ? "-inf" + ? -Infinity : vals[2] === "INF_POS" - ? "+inf" + ? Infinity : vals[2] === "NAN" - ? "nan" + ? NaN : vals[1], }) }, diff --git a/standalone_app/src/types/index.d.ts b/standalone_app/src/types/index.d.ts index da00a7aa..e379a926 100644 --- a/standalone_app/src/types/index.d.ts +++ b/standalone_app/src/types/index.d.ts @@ -1,6 +1,6 @@ declare const IS_VSCODE: boolean -type TrialValueNumber = number | "inf" | "-inf" +type TrialValueNumber = number type TrialIntermediateValueNumber = number | "inf" | "-inf" | "nan" type TrialState = "Running" | "Complete" | "Pruned" | "Fail" | "Waiting" type TrialStateFinished = "Complete" | "Fail" | "Pruned" From 1c9dbbb7bc7a589bb3ebfd455eea1f4ee6c81bd4 Mon Sep 17 00:00:00 2001 From: keisuke-umezawa Date: Sun, 18 Feb 2024 14:49:27 +0900 Subject: [PATCH 33/98] Replace StudySummary to ForzenStudy --- optuna_dashboard/_app.py | 34 +++++++++++++------------- optuna_dashboard/_serializer.py | 33 +++++++++++-------------- optuna_dashboard/_storage.py | 36 ++++++--------------------- python_tests/test_serializers.py | 42 ++++++++++++++------------------ 4 files changed, 57 insertions(+), 88 deletions(-) diff --git a/optuna_dashboard/_app.py b/optuna_dashboard/_app.py index 1d4c9f7c..91cf08d1 100644 --- a/optuna_dashboard/_app.py +++ b/optuna_dashboard/_app.py @@ -40,11 +40,11 @@ from ._preferential_history import remove_history from ._preferential_history import report_history from ._preferential_history import restore_history from ._rdb_migration import register_rdb_migration_route +from ._serializer import serialize_frozen_study from ._serializer import serialize_study_detail -from ._serializer import serialize_study_summary from ._storage import create_new_study -from ._storage import get_study_summaries -from ._storage import get_study_summary +from ._storage import get_studies +from ._storage import get_study from ._storage import get_trials from ._storage_url import get_storage from .artifact._backend import delete_all_artifacts @@ -102,8 +102,8 @@ def create_app( @app.get("/api/studies") @json_api_view def list_study_summaries() -> dict[str, Any]: - summaries = get_study_summaries(storage) - serialized = [serialize_study_summary(summary) for summary in summaries] + studies = get_studies(storage) + serialized = [serialize_frozen_study(s) for s in studies] return { "study_summaries": serialized, } @@ -131,12 +131,12 @@ def create_app( response.status = 400 # Bad request return {"reason": f"'{study_name}' already exists"} - summary = get_study_summary(storage, study_id) - if summary is None: + study = get_study(storage, study_id) + if study is None: response.status = 500 # Internal server error return {"reason": "Failed to create study"} response.status = 201 # Created - return {"study_summary": serialize_study_summary(summary)} + return {"study_summary": serialize_frozen_study(study)} @app.post("/api/studies//rename") @json_api_view @@ -167,14 +167,14 @@ def create_app( response.status = 500 storage.delete_study(dst_study._study_id) return {"reason": str(e)} - new_study_summary = get_study_summary(storage, dst_study._study_id) - if new_study_summary is None: + new_study = get_study(storage, dst_study._study_id) + if new_study is None: response.status = 500 return {"reason": "Failed to load the new study"} storage.delete_study(src_study._study_id) response.status = 201 - return serialize_study_summary(new_study_summary) + return serialize_frozen_study(new_study) @app.delete("/api/studies/") @json_api_view @@ -201,24 +201,24 @@ def create_app( return {"reason": "`after` should be larger or equal 0."} except KeyError: after = 0 - summary = get_study_summary(storage, study_id) - if summary is None: + study = get_study(storage, study_id) + if study is None: response.status = 404 # Not found return {"reason": f"study_id={study_id} is not found"} trials = get_trials(storage, study_id) - system_attrs = getattr(summary, "system_attrs", {}) + system_attrs = getattr(study, "system_attrs", {}) is_preferential = system_attrs.get(_SYSTEM_ATTR_PREFERENTIAL_STUDY, False) # TODO(c-bata): Cache best_trials if is_preferential: best_trials = get_best_preferential_trials(study_id, storage) - elif len(summary.directions) == 1: + elif len(study.directions) == 1: if len([t for t in trials if t.state == TrialState.COMPLETE]) == 0: best_trials = [] else: best_trials = [storage.get_best_trial(study_id)] else: - best_trials = get_pareto_front_trials(trials=trials, directions=summary.directions) + best_trials = get_pareto_front_trials(trials=trials, directions=study.directions) ( # TODO: intersection_search_space and union_search_space look more clear since now we # have union_user_attrs. @@ -232,7 +232,7 @@ def create_app( skipped_trial_ids = get_skipped_trial_ids(system_attrs) skipped_trial_numbers = [t.number for t in trials if t._trial_id in skipped_trial_ids] return serialize_study_detail( - summary, + study, best_trials, trials[after:], intersection, diff --git a/optuna_dashboard/_serializer.py b/optuna_dashboard/_serializer.py index e3c4da65..bbb94d97 100644 --- a/optuna_dashboard/_serializer.py +++ b/optuna_dashboard/_serializer.py @@ -12,7 +12,7 @@ from optuna.distributions import BaseDistribution from optuna.distributions import CategoricalDistribution from optuna.distributions import FloatDistribution from optuna.distributions import IntDistribution -from optuna.study import StudySummary +from optuna.study._frozen import FrozenStudy from optuna.trial import FrozenTrial from . import _note as note @@ -116,25 +116,22 @@ def serialize_attrs(attrs: dict[str, Any]) -> list[Attribute]: return serialized -def serialize_study_summary(summary: StudySummary) -> dict[str, Any]: +def serialize_frozen_study(study: FrozenStudy) -> dict[str, Any]: serialized = { - "study_id": summary._study_id, - "study_name": summary.study_name, - "directions": [d.name.lower() for d in summary.directions], - "user_attrs": serialize_attrs(summary.user_attrs), - "is_preferential": getattr(summary, "_system_attrs", {}).get( + "study_id": study._study_id, + "study_name": study.study_name, + "directions": [d.name.lower() for d in study.directions], + "user_attrs": serialize_attrs(study.user_attrs), + "is_preferential": getattr(study, "_system_attrs", {}).get( _SYSTEM_ATTR_PREFERENTIAL_STUDY, False ), } - if summary.datetime_start is not None: - serialized["datetime_start"] = summary.datetime_start.isoformat() - return serialized def serialize_study_detail( - summary: StudySummary, + study: FrozenStudy, best_trials: list[FrozenTrial], trials: list[FrozenTrial], intersection: list[tuple[str, BaseDistribution]], @@ -145,20 +142,18 @@ def serialize_study_detail( skipped_trial_numbers: list[int], ) -> dict[str, Any]: serialized: dict[str, Any] = { - "name": summary.study_name, - "directions": [d.name.lower() for d in summary.directions], - "user_attrs": serialize_attrs(summary.user_attrs), + "name": study.study_name, + "directions": [d.name.lower() for d in study.directions], + "user_attrs": serialize_attrs(study.user_attrs), } - system_attrs = getattr(summary, "system_attrs", {}) + system_attrs = getattr(study, "system_attrs", {}) serialized["artifacts"] = list_study_artifacts(system_attrs) - if summary.datetime_start is not None: - serialized["datetime_start"] = summary.datetime_start.isoformat() serialized["trials"] = [ - serialize_frozen_trial(summary._study_id, trial, system_attrs) for trial in trials + serialize_frozen_trial(study._study_id, trial, system_attrs) for trial in trials ] serialized["best_trials"] = [ - serialize_frozen_trial(summary._study_id, trial, system_attrs) for trial in best_trials + serialize_frozen_trial(study._study_id, trial, system_attrs) for trial in best_trials ] serialized["intersection_search_space"] = serialize_search_space(intersection) serialized["union_search_space"] = serialize_search_space(union) diff --git a/optuna_dashboard/_storage.py b/optuna_dashboard/_storage.py index 460d7cb7..fe4a36c0 100644 --- a/optuna_dashboard/_storage.py +++ b/optuna_dashboard/_storage.py @@ -3,19 +3,14 @@ from __future__ import annotations from datetime import datetime from datetime import timedelta import threading -import typing from optuna.storages import BaseStorage from optuna.storages import RDBStorage from optuna.study import StudyDirection -from optuna.study import StudySummary +from optuna.study._frozen import FrozenStudy from optuna.trial import FrozenTrial -if typing.TYPE_CHECKING: - from optuna.study._frozen import FrozenStudy - - # In-memory trials cache trials_cache_lock = threading.Lock() trials_cache: dict[int, list[FrozenTrial]] = {} @@ -49,19 +44,19 @@ def get_trials(storage: BaseStorage, study_id: int) -> list[FrozenTrial]: return trials -def get_study_summaries(storage: BaseStorage) -> list[StudySummary]: +def get_studies(storage: BaseStorage) -> list[FrozenStudy]: frozen_studies = storage.get_all_studies() if isinstance(storage, RDBStorage): frozen_studies = sorted(frozen_studies, key=lambda s: s._study_id) - return [_frozen_study_to_study_summary(s) for s in frozen_studies] + return frozen_studies -def get_study_summary(storage: BaseStorage, study_id: int) -> StudySummary | None: - summaries = get_study_summaries(storage) - for summary in summaries: - if summary._study_id != study_id: +def get_study(storage: BaseStorage, study_id: int) -> FrozenStudy: + studies = get_studies(storage) + for s in studies: + if s._study_id != study_id: continue - return summary + return s return None @@ -70,18 +65,3 @@ def create_new_study( ) -> int: study_id = storage.create_new_study(directions, study_name=study_name) return study_id - - -def _frozen_study_to_study_summary(frozen_study: "FrozenStudy") -> StudySummary: - is_single = len(frozen_study.directions) == 1 - return StudySummary( - study_name=frozen_study.study_name, - study_id=frozen_study._study_id, - direction=frozen_study.direction if is_single else None, - directions=frozen_study.directions if not is_single else None, - user_attrs=frozen_study.user_attrs, - system_attrs=frozen_study.system_attrs, - best_trial=None, - n_trials=-1, # This field isn't used by Dashboard. - datetime_start=None, - ) diff --git a/python_tests/test_serializers.py b/python_tests/test_serializers.py index a991d5d3..fb43a9c8 100644 --- a/python_tests/test_serializers.py +++ b/python_tests/test_serializers.py @@ -5,9 +5,9 @@ import sys import numpy as np import optuna from optuna_dashboard._serializer import serialize_attrs +from optuna_dashboard._serializer import serialize_frozen_study from optuna_dashboard._serializer import serialize_study_detail -from optuna_dashboard._serializer import serialize_study_summary -from optuna_dashboard._storage import get_study_summaries +from optuna_dashboard._storage import get_studies from optuna_dashboard.preferential import create_study from packaging import version import pytest @@ -60,26 +60,20 @@ def test_serialize_numpy_floating() -> None: def test_get_study_detail_is_preferential() -> None: storage = optuna.storages.InMemoryStorage() study = create_study(n_generate=4, storage=storage) - study_summaries = get_study_summaries(storage) - assert len(study_summaries) == 1 + studies = get_studies(storage) + assert len(studies) == 1 - study_summary = study_summaries[0] - study_detail = serialize_study_detail( - study_summary, [], study.trials, [], [], [], False, {}, [] - ) + study_detail = serialize_study_detail(studies[0], [], study.trials, [], [], [], False, {}, []) assert study_detail["is_preferential"] def test_get_study_detail_is_not_preferential() -> None: storage = optuna.storages.InMemoryStorage() study = optuna.create_study(storage=storage) - study_summaries = get_study_summaries(storage) - assert len(study_summaries) == 1 + studies = get_studies(storage) + assert len(studies) == 1 - study_summary = study_summaries[0] - study_detail = serialize_study_detail( - study_summary, [], study.trials, [], [], [], False, {}, [] - ) + study_detail = serialize_study_detail(studies[0], [], study.trials, [], [], [], False, {}, []) assert not study_detail["is_preferential"] @@ -87,20 +81,20 @@ def test_get_study_detail_is_not_preferential() -> None: @pytest.mark.skipif( version.parse(optuna.__version__) < version.parse("3.2.0"), reason="Needs optuna.search_space" ) -def test_get_study_summary_is_preferential() -> None: +def test_get_study_is_preferential() -> None: storage = optuna.storages.InMemoryStorage() create_study(n_generate=4, storage=storage) - study_summaries = get_study_summaries(storage) - assert len(study_summaries) == 1 + studies = get_studies(storage) + assert len(studies) == 1 - study_summary = serialize_study_summary(study_summaries[0]) - assert study_summary["is_preferential"] + serialized = serialize_frozen_study(studies[0]) + assert serialized["is_preferential"] -def test_get_study_summary_is_not_preferential() -> None: +def test_get_study_is_not_preferential() -> None: storage = optuna.storages.InMemoryStorage() optuna.create_study(storage=storage) - study_summaries = get_study_summaries(storage) - assert len(study_summaries) == 1 - study_summary = serialize_study_summary(study_summaries[0]) - assert not study_summary["is_preferential"] + studies = get_studies(storage) + assert len(studies) == 1 + serialized = serialize_frozen_study(studies[0]) + assert not serialized["is_preferential"] From ed6636955d936141b04e908909d8ea709f2e3e9a Mon Sep 17 00:00:00 2001 From: keisuke-umezawa Date: Sun, 18 Feb 2024 14:56:34 +0900 Subject: [PATCH 34/98] Fix mypy --- optuna_dashboard/_storage.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/optuna_dashboard/_storage.py b/optuna_dashboard/_storage.py index fe4a36c0..8fe10e0a 100644 --- a/optuna_dashboard/_storage.py +++ b/optuna_dashboard/_storage.py @@ -51,7 +51,7 @@ def get_studies(storage: BaseStorage) -> list[FrozenStudy]: return frozen_studies -def get_study(storage: BaseStorage, study_id: int) -> FrozenStudy: +def get_study(storage: BaseStorage, study_id: int) -> FrozenStudy | None: studies = get_studies(storage) for s in studies: if s._study_id != study_id: From 9170b8824f69b08dd94d1dfd26e5c9910f8a93d8 Mon Sep 17 00:00:00 2001 From: keisuke-umezawa Date: Sun, 18 Feb 2024 15:11:24 +0900 Subject: [PATCH 35/98] Fix unittest --- optuna_dashboard/_serializer.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/optuna_dashboard/_serializer.py b/optuna_dashboard/_serializer.py index bbb94d97..ee527ca6 100644 --- a/optuna_dashboard/_serializer.py +++ b/optuna_dashboard/_serializer.py @@ -122,9 +122,7 @@ def serialize_frozen_study(study: FrozenStudy) -> dict[str, Any]: "study_name": study.study_name, "directions": [d.name.lower() for d in study.directions], "user_attrs": serialize_attrs(study.user_attrs), - "is_preferential": getattr(study, "_system_attrs", {}).get( - _SYSTEM_ATTR_PREFERENTIAL_STUDY, False - ), + "is_preferential": study.system_attrs.get(_SYSTEM_ATTR_PREFERENTIAL_STUDY, False), } return serialized @@ -146,7 +144,7 @@ def serialize_study_detail( "directions": [d.name.lower() for d in study.directions], "user_attrs": serialize_attrs(study.user_attrs), } - system_attrs = getattr(study, "system_attrs", {}) + system_attrs = study.system_attrs serialized["artifacts"] = list_study_artifacts(system_attrs) serialized["trials"] = [ From 8106f1edd28094f97b74bdd22c6c0ec9b8f1d7f0 Mon Sep 17 00:00:00 2001 From: y0z Date: Wed, 21 Feb 2024 16:44:14 +0900 Subject: [PATCH 36/98] Virtualize trials list. --- optuna_dashboard/ts/components/TrialList.tsx | 137 ++++++++++++------- package-lock.json | 39 ++++++ package.json | 1 + 3 files changed, 127 insertions(+), 50 deletions(-) diff --git a/optuna_dashboard/ts/components/TrialList.tsx b/optuna_dashboard/ts/components/TrialList.tsx index cfde6536..444fe5af 100644 --- a/optuna_dashboard/ts/components/TrialList.tsx +++ b/optuna_dashboard/ts/components/TrialList.tsx @@ -29,6 +29,8 @@ import { actionCreator } from "../action" import { TrialFormWidgets } from "./TrialFormWidgets" import { TrialArtifactCards } from "./TrialArtifactCards" +import { useVirtualizer } from "@tanstack/react-virtual" + const states: TrialState[] = [ "Complete", "Pruned", @@ -344,6 +346,14 @@ export const TrialList: FC<{ studyDetail: StudyDetail | null }> = ({ (state) => allTrials.filter((t) => t.state === state).length ) }, [studyDetail?.trials]) + const listParentRef = React.useRef(null) + + const rowVirtualizer = useVirtualizer({ + count: trials.length, + getScrollElement: () => listParentRef.current, + estimateSize: () => 75, + overscan: 10, + }) const trialListWidth = 200 @@ -353,13 +363,14 @@ export const TrialList: FC<{ studyDetail: StudyDetail | null }> = ({ return ( - + {trials.length} Trials @@ -417,65 +428,91 @@ export const TrialList: FC<{ studyDetail: StudyDetail | null }> = ({ - {trials.map((trial) => { - return ( - - { - if (e.shiftKey) { - let next: number[] - const selectedNumbers = selected.map((t) => t.number) - const alreadySelected = - selectedNumbers.findIndex((n) => n === trial.number) >= - 0 - if (alreadySelected) { - next = selectedNumbers.filter((n) => n !== trial.number) - } else { - next = [...selectedNumbers, trial.number] - } - navigate( - getTrialListLink(trial.study_id, excludedStates, next) - ) - } else { - navigate( - getTrialListLink(trial.study_id, excludedStates, [ - trial.number, - ]) - ) - } - }} - selected={ - selected.findIndex((t) => t.number === trial.number) !== -1 - } + + {rowVirtualizer.getVirtualItems().map((virtualItem) => { + console.log(virtualItem.index, virtualItem.start, virtualItem.end) + const trial = trials[virtualItem.index] + return ( + - - - - {isBestTrial(trial.trial_id) ? ( + { + if (e.shiftKey) { + let next: number[] + const selectedNumbers = selected.map((t) => t.number) + const alreadySelected = + selectedNumbers.findIndex( + (n) => n === trial.number + ) >= 0 + if (alreadySelected) { + next = selectedNumbers.filter( + (n) => n !== trial.number + ) + } else { + next = [...selectedNumbers, trial.number] + } + navigate( + getTrialListLink(trial.study_id, excludedStates, next) + ) + } else { + navigate( + getTrialListLink(trial.study_id, excludedStates, [ + trial.number, + ]) + ) + } + }} + selected={ + selected.findIndex((t) => t.number === trial.number) !== + -1 + } + sx={{ + display: "flex", + flexDirection: "column", + alignItems: "flex-start", + }} + > + + - ) : null} - - - - ) - })} + {isBestTrial(trial.trial_id) ? ( + + ) : null} + + + + ) + })} + diff --git a/package-lock.json b/package-lock.json index 1d9a286e..11df1cdf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,6 +16,7 @@ "@mui/material": "^5.12.1", "@react-three/drei": "^9.80.0", "@react-three/fiber": "^8.13.6", + "@tanstack/react-virtual": "^3.1.2", "@types/three": "^0.154.0", "axios": "^1.6.0", "elkjs": "^0.8.2", @@ -3810,6 +3811,31 @@ "@sinonjs/commons": "^1.7.0" } }, + "node_modules/@tanstack/react-virtual": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.1.2.tgz", + "integrity": "sha512-qibmxtctgOZo2I+3Rw5GR9kXgaa15U5r3/idDY1ItUKW15UK7GhCfyIfE6qYuJ1fxQF6dJDsD8SbpPyuJgpxuA==", + "dependencies": { + "@tanstack/virtual-core": "3.1.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@tanstack/virtual-core": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.1.2.tgz", + "integrity": "sha512-DATZJs8iejkIUqXZe6ruDAnjFo78BKnIIgqQZrc7CmEFqfLEN/TPD91n4hRfo6hpRB6xC00bwKxv7vdjFNEmOg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, "node_modules/@testing-library/dom": { "version": "8.19.0", "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.19.0.tgz", @@ -17926,6 +17952,19 @@ "@sinonjs/commons": "^1.7.0" } }, + "@tanstack/react-virtual": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.1.2.tgz", + "integrity": "sha512-qibmxtctgOZo2I+3Rw5GR9kXgaa15U5r3/idDY1ItUKW15UK7GhCfyIfE6qYuJ1fxQF6dJDsD8SbpPyuJgpxuA==", + "requires": { + "@tanstack/virtual-core": "3.1.2" + } + }, + "@tanstack/virtual-core": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.1.2.tgz", + "integrity": "sha512-DATZJs8iejkIUqXZe6ruDAnjFo78BKnIIgqQZrc7CmEFqfLEN/TPD91n4hRfo6hpRB6xC00bwKxv7vdjFNEmOg==" + }, "@testing-library/dom": { "version": "8.19.0", "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.19.0.tgz", diff --git a/package.json b/package.json index 9e6e59e9..5ab63bdc 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "@mui/material": "^5.12.1", "@react-three/drei": "^9.80.0", "@react-three/fiber": "^8.13.6", + "@tanstack/react-virtual": "^3.1.2", "@types/three": "^0.154.0", "axios": "^1.6.0", "elkjs": "^0.8.2", From 89174652318c11d244ad67bdb2b0fafab0fc0ea7 Mon Sep 17 00:00:00 2001 From: y0z Date: Wed, 21 Feb 2024 19:25:14 +0900 Subject: [PATCH 37/98] Fix style. --- optuna_dashboard/ts/components/TrialList.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/optuna_dashboard/ts/components/TrialList.tsx b/optuna_dashboard/ts/components/TrialList.tsx index 444fe5af..1b81c897 100644 --- a/optuna_dashboard/ts/components/TrialList.tsx +++ b/optuna_dashboard/ts/components/TrialList.tsx @@ -370,7 +370,7 @@ export const TrialList: FC<{ studyDetail: StudyDetail | null }> = ({ height: `calc(100vh - ${theme.spacing(8)})`, }} > - + {trials.length} Trials From 8f39413e9c2e00a58687cab3cdae1d19bde33ee0 Mon Sep 17 00:00:00 2001 From: keisuke-umezawa Date: Thu, 22 Feb 2024 10:15:10 +0900 Subject: [PATCH 38/98] Follow review comments --- optuna_dashboard/_app.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/optuna_dashboard/_app.py b/optuna_dashboard/_app.py index 91cf08d1..c2e5099a 100644 --- a/optuna_dashboard/_app.py +++ b/optuna_dashboard/_app.py @@ -101,9 +101,10 @@ def create_app( @app.get("/api/studies") @json_api_view - def list_study_summaries() -> dict[str, Any]: + def list_studies() -> dict[str, Any]: studies = get_studies(storage) serialized = [serialize_frozen_study(s) for s in studies] + # TODO(umezawa): Rename `study_summaries` to `studies`. return { "study_summaries": serialized, } From 9eba1ce243248290a844800fdad616fa96c92e3f Mon Sep 17 00:00:00 2001 From: keisuke umezawa Date: Thu, 22 Feb 2024 10:38:59 +0900 Subject: [PATCH 39/98] Apply suggestions from code review Co-authored-by: Shuhei Watanabe <47781922+nabenabe0928@users.noreply.github.com> --- e2e_tests/test_standalone/test_study_list.py | 33 +++++++------------- 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/e2e_tests/test_standalone/test_study_list.py b/e2e_tests/test_standalone/test_study_list.py index 18c57e08..0e6b5079 100644 --- a/e2e_tests/test_standalone/test_study_list.py +++ b/e2e_tests/test_standalone/test_study_list.py @@ -1,6 +1,6 @@ import os import tempfile -from typing import Callable +from collections.abc import Callable import optuna from playwright.sync_api import Page @@ -28,8 +28,16 @@ def test_home( assert title == "Optuna Dashboard (Wasm ver.)" -def create_rdb_storage_sqlite_file(filename: str, study_name: str): - storage = optuna.storages.RDBStorage(f"sqlite:///{filename}") +def create_rdb_storage_file(filename: str, study_name: str, storage_type: str): + if storage_type == "rdb": + storage = optuna.storages.RDBStorage(f"sqlite:///{filename}") + elif storage_type == "journal": + storage = optuna.storages.JournalStorage( + optuna.storages.JournalFileStorage(f"{filename}"), + ) + else: + assert False, f"Got an unexpected storage_type={storage_type}." + study = optuna.create_study(study_name=study_name, storage=storage) def objective(trial: optuna.Trial) -> float: @@ -40,24 +48,7 @@ def create_rdb_storage_sqlite_file(filename: str, study_name: str): study.optimize(objective, n_trials=100) -def create_journal_storage_local_file(filename: str, study_name: str): - storage = optuna.storages.JournalStorage( - optuna.storages.JournalFileStorage(f"{filename}"), - ) - study = optuna.create_study(study_name=study_name, storage=storage) - - def objective(trial: optuna.Trial) -> float: - x1 = trial.suggest_float("x1", 0, 10) - x2 = trial.suggest_float("x2", 0, 10) - return (x1 - 2) ** 2 + (x2 - 5) ** 2 - - study.optimize(objective, n_trials=100) - - -@pytest.mark.parametrize( - "create_storage_file", - [create_rdb_storage_sqlite_file, create_journal_storage_local_file], -) +@pytest.mark.parametrize("storage_type", ["rdb", "journal"]) def test_load_storage( page: Page, server_url: str, From 3280647781de3713ecbbf187408663a3a4595fcb Mon Sep 17 00:00:00 2001 From: nabenabe0928 Date: Thu, 22 Feb 2024 07:15:16 +0100 Subject: [PATCH 40/98] Add PED-ANOVA as the first option for importance evaluator --- optuna_dashboard/_importance.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/optuna_dashboard/_importance.py b/optuna_dashboard/_importance.py index f0a8b284..100679a7 100644 --- a/optuna_dashboard/_importance.py +++ b/optuna_dashboard/_importance.py @@ -26,6 +26,16 @@ except Exception as e: FastFanovaImportanceEvaluator = None # type: ignore +try: + from optuna.importance import PedAnovaImportanceEvaluator +except ImportError: + _logger.warning(f"optuna>=3.6.0 is required for PedAnovaImportanceEvaluator.") + PedAnovaImportanceEvaluator = None # type: ignore +except Exception as e: + _logger.warning(f"Skipping to use PedAnovaImportanceEvaluator due to {e}.") + PedAnovaImportanceEvaluator = None # type: ignore + + if TYPE_CHECKING: from typing import Callable from typing import Optional @@ -64,6 +74,12 @@ def _get_param_importances( *, target: Optional[Callable[[FrozenTrial], float]] = None, ) -> dict[str, float]: + if PedAnovaImportanceEvaluator is not None: + # TODO(nabenabe0928): We might want to pass baseline_quantile as an argument in the future. + return get_param_importances( + study, target=target, evaluator=PedAnovaImportanceEvaluator() + ) + if FastFanovaImportanceEvaluator is not None: try: evaluator = FastFanovaImportanceEvaluator(completed_trials=completed_trials) From 0ef5a7bcb406db38781fba5d1182c3a3743b69f0 Mon Sep 17 00:00:00 2001 From: nabenabe0928 Date: Thu, 22 Feb 2024 07:57:32 +0100 Subject: [PATCH 41/98] Address the flake8 issue --- optuna_dashboard/_importance.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/optuna_dashboard/_importance.py b/optuna_dashboard/_importance.py index 100679a7..ae721340 100644 --- a/optuna_dashboard/_importance.py +++ b/optuna_dashboard/_importance.py @@ -29,7 +29,7 @@ except Exception as e: try: from optuna.importance import PedAnovaImportanceEvaluator except ImportError: - _logger.warning(f"optuna>=3.6.0 is required for PedAnovaImportanceEvaluator.") + _logger.warning("optuna>=3.6.0 is required for PedAnovaImportanceEvaluator.") PedAnovaImportanceEvaluator = None # type: ignore except Exception as e: _logger.warning(f"Skipping to use PedAnovaImportanceEvaluator due to {e}.") From b6d62ce43074057383dbfe6d7a9358f8d4442203 Mon Sep 17 00:00:00 2001 From: nabenabe0928 Date: Thu, 22 Feb 2024 07:58:37 +0100 Subject: [PATCH 42/98] Address c-bata's comment --- optuna_dashboard/_importance.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/optuna_dashboard/_importance.py b/optuna_dashboard/_importance.py index ae721340..7469fa18 100644 --- a/optuna_dashboard/_importance.py +++ b/optuna_dashboard/_importance.py @@ -31,9 +31,6 @@ try: except ImportError: _logger.warning("optuna>=3.6.0 is required for PedAnovaImportanceEvaluator.") PedAnovaImportanceEvaluator = None # type: ignore -except Exception as e: - _logger.warning(f"Skipping to use PedAnovaImportanceEvaluator due to {e}.") - PedAnovaImportanceEvaluator = None # type: ignore if TYPE_CHECKING: From 3efee7438a6a81c20ce16286123c29c32e55afa6 Mon Sep 17 00:00:00 2001 From: nabenabe0928 Date: Thu, 22 Feb 2024 08:33:31 +0100 Subject: [PATCH 43/98] Apply formatter * Apply black * Add type ignore to PedAnova import --- optuna_dashboard/_importance.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/optuna_dashboard/_importance.py b/optuna_dashboard/_importance.py index 7469fa18..8aa4bb77 100644 --- a/optuna_dashboard/_importance.py +++ b/optuna_dashboard/_importance.py @@ -27,7 +27,7 @@ except Exception as e: try: - from optuna.importance import PedAnovaImportanceEvaluator + from optuna.importance import PedAnovaImportanceEvaluator # type: ignore[attr-defined] except ImportError: _logger.warning("optuna>=3.6.0 is required for PedAnovaImportanceEvaluator.") PedAnovaImportanceEvaluator = None # type: ignore @@ -73,9 +73,7 @@ def _get_param_importances( ) -> dict[str, float]: if PedAnovaImportanceEvaluator is not None: # TODO(nabenabe0928): We might want to pass baseline_quantile as an argument in the future. - return get_param_importances( - study, target=target, evaluator=PedAnovaImportanceEvaluator() - ) + return get_param_importances(study, target=target, evaluator=PedAnovaImportanceEvaluator()) if FastFanovaImportanceEvaluator is not None: try: From b976fa1aedf1cacdb5482b78e31f7161163b55f6 Mon Sep 17 00:00:00 2001 From: keisuke-umezawa Date: Sun, 25 Feb 2024 20:55:57 +0900 Subject: [PATCH 44/98] Follow review comments --- standalone_app/src/components/PlotIntermediateValues.tsx | 5 ++++- standalone_app/src/sqlite3.ts | 4 ++-- standalone_app/src/types/index.d.ts | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/standalone_app/src/components/PlotIntermediateValues.tsx b/standalone_app/src/components/PlotIntermediateValues.tsx index 2c10cf74..fbf8cc2a 100644 --- a/standalone_app/src/components/PlotIntermediateValues.tsx +++ b/standalone_app/src/components/PlotIntermediateValues.tsx @@ -80,7 +80,10 @@ const plotIntermediateValue = ( ) const plotData: Partial[] = filteredTrials.map((trial) => { const values = trial.intermediate_values.filter( - (iv) => iv.value !== "inf" && iv.value !== "-inf" && iv.value !== "nan" + (iv) => + iv.value !== Infinity && + iv.value !== -Infinity && + !Number.isNaN(iv.value) ) return { x: values.map((iv) => iv.step), diff --git a/standalone_app/src/sqlite3.ts b/standalone_app/src/sqlite3.ts index 682bf803..0330750b 100644 --- a/standalone_app/src/sqlite3.ts +++ b/standalone_app/src/sqlite3.ts @@ -218,9 +218,9 @@ const getTrialValues = ( callback: (vals: any[]) => { values.push( vals[1] === "INF_NEG" - ? "-inf" + ? -Infinity : vals[1] === "INF_POS" - ? "+inf" + ? Infinity : vals[0] ) }, diff --git a/standalone_app/src/types/index.d.ts b/standalone_app/src/types/index.d.ts index e379a926..684858e9 100644 --- a/standalone_app/src/types/index.d.ts +++ b/standalone_app/src/types/index.d.ts @@ -1,7 +1,7 @@ declare const IS_VSCODE: boolean type TrialValueNumber = number -type TrialIntermediateValueNumber = number | "inf" | "-inf" | "nan" +type TrialIntermediateValueNumber = number type TrialState = "Running" | "Complete" | "Pruned" | "Fail" | "Waiting" type TrialStateFinished = "Complete" | "Fail" | "Pruned" type StudyDirection = "maximize" | "minimize" | "not_set" From 3531b8af3897cb42682c7f36fef80091a401f261 Mon Sep 17 00:00:00 2001 From: c-bata Date: Fri, 1 Mar 2024 22:11:55 +0900 Subject: [PATCH 45/98] Fix the bug of code-server extension --- README.md | 3 --- docs/getting-started.rst | 3 --- vscode/CHANGELOG.md | 18 +++++++++++++++++- vscode/README.md | 15 --------------- vscode/package-lock.json | 4 ++-- vscode/package.json | 2 +- vscode/src/web/extension.ts | 30 ++++++++++++++++++++++++------ 7 files changed, 44 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index 2a2ee515..0df883e6 100644 --- a/README.md +++ b/README.md @@ -112,9 +112,6 @@ or install the code-server extension via [Open VSX](https://open-vsx.org/extensi Please right-click the SQLite3 files (`*.db` or `*.sqlite3`) in the VS Code file explorer and select the "Open in Optuna Dashboard" command from the dropdown menu. This extension leverages the browser-only version of Optuna Dashboard, so the same limitations apply. -Please note that we have confirmed the behavior of the code-server extension can be unstable. -When opening SQLite files, the dashboard may not appear on the first attempt, but it should be displayed upon a second try. - ## Submitting patches If you want to contribute, please check [Developers Guide](./CONTRIBUTING.md). diff --git a/docs/getting-started.rst b/docs/getting-started.rst index 3179d3f5..3375c469 100644 --- a/docs/getting-started.rst +++ b/docs/getting-started.rst @@ -228,9 +228,6 @@ or install the code-server extension via `Open VSX { + switch (message.type) { + case 'webviewDidLoad': + console.log("[host] Receive a webviewDidLoad event.") + const storageContentBase64 = await readFileAsBase64(fileUri) + panel.webview.postMessage({ + type: "optunaStorage", + content: storageContentBase64, + }) + break + } + } + ); } ) @@ -58,12 +66,22 @@ function uint8ArrayToBase64(uint8Array: Uint8Array): string { } function getWebviewContent(indexJsUri: vscode.Uri): string { + // https://code.visualstudio.com/api/extension-guides/webview#passing-messages-from-a-webview-to-an-extension return ` Optuna Dashboard (Wasm ver.) +
From 688d087240ee71fb8417fd786af9ef206d0d55e7 Mon Sep 17 00:00:00 2001 From: keisuke-umezawa Date: Sat, 2 Mar 2024 15:57:44 +0900 Subject: [PATCH 46/98] Fix isort --- e2e_tests/test_standalone/test_study_list.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e_tests/test_standalone/test_study_list.py b/e2e_tests/test_standalone/test_study_list.py index 0e6b5079..ed749979 100644 --- a/e2e_tests/test_standalone/test_study_list.py +++ b/e2e_tests/test_standalone/test_study_list.py @@ -1,6 +1,6 @@ +from collections.abc import Callable import os import tempfile -from collections.abc import Callable import optuna from playwright.sync_api import Page From 22653eeaf48892c82529c549f46a894555387c9b Mon Sep 17 00:00:00 2001 From: keisuke-umezawa Date: Sat, 2 Mar 2024 16:02:54 +0900 Subject: [PATCH 47/98] Update python version of standalone test --- .github/workflows/e2e-standalone-tests.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/e2e-standalone-tests.yml b/.github/workflows/e2e-standalone-tests.yml index 49839e4b..c3f654f2 100644 --- a/.github/workflows/e2e-standalone-tests.yml +++ b/.github/workflows/e2e-standalone-tests.yml @@ -31,6 +31,12 @@ jobs: with: node-version: '18' + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: '3.10' + architecture: x64 + - name: Setup Optuna ${{ matrix.optuna-version }} run: | python -m pip install --progress-bar off --upgrade pip setuptools From 5bab40e33c357e0ccb344b1ff40af5aec8aa56da Mon Sep 17 00:00:00 2001 From: keisuke-umezawa Date: Sat, 2 Mar 2024 22:13:44 +0900 Subject: [PATCH 48/98] Fix typo --- e2e_tests/test_standalone/test_study_list.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/e2e_tests/test_standalone/test_study_list.py b/e2e_tests/test_standalone/test_study_list.py index ed749979..9ac9f221 100644 --- a/e2e_tests/test_standalone/test_study_list.py +++ b/e2e_tests/test_standalone/test_study_list.py @@ -28,7 +28,7 @@ def test_home( assert title == "Optuna Dashboard (Wasm ver.)" -def create_rdb_storage_file(filename: str, study_name: str, storage_type: str): +def create_storage_file(filename: str, study_name: str, storage_type: str): if storage_type == "rdb": storage = optuna.storages.RDBStorage(f"sqlite:///{filename}") elif storage_type == "journal": @@ -52,7 +52,7 @@ def create_rdb_storage_file(filename: str, study_name: str, storage_type: str): def test_load_storage( page: Page, server_url: str, - create_storage_file: Callable[[str, str], optuna.storages.BaseStorage], + storage_type: str, ) -> None: study_name = "single-objective" url = f"{server_url}" @@ -61,7 +61,7 @@ def test_load_storage( with tempfile.NamedTemporaryFile() as fp: filename = fp.name path = os.path.join(dir, filename) - create_storage_file(filename, study_name) + create_storage_file(filename, study_name, storage_type) page.goto(url) with page.expect_file_chooser() as fc_info: page.get_by_role("button").nth(2).click() From 94815c56eee981d4785db04ec1b6e7e1ec5d03fa Mon Sep 17 00:00:00 2001 From: keisuke-umezawa Date: Sat, 2 Mar 2024 22:17:40 +0900 Subject: [PATCH 49/98] Fix flake8 --- e2e_tests/test_standalone/test_study_list.py | 1 - 1 file changed, 1 deletion(-) diff --git a/e2e_tests/test_standalone/test_study_list.py b/e2e_tests/test_standalone/test_study_list.py index 9ac9f221..3d163844 100644 --- a/e2e_tests/test_standalone/test_study_list.py +++ b/e2e_tests/test_standalone/test_study_list.py @@ -1,4 +1,3 @@ -from collections.abc import Callable import os import tempfile From e24137bff5e66355cb00357465a8ba5da307fa43 Mon Sep 17 00:00:00 2001 From: keisuke-umezawa Date: Sat, 2 Mar 2024 22:34:14 +0900 Subject: [PATCH 50/98] Use boolean state for api call --- optuna_dashboard/ts/action.ts | 5 +++++ optuna_dashboard/ts/components/StudyDetail.tsx | 10 ++++++++-- optuna_dashboard/ts/state.ts | 5 +++++ 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/optuna_dashboard/ts/action.ts b/optuna_dashboard/ts/action.ts index a0037f46..c4ad3cd9 100644 --- a/optuna_dashboard/ts/action.ts +++ b/optuna_dashboard/ts/action.ts @@ -27,6 +27,7 @@ import { isFileUploading, artifactIsAvailable, plotlypyIsAvailableState, + reloadingState, reloadIntervalState, trialsUpdatingState, studySummariesLoadingState, @@ -40,6 +41,7 @@ export const actionCreator = () => { useRecoilState(studySummariesState) const [studyDetails, setStudyDetails] = useRecoilState(studyDetailsState) + const setReloading = useSetRecoilState(reloadingState) const setReloadInterval = useSetRecoilState(reloadIntervalState) const setUploading = useSetRecoilState(isFileUploading) const setTrialsUpdating = useSetRecoilState(trialsUpdatingState) @@ -231,6 +233,7 @@ export const actionCreator = () => { } const updateStudyDetail = (studyId: number) => { + setReloading(true) let nLocalFixedTrials = 0 if (studyId in studyDetails) { const currentTrials = studyDetails[studyId].trials @@ -242,6 +245,7 @@ export const actionCreator = () => { } getStudyDetailAPI(studyId, nLocalFixedTrials) .then((study) => { + setReloading(false) const currentFixedTrials = studyId in studyDetails ? studyDetails[studyId].trials.slice(0, nLocalFixedTrials) @@ -250,6 +254,7 @@ export const actionCreator = () => { setStudyDetailState(studyId, study) }) .catch((err) => { + setReloading(false) const reason = err.response?.data.reason if (reason !== undefined) { enqueueSnackbar(`Failed to fetch study (reason=${reason})`, { diff --git a/optuna_dashboard/ts/components/StudyDetail.tsx b/optuna_dashboard/ts/components/StudyDetail.tsx index 065b90f5..963f7826 100644 --- a/optuna_dashboard/ts/components/StudyDetail.tsx +++ b/optuna_dashboard/ts/components/StudyDetail.tsx @@ -16,6 +16,7 @@ import HomeIcon from "@mui/icons-material/Home" import { StudyNote } from "./Note" import { actionCreator } from "../action" import { + reloadingState, reloadIntervalState, useStudyDetailValue, useStudyIsPreferential, @@ -53,6 +54,7 @@ export const StudyDetail: FC<{ const action = actionCreator() const studyId = useURLVars() const studyDetail = useStudyDetailValue(studyId) + const isLoading = useRecoilValue(reloadingState) const reloadInterval = useRecoilValue(reloadIntervalState) const studyName = useStudyName(studyId) const isPreferential = useStudyIsPreferential(studyId) @@ -61,7 +63,9 @@ export const StudyDetail: FC<{ studyName !== null ? `${studyName} (id=${studyId})` : `Study #${studyId}` useEffect(() => { - action.updateStudyDetail(studyId) + if (!isLoading) { + action.updateStudyDetail(studyId) + } action.updateAPIMeta() }, []) @@ -86,7 +90,9 @@ export const StudyDetail: FC<{ } const intervalId = setInterval(function () { - action.updateStudyDetail(studyId) + if (!isLoading) { + action.updateStudyDetail(studyId) + } }, interval) return () => clearInterval(intervalId) }, [reloadInterval, studyDetail, page]) diff --git a/optuna_dashboard/ts/state.ts b/optuna_dashboard/ts/state.ts index 5828985f..bac5d641 100644 --- a/optuna_dashboard/ts/state.ts +++ b/optuna_dashboard/ts/state.ts @@ -21,6 +21,11 @@ export const trialsUpdatingState = atom<{ default: {}, }) +export const reloadingState = atom({ + key: "reloadng", + default: false, +}) + // TODO(c-bata): Consider representing the state as boolean. export const reloadIntervalState = atom({ key: "reloadInterval", From 06d1527a36a5f85a7dae4baadc506dc08f847481 Mon Sep 17 00:00:00 2001 From: c-bata Date: Sun, 3 Mar 2024 01:13:49 +0900 Subject: [PATCH 51/98] Simplify type definition in the standalone app --- standalone_app/src/components/TrialTable.tsx | 6 ++---- standalone_app/src/journalStorage.ts | 11 ++--------- standalone_app/src/sqlite3.ts | 18 +++++------------- standalone_app/src/types/index.d.ts | 11 +++++------ 4 files changed, 14 insertions(+), 32 deletions(-) diff --git a/standalone_app/src/components/TrialTable.tsx b/standalone_app/src/components/TrialTable.tsx index 41cabdd4..49028fcb 100644 --- a/standalone_app/src/components/TrialTable.tsx +++ b/standalone_app/src/components/TrialTable.tsx @@ -86,8 +86,7 @@ export const TrialTable: FC<{ null, sortable: true, filterable: false, - // eslint-disable-next-line @typescript-eslint/no-unused-vars - less: (firstEl, secondEl, _): number => { + less: (firstEl, secondEl): number => { const firstVal = firstEl.params.find( (p) => p.name === s.name )?.param_internal_value @@ -117,8 +116,7 @@ export const TrialTable: FC<{ ?.value || null, sortable: attr_spec.sortable, filterable: false, - // eslint-disable-next-line @typescript-eslint/no-unused-vars - less: (firstEl, secondEl, _): number => { + less: (firstEl, secondEl): number => { const firstVal = firstEl.user_attrs.find( (attr) => attr.key === attr_spec.key )?.value diff --git a/standalone_app/src/journalStorage.ts b/standalone_app/src/journalStorage.ts index 64a32f7b..35c80da1 100644 --- a/standalone_app/src/journalStorage.ts +++ b/standalone_app/src/journalStorage.ts @@ -99,15 +99,8 @@ const parseDistribution = (distribution: string): Distribution => { } } else { return { - // TODO(gen740): support other types type: "CategoricalDistribution", - // eslint-disable-next-line @typescript-eslint/no-explicit-any - choices: distributionJson["attributes"]["choices"].map((choice: any) => { - return { - pytype: "str", - value: choice.toString(), - } - }), + choices: distributionJson["attributes"]["choices"], } } } @@ -201,7 +194,7 @@ class JournalStorage { } else if (distribution.type === "IntDistribution") { return value.toString() } else { - return distribution.choices[value].value + return distribution.choices[value] } })(), distribution: distribution, diff --git a/standalone_app/src/sqlite3.ts b/standalone_app/src/sqlite3.ts index 0330750b..d446f588 100644 --- a/standalone_app/src/sqlite3.ts +++ b/standalone_app/src/sqlite3.ts @@ -206,8 +206,8 @@ const getTrialValues = ( db: SQLite3DB, trialId: number, schemaVersion: string -): TrialValueNumber[] => { - const values: TrialValueNumber[] = [] +): number[] => { + const values: number[] = [] if (isGreaterSchemaVersion(schemaVersion, "v3.0.0.c")) { db.exec({ sql: @@ -267,13 +267,13 @@ const getTrialParams = (db: SQLite3DB, trialId: number): TrialParam[] => { const paramInternalValueToExternalValue = ( distribution: Distribution, internalValue: number -): string => { +): CategoricalChoiceType => { if (distribution.type === "FloatDistribution") { return internalValue.toString() } else if (distribution.type === "IntDistribution") { return internalValue.toString() } else { - return distribution.choices[internalValue].value + return distribution.choices[internalValue] } } @@ -336,17 +336,9 @@ const parseDistributionJSON = (t: string): Distribution => { log: true, } } else { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const choices = parsed.attributes.choices.map((value: any) => { - // TODO(c-bata): Support other types - return { - pytype: "str", - value: value.toString(), - } - }) return { type: "CategoricalDistribution", - choices: choices, + choices: parsed.attributes.choices, } } } diff --git a/standalone_app/src/types/index.d.ts b/standalone_app/src/types/index.d.ts index 684858e9..4bc34bf5 100644 --- a/standalone_app/src/types/index.d.ts +++ b/standalone_app/src/types/index.d.ts @@ -1,7 +1,5 @@ declare const IS_VSCODE: boolean -type TrialValueNumber = number -type TrialIntermediateValueNumber = number type TrialState = "Running" | "Complete" | "Pruned" | "Fail" | "Waiting" type TrialStateFinished = "Complete" | "Fail" | "Pruned" type StudyDirection = "maximize" | "minimize" | "not_set" @@ -22,14 +20,15 @@ type IntDistribution = { log: boolean } +type CategoricalChoiceType = null | boolean | number | string type CategoricalDistribution = { type: "CategoricalDistribution" - choices: { pytype: string; value: string }[] + choices: CategoricalChoiceType[] } type TrialIntermediateValue = { step: number - value: TrialIntermediateValueNumber + value: number } type Distribution = @@ -63,7 +62,7 @@ type Trial = { number: number study_id: number state: TrialState - values?: TrialValueNumber[] + values?: number[] params: TrialParam[] intermediate_values: TrialIntermediateValue[] user_attrs: Attribute[] @@ -74,7 +73,7 @@ type Trial = { type TrialParam = { name: string param_internal_value: number - param_external_value: string + param_external_value: CategoricalChoiceType param_external_type: string distribution: Distribution } From 18b188b06c20f213aba26971cfd892bc33a06faa Mon Sep 17 00:00:00 2001 From: c-bata Date: Fri, 1 Mar 2024 22:29:23 +0900 Subject: [PATCH 52/98] Fix lint error and revert debug logs --- vscode/CHANGELOG.md | 12 +++++------- vscode/package-lock.json | 4 ++-- vscode/package.json | 2 +- vscode/src/web/extension.ts | 25 ++++++++++--------------- 4 files changed, 18 insertions(+), 25 deletions(-) diff --git a/vscode/CHANGELOG.md b/vscode/CHANGELOG.md index 0b2084bc..73d0021a 100644 --- a/vscode/CHANGELOG.md +++ b/vscode/CHANGELOG.md @@ -6,19 +6,17 @@ Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how ## [Unreleased] -## 0.2.1 - -* Enable a "Open in Optuna Dashboard" menu for `.log` files. -* Fix a bug that the extension cannot show studies on the first attempt. +* [bug] Fix a bug that the extension cannot show studies on the first attempt. +* [feature] Enable a "Open in Optuna Dashboard" menu for `.log` files. ## 0.2.0 -* Added support for `JournalFileStorage`. -* Added support for code-server. +* [feature] Added support for `JournalFileStorage`. +* [feature] Added support for code-server. ## 0.1.0 -* Added older database schemas support (Optuna 2.6.0 or later) +* [feature] Added older database schemas support (Optuna 2.6.0 or later) ## 0.0.1 diff --git a/vscode/package-lock.json b/vscode/package-lock.json index 340a8bdb..ac6837b4 100644 --- a/vscode/package-lock.json +++ b/vscode/package-lock.json @@ -1,12 +1,12 @@ { "name": "optuna-dashboard", - "version": "0.2.1", + "version": "0.2.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "optuna-dashboard", - "version": "0.2.1", + "version": "0.2.0", "license": "MIT", "devDependencies": { "@types/mocha": "^10.0.1", diff --git a/vscode/package.json b/vscode/package.json index a3cb4a56..e5ee047a 100644 --- a/vscode/package.json +++ b/vscode/package.json @@ -3,7 +3,7 @@ "displayName": "Optuna Dashboard", "description": "Web Dashboard for Optuna", "publisher": "Optuna", - "version": "0.2.1", + "version": "0.2.0", "license": "MIT", "icon": "images/optuna-logo.png", "engines": { diff --git a/vscode/src/web/extension.ts b/vscode/src/web/extension.ts index 62dcaec8..914f35ba 100644 --- a/vscode/src/web/extension.ts +++ b/vscode/src/web/extension.ts @@ -30,20 +30,17 @@ export function activate(context: vscode.ExtensionContext) { const appPath = panel.webview.asWebviewUri(indexJsUri) panel.webview.html = getWebviewContent(appPath) - panel.webview.onDidReceiveMessage( - async (message: any) => { - switch (message.type) { - case 'webviewDidLoad': - console.log("[host] Receive a webviewDidLoad event.") - const storageContentBase64 = await readFileAsBase64(fileUri) - panel.webview.postMessage({ - type: "optunaStorage", - content: storageContentBase64, - }) - break - } + panel.webview.onDidReceiveMessage(async (message: any) => { + switch (message.type) { + case "webviewDidLoad": + const storageContentBase64 = await readFileAsBase64(fileUri) + panel.webview.postMessage({ + type: "optunaStorage", + content: storageContentBase64, + }) + break } - ); + }) } ) @@ -66,7 +63,6 @@ function uint8ArrayToBase64(uint8Array: Uint8Array): string { } function getWebviewContent(indexJsUri: vscode.Uri): string { - // https://code.visualstudio.com/api/extension-guides/webview#passing-messages-from-a-webview-to-an-extension return ` @@ -78,7 +74,6 @@ function getWebviewContent(indexJsUri: vscode.Uri): string { const vscodeApi = acquireVsCodeApi(); window.addEventListener('DOMContentLoaded', (event) => { vscodeApi.postMessage({ type: 'webviewDidLoad' }) - console.log("[webview] Post a webviewDidLoad event.") }) }()) From 3745b23eb986d4a81117b0887895434935e0374b Mon Sep 17 00:00:00 2001 From: keisuke-umezawa Date: Mon, 4 Mar 2024 17:50:02 +0900 Subject: [PATCH 53/98] Rename state --- optuna_dashboard/ts/action.ts | 12 +++++++----- optuna_dashboard/ts/components/StudyDetail.tsx | 4 ++-- optuna_dashboard/ts/state.ts | 10 +++++----- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/optuna_dashboard/ts/action.ts b/optuna_dashboard/ts/action.ts index c4ad3cd9..1a59d8fe 100644 --- a/optuna_dashboard/ts/action.ts +++ b/optuna_dashboard/ts/action.ts @@ -27,7 +27,7 @@ import { isFileUploading, artifactIsAvailable, plotlypyIsAvailableState, - reloadingState, + studyDetailLoadingState, reloadIntervalState, trialsUpdatingState, studySummariesLoadingState, @@ -41,7 +41,6 @@ export const actionCreator = () => { useRecoilState(studySummariesState) const [studyDetails, setStudyDetails] = useRecoilState(studyDetailsState) - const setReloading = useSetRecoilState(reloadingState) const setReloadInterval = useSetRecoilState(reloadIntervalState) const setUploading = useSetRecoilState(isFileUploading) const setTrialsUpdating = useSetRecoilState(trialsUpdatingState) @@ -52,6 +51,9 @@ export const actionCreator = () => { const setStudySummariesLoading = useSetRecoilState( studySummariesLoadingState ) + const setStudyDetailLoading = useSetRecoilState( + studyDetailLoadingState + ) const setStudyDetailState = (studyId: number, study: StudyDetail) => { setStudyDetails((prevVal) => { @@ -233,7 +235,7 @@ export const actionCreator = () => { } const updateStudyDetail = (studyId: number) => { - setReloading(true) + setStudyDetailLoading(true) let nLocalFixedTrials = 0 if (studyId in studyDetails) { const currentTrials = studyDetails[studyId].trials @@ -245,7 +247,7 @@ export const actionCreator = () => { } getStudyDetailAPI(studyId, nLocalFixedTrials) .then((study) => { - setReloading(false) + setStudyDetailLoading(false) const currentFixedTrials = studyId in studyDetails ? studyDetails[studyId].trials.slice(0, nLocalFixedTrials) @@ -254,7 +256,7 @@ export const actionCreator = () => { setStudyDetailState(studyId, study) }) .catch((err) => { - setReloading(false) + setStudyDetailLoading(false) const reason = err.response?.data.reason if (reason !== undefined) { enqueueSnackbar(`Failed to fetch study (reason=${reason})`, { diff --git a/optuna_dashboard/ts/components/StudyDetail.tsx b/optuna_dashboard/ts/components/StudyDetail.tsx index 963f7826..ff9ac356 100644 --- a/optuna_dashboard/ts/components/StudyDetail.tsx +++ b/optuna_dashboard/ts/components/StudyDetail.tsx @@ -16,7 +16,7 @@ import HomeIcon from "@mui/icons-material/Home" import { StudyNote } from "./Note" import { actionCreator } from "../action" import { - reloadingState, + studyDetailLoadingState, reloadIntervalState, useStudyDetailValue, useStudyIsPreferential, @@ -54,7 +54,7 @@ export const StudyDetail: FC<{ const action = actionCreator() const studyId = useURLVars() const studyDetail = useStudyDetailValue(studyId) - const isLoading = useRecoilValue(reloadingState) + const isLoading = useRecoilValue(studyDetailLoadingState) const reloadInterval = useRecoilValue(reloadIntervalState) const studyName = useStudyName(studyId) const isPreferential = useStudyIsPreferential(studyId) diff --git a/optuna_dashboard/ts/state.ts b/optuna_dashboard/ts/state.ts index bac5d641..19659aa4 100644 --- a/optuna_dashboard/ts/state.ts +++ b/optuna_dashboard/ts/state.ts @@ -21,11 +21,6 @@ export const trialsUpdatingState = atom<{ default: {}, }) -export const reloadingState = atom({ - key: "reloadng", - default: false, -}) - // TODO(c-bata): Consider representing the state as boolean. export const reloadIntervalState = atom({ key: "reloadInterval", @@ -70,6 +65,11 @@ export const studySummariesLoadingState = atom({ default: false, }) +export const studyDetailLoadingState = atom({ + key: "studyDetailLoading", + default: false, +}) + export const useStudyDetailValue = (studyId: number): StudyDetail | null => { const studyDetails = useRecoilValue(studyDetailsState) return studyDetails[studyId] || null From b3a63b2d75c2a6d97aec31960d8111392b564780 Mon Sep 17 00:00:00 2001 From: keisuke-umezawa Date: Mon, 4 Mar 2024 17:58:00 +0900 Subject: [PATCH 54/98] Create state for each study --- optuna_dashboard/ts/action.ts | 12 ++++++------ optuna_dashboard/ts/components/StudyDetail.tsx | 8 +++++--- optuna_dashboard/ts/state.ts | 4 ++-- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/optuna_dashboard/ts/action.ts b/optuna_dashboard/ts/action.ts index 1a59d8fe..04c3532b 100644 --- a/optuna_dashboard/ts/action.ts +++ b/optuna_dashboard/ts/action.ts @@ -51,9 +51,9 @@ export const actionCreator = () => { const setStudySummariesLoading = useSetRecoilState( studySummariesLoadingState ) - const setStudyDetailLoading = useSetRecoilState( - studyDetailLoadingState - ) + const [studyDetailLoading, setStudyDetailLoading] = useRecoilState< + Record + >(studyDetailLoadingState) const setStudyDetailState = (studyId: number, study: StudyDetail) => { setStudyDetails((prevVal) => { @@ -235,7 +235,7 @@ export const actionCreator = () => { } const updateStudyDetail = (studyId: number) => { - setStudyDetailLoading(true) + setStudyDetailLoading({ ...studyDetailLoading, [studyId]: true }) let nLocalFixedTrials = 0 if (studyId in studyDetails) { const currentTrials = studyDetails[studyId].trials @@ -247,7 +247,7 @@ export const actionCreator = () => { } getStudyDetailAPI(studyId, nLocalFixedTrials) .then((study) => { - setStudyDetailLoading(false) + setStudyDetailLoading({ ...studyDetailLoading, [studyId]: false }) const currentFixedTrials = studyId in studyDetails ? studyDetails[studyId].trials.slice(0, nLocalFixedTrials) @@ -256,7 +256,7 @@ export const actionCreator = () => { setStudyDetailState(studyId, study) }) .catch((err) => { - setStudyDetailLoading(false) + setStudyDetailLoading({ ...studyDetailLoading, [studyId]: false }) const reason = err.response?.data.reason if (reason !== undefined) { enqueueSnackbar(`Failed to fetch study (reason=${reason})`, { diff --git a/optuna_dashboard/ts/components/StudyDetail.tsx b/optuna_dashboard/ts/components/StudyDetail.tsx index ff9ac356..eaa17bb0 100644 --- a/optuna_dashboard/ts/components/StudyDetail.tsx +++ b/optuna_dashboard/ts/components/StudyDetail.tsx @@ -54,7 +54,9 @@ export const StudyDetail: FC<{ const action = actionCreator() const studyId = useURLVars() const studyDetail = useStudyDetailValue(studyId) - const isLoading = useRecoilValue(studyDetailLoadingState) + const isLoading = useRecoilValue>( + studyDetailLoadingState + ) const reloadInterval = useRecoilValue(reloadIntervalState) const studyName = useStudyName(studyId) const isPreferential = useStudyIsPreferential(studyId) @@ -63,7 +65,7 @@ export const StudyDetail: FC<{ studyName !== null ? `${studyName} (id=${studyId})` : `Study #${studyId}` useEffect(() => { - if (!isLoading) { + if (!isLoading[studyId]) { action.updateStudyDetail(studyId) } action.updateAPIMeta() @@ -90,7 +92,7 @@ export const StudyDetail: FC<{ } const intervalId = setInterval(function () { - if (!isLoading) { + if (!isLoading[studyId]) { action.updateStudyDetail(studyId) } }, interval) diff --git a/optuna_dashboard/ts/state.ts b/optuna_dashboard/ts/state.ts index 19659aa4..0811c51a 100644 --- a/optuna_dashboard/ts/state.ts +++ b/optuna_dashboard/ts/state.ts @@ -65,9 +65,9 @@ export const studySummariesLoadingState = atom({ default: false, }) -export const studyDetailLoadingState = atom({ +export const studyDetailLoadingState = atom>({ key: "studyDetailLoading", - default: false, + default: {}, }) export const useStudyDetailValue = (studyId: number): StudyDetail | null => { From 40f40dbb6aaa88a74f769393c08021cc62ffa774 Mon Sep 17 00:00:00 2001 From: c-bata Date: Sat, 2 Mar 2024 16:02:15 +0900 Subject: [PATCH 55/98] Update npm dependencies on standalone app --- standalone_app/package-lock.json | 1124 ++++++++++++++++-------------- standalone_app/package.json | 14 +- 2 files changed, 613 insertions(+), 525 deletions(-) diff --git a/standalone_app/package-lock.json b/standalone_app/package-lock.json index dee5635d..6feadbc3 100644 --- a/standalone_app/package-lock.json +++ b/standalone_app/package-lock.json @@ -8,16 +8,16 @@ "name": "optuna-dashboard-wasm", "version": "0.0.0", "dependencies": { - "@emotion/react": "^11.10.8", - "@emotion/styled": "^11.10.8", - "@mui/icons-material": "^5.11.16", - "@mui/lab": "^5.0.0-alpha.128", - "@mui/material": "^5.12.2", - "@sqlite.org/sqlite-wasm": "^3.41.2-build11", + "@emotion/react": "^11.11.3", + "@emotion/styled": "^11.11.0", + "@mui/icons-material": "^5.15.6", + "@mui/lab": "^5.0.0-alpha.162", + "@mui/material": "^5.15.6", + "@sqlite.org/sqlite-wasm": "^3.45.1-build1", "module-workers-polyfill": "^0.3.2", "notistack": "^3.0.1", "optuna": "../rustlib/pkg", - "plotly.js-dist-min": "^2.22.0", + "plotly.js-dist-min": "^2.28.0", "react": "^18.2.0", "react-dom": "^18.2.0", "react-router-dom": "^6.11.0", @@ -47,50 +47,51 @@ "license": "MIT" }, "node_modules/@babel/code-frame": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.21.4.tgz", - "integrity": "sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", + "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", "dependencies": { - "@babel/highlight": "^7.18.6" + "@babel/highlight": "^7.23.4", + "chalk": "^2.4.2" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.21.4.tgz", - "integrity": "sha512-orajc5T2PsRYUN3ZryCEFeMDYwyw09c/pZeaQEZPH0MpKzSvn3e0uXsDBu3k03VI+9DBiRo+l22BfKTpKwa/Wg==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", + "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", "dependencies": { - "@babel/types": "^7.21.4" + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", - "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", + "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", - "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", "dependencies": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", "js-tokens": "^4.0.0" }, "engines": { @@ -98,23 +99,23 @@ } }, "node_modules/@babel/runtime": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.5.tgz", - "integrity": "sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q==", + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.0.tgz", + "integrity": "sha512-Chk32uHMg6TnQdvw2e9IlqPpFX/6NLuK0Ys2PqLb7/gL5uFn9mXvK715FGLlOLQrcO4qIkNHkvPGktzzXexsFw==", "dependencies": { - "regenerator-runtime": "^0.13.11" + "regenerator-runtime": "^0.14.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/types": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.4.tgz", - "integrity": "sha512-rU2oY501qDxE8Pyo7i/Orqma4ziCOrby0/9mvbDUGEfvZjb279Nk9k19e2fiCxHbRRpY2ZyrgW1eq22mvmOIzA==", + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz", + "integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==", "dependencies": { - "@babel/helper-string-parser": "^7.19.4", - "@babel/helper-validator-identifier": "^7.19.1", + "@babel/helper-string-parser": "^7.23.4", + "@babel/helper-validator-identifier": "^7.22.20", "to-fast-properties": "^2.0.0" }, "engines": { @@ -131,76 +132,65 @@ } }, "node_modules/@emotion/babel-plugin": { - "version": "11.10.8", - "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.10.8.tgz", - "integrity": "sha512-gxNky50AJL3AlkbjvTARiwAqei6/tNUxDZPSKd+3jqWVM3AmdVTTdpjHorR/an/M0VJqdsuq5oGcFH+rjtyujQ==", + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz", + "integrity": "sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==", "dependencies": { "@babel/helper-module-imports": "^7.16.7", "@babel/runtime": "^7.18.3", - "@emotion/hash": "^0.9.0", - "@emotion/memoize": "^0.8.0", - "@emotion/serialize": "^1.1.1", + "@emotion/hash": "^0.9.1", + "@emotion/memoize": "^0.8.1", + "@emotion/serialize": "^1.1.2", "babel-plugin-macros": "^3.1.0", "convert-source-map": "^1.5.0", "escape-string-regexp": "^4.0.0", "find-root": "^1.1.0", "source-map": "^0.5.7", - "stylis": "4.1.4" - } - }, - "node_modules/@emotion/babel-plugin/node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "stylis": "4.2.0" } }, "node_modules/@emotion/cache": { - "version": "11.10.8", - "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.10.8.tgz", - "integrity": "sha512-5fyqGHi51LU95o7qQ/vD1jyvC4uCY5GcBT+UgP4LHdpO9jPDlXqhrRr9/wCKmfoAvh5G/F7aOh4MwQa+8uEqhA==", + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.11.0.tgz", + "integrity": "sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==", "dependencies": { - "@emotion/memoize": "^0.8.0", - "@emotion/sheet": "^1.2.1", - "@emotion/utils": "^1.2.0", - "@emotion/weak-memoize": "^0.3.0", - "stylis": "4.1.4" + "@emotion/memoize": "^0.8.1", + "@emotion/sheet": "^1.2.2", + "@emotion/utils": "^1.2.1", + "@emotion/weak-memoize": "^0.3.1", + "stylis": "4.2.0" } }, "node_modules/@emotion/hash": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.0.tgz", - "integrity": "sha512-14FtKiHhy2QoPIzdTcvh//8OyBlknNs2nXRwIhG904opCby3l+9Xaf/wuPvICBF0rc1ZCNBd3nKe9cd2mecVkQ==" + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.1.tgz", + "integrity": "sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==" }, "node_modules/@emotion/is-prop-valid": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.0.tgz", - "integrity": "sha512-3aDpDprjM0AwaxGE09bOPkNxHpBd+kA6jty3RnaEXdweX1DF1U3VQpPYb0g1IStAuK7SVQ1cy+bNBBKp4W3Fjg==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.2.tgz", + "integrity": "sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw==", "dependencies": { - "@emotion/memoize": "^0.8.0" + "@emotion/memoize": "^0.8.1" } }, "node_modules/@emotion/memoize": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz", - "integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==" + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", + "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==" }, "node_modules/@emotion/react": { - "version": "11.10.8", - "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.10.8.tgz", - "integrity": "sha512-ZfGfiABtJ1P1OXqOBsW08EgCDp5fK6C5I8hUJauc/VcJBGSzqAirMnFslhFWnZJ/w5HxPI36XbvMV0l4KZHl+w==", + "version": "11.11.4", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.11.4.tgz", + "integrity": "sha512-t8AjMlF0gHpvvxk5mAtCqR4vmxiGHCeJBaQO6gncUSdklELOgtwjerNY2yuJNfwnc6vi16U/+uMF+afIawJ9iw==", "dependencies": { "@babel/runtime": "^7.18.3", - "@emotion/babel-plugin": "^11.10.8", - "@emotion/cache": "^11.10.8", - "@emotion/serialize": "^1.1.1", - "@emotion/use-insertion-effect-with-fallbacks": "^1.0.0", - "@emotion/utils": "^1.2.0", - "@emotion/weak-memoize": "^0.3.0", + "@emotion/babel-plugin": "^11.11.0", + "@emotion/cache": "^11.11.0", + "@emotion/serialize": "^1.1.3", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", + "@emotion/utils": "^1.2.1", + "@emotion/weak-memoize": "^0.3.1", "hoist-non-react-statics": "^3.3.1" }, "peerDependencies": { @@ -213,33 +203,33 @@ } }, "node_modules/@emotion/serialize": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.1.tgz", - "integrity": "sha512-Zl/0LFggN7+L1liljxXdsVSVlg6E/Z/olVWpfxUTxOAmi8NU7YoeWeLfi1RmnB2TATHoaWwIBRoL+FvAJiTUQA==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.3.tgz", + "integrity": "sha512-iD4D6QVZFDhcbH0RAG1uVu1CwVLMWUkCvAqqlewO/rxf8+87yIBAlt4+AxMiiKPLs5hFc0owNk/sLLAOROw3cA==", "dependencies": { - "@emotion/hash": "^0.9.0", - "@emotion/memoize": "^0.8.0", - "@emotion/unitless": "^0.8.0", - "@emotion/utils": "^1.2.0", + "@emotion/hash": "^0.9.1", + "@emotion/memoize": "^0.8.1", + "@emotion/unitless": "^0.8.1", + "@emotion/utils": "^1.2.1", "csstype": "^3.0.2" } }, "node_modules/@emotion/sheet": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.1.tgz", - "integrity": "sha512-zxRBwl93sHMsOj4zs+OslQKg/uhF38MB+OMKoCrVuS0nyTkqnau+BM3WGEoOptg9Oz45T/aIGs1qbVAsEFo3nA==" + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.2.tgz", + "integrity": "sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==" }, "node_modules/@emotion/styled": { - "version": "11.10.8", - "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.10.8.tgz", - "integrity": "sha512-gow0lF4Uw/QEdX2REMhI8v6wLOabPKJ+4HKNF0xdJ2DJdznN6fxaXpQOx6sNkyBhSUL558Rmcu1Lq/MYlVo4vw==", + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.11.0.tgz", + "integrity": "sha512-hM5Nnvu9P3midq5aaXj4I+lnSfNi7Pmd4EWk1fOZ3pxookaQTNew6bp4JaCBYM4HVFZF9g7UjJmsUmC2JlxOng==", "dependencies": { "@babel/runtime": "^7.18.3", - "@emotion/babel-plugin": "^11.10.8", - "@emotion/is-prop-valid": "^1.2.0", - "@emotion/serialize": "^1.1.1", - "@emotion/use-insertion-effect-with-fallbacks": "^1.0.0", - "@emotion/utils": "^1.2.0" + "@emotion/babel-plugin": "^11.11.0", + "@emotion/is-prop-valid": "^1.2.1", + "@emotion/serialize": "^1.1.2", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", + "@emotion/utils": "^1.2.1" }, "peerDependencies": { "@emotion/react": "^11.0.0-rc.0", @@ -252,27 +242,27 @@ } }, "node_modules/@emotion/unitless": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.0.tgz", - "integrity": "sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw==" + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", + "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==" }, "node_modules/@emotion/use-insertion-effect-with-fallbacks": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.0.tgz", - "integrity": "sha512-1eEgUGmkaljiBnRMTdksDV1W4kUnmwgp7X9G8B++9GYwl1lUdqSndSriIrTJ0N7LQaoauY9JJ2yhiOYK5+NI4A==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz", + "integrity": "sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==", "peerDependencies": { "react": ">=16.8.0" } }, "node_modules/@emotion/utils": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.0.tgz", - "integrity": "sha512-sn3WH53Kzpw8oQ5mgMmIzzyAaH2ZqFEbozVVBSYp538E06OSE6ytOp7pRAjNQR+Q/orwqdQYJSe2m3hCOeznkw==" + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.1.tgz", + "integrity": "sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg==" }, "node_modules/@emotion/weak-memoize": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.0.tgz", - "integrity": "sha512-AHPmaAx+RYfZz0eYu6Gviiagpmiyw98ySSlQvCUhVGDRtDFe4DBS0x1bSjdF3gqUDYOczB+yYvBTtEylYSdRhg==" + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz", + "integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==" }, "node_modules/@esbuild/android-arm": { "version": "0.17.18", @@ -626,6 +616,40 @@ "node": ">=12" } }, + "node_modules/@floating-ui/core": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.0.tgz", + "integrity": "sha512-PcF++MykgmTj3CIyOQbKA/hDzOAiqI3mhuoN44WRCopIs1sgoDoU4oty4Jtqaj/y3oDU6fnVSm4QG0a3t5i0+g==", + "dependencies": { + "@floating-ui/utils": "^0.2.1" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.3.tgz", + "integrity": "sha512-RnDthu3mzPlQ31Ss/BTwQ1zjzIhr3lk1gZB1OC56h/1vEtaXkESrOqL5fQVMfXpwGtRwX+YsZBdyHtJMQnkArw==", + "dependencies": { + "@floating-ui/core": "^1.0.0", + "@floating-ui/utils": "^0.2.0" + } + }, + "node_modules/@floating-ui/react-dom": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.0.8.tgz", + "integrity": "sha512-HOdqOt3R3OGeTKidaLvJKcgg75S6tibQ3Tif4eyd91QnIJWr0NLvoXFpJA/j8HqkFSL68GDca9AuyWEHlhyClw==", + "dependencies": { + "@floating-ui/dom": "^1.6.1" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.1.tgz", + "integrity": "sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q==" + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", @@ -691,25 +715,24 @@ "dev": true }, "node_modules/@mui/base": { - "version": "5.0.0-alpha.127", - "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.127.tgz", - "integrity": "sha512-FoRQd0IOH9MnfyL5yXssyQRnC4vXI+1bwkU1idr+wNkP1ZfxE+JsThHcfl1dy5azLssVUGTtQFD9edQLdbyJog==", + "version": "5.0.0-beta.37", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.37.tgz", + "integrity": "sha512-/o3anbb+DeCng8jNsd3704XtmmLDZju1Fo8R2o7ugrVtPQ/QpcqddwKNzKPZwa0J5T8YNW3ZVuHyQgbTnQLisQ==", "dependencies": { - "@babel/runtime": "^7.21.0", - "@emotion/is-prop-valid": "^1.2.0", - "@mui/types": "^7.2.4", - "@mui/utils": "^5.12.0", - "@popperjs/core": "^2.11.7", - "clsx": "^1.2.1", - "prop-types": "^15.8.1", - "react-is": "^18.2.0" + "@babel/runtime": "^7.23.9", + "@floating-ui/react-dom": "^2.0.8", + "@mui/types": "^7.2.13", + "@mui/utils": "^5.15.11", + "@popperjs/core": "^2.11.8", + "clsx": "^2.1.0", + "prop-types": "^15.8.1" }, "engines": { "node": ">=12.0.0" }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/mui" + "url": "https://opencollective.com/mui-org" }, "peerDependencies": { "@types/react": "^17.0.0 || ^18.0.0", @@ -722,28 +745,36 @@ } } }, + "node_modules/@mui/base/node_modules/clsx": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.0.tgz", + "integrity": "sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==", + "engines": { + "node": ">=6" + } + }, "node_modules/@mui/core-downloads-tracker": { - "version": "5.12.2", - "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.12.2.tgz", - "integrity": "sha512-Qn7dy8tql6T0hY6gTFPkpWlnqVVFGu5Z6QzEzUSzzmLZpfAx4kf8sFz0PHiB7gU5yrqcZF9picMx1shpRY/rXw==", + "version": "5.15.11", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.15.11.tgz", + "integrity": "sha512-JVrJ9Jo4gyU707ujnRzmE8ABBWpXd6FwL9GYULmwZRtfPg89ggXs/S3MStQkpJ1JRWfdLL6S5syXmgQGq5EDAw==", "funding": { "type": "opencollective", - "url": "https://opencollective.com/mui" + "url": "https://opencollective.com/mui-org" } }, "node_modules/@mui/icons-material": { - "version": "5.11.16", - "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.11.16.tgz", - "integrity": "sha512-oKkx9z9Kwg40NtcIajF9uOXhxiyTZrrm9nmIJ4UjkU2IdHpd4QVLbCc/5hZN/y0C6qzi2Zlxyr9TGddQx2vx2A==", + "version": "5.15.11", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.15.11.tgz", + "integrity": "sha512-R5ZoQqnKpd+5Ew7mBygTFLxgYsQHPhgR3TDXSgIHYIjGzYuyPLmGLSdcPUoMdi6kxiYqHlpPj4NJxlbaFD0UHA==", "dependencies": { - "@babel/runtime": "^7.21.0" + "@babel/runtime": "^7.23.9" }, "engines": { "node": ">=12.0.0" }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/mui" + "url": "https://opencollective.com/mui-org" }, "peerDependencies": { "@mui/material": "^5.0.0", @@ -757,30 +788,29 @@ } }, "node_modules/@mui/lab": { - "version": "5.0.0-alpha.128", - "resolved": "https://registry.npmjs.org/@mui/lab/-/lab-5.0.0-alpha.128.tgz", - "integrity": "sha512-jsGP8bbAvnG+cBCveHhF49BHhVNojBvblWrNUuMkkLYS6T239Dela/+UvVnfIn/1hfUUNf/G/RiB42qC6ud7vQ==", + "version": "5.0.0-alpha.166", + "resolved": "https://registry.npmjs.org/@mui/lab/-/lab-5.0.0-alpha.166.tgz", + "integrity": "sha512-a+0yorrgxLIgfKhShVKQk0/5CnB4KBhMQ64SvEB+CsvKAKKJzjIU43m2nMqdBbWzfnEuj6wR9vQ9kambdn3ZKA==", "dependencies": { - "@babel/runtime": "^7.21.0", - "@mui/base": "5.0.0-alpha.127", - "@mui/system": "^5.12.1", - "@mui/types": "^7.2.4", - "@mui/utils": "^5.12.0", - "clsx": "^1.2.1", - "prop-types": "^15.8.1", - "react-is": "^18.2.0" + "@babel/runtime": "^7.23.9", + "@mui/base": "5.0.0-beta.37", + "@mui/system": "^5.15.11", + "@mui/types": "^7.2.13", + "@mui/utils": "^5.15.11", + "clsx": "^2.1.0", + "prop-types": "^15.8.1" }, "engines": { "node": ">=12.0.0" }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/mui" + "url": "https://opencollective.com/mui-org" }, "peerDependencies": { "@emotion/react": "^11.5.0", "@emotion/styled": "^11.3.0", - "@mui/material": "^5.0.0", + "@mui/material": ">=5.15.0", "@types/react": "^17.0.0 || ^18.0.0", "react": "^17.0.0 || ^18.0.0", "react-dom": "^17.0.0 || ^18.0.0" @@ -797,20 +827,28 @@ } } }, + "node_modules/@mui/lab/node_modules/clsx": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.0.tgz", + "integrity": "sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==", + "engines": { + "node": ">=6" + } + }, "node_modules/@mui/material": { - "version": "5.12.2", - "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.12.2.tgz", - "integrity": "sha512-XOVy6fVC0rI2dEwDq/1s4Te2hewTUe6lznzeVnruyATGkdmM06WnHqkZOoLVIWo9hWwAxpcgTDcAIVpFtt1nrw==", + "version": "5.15.11", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.15.11.tgz", + "integrity": "sha512-FA3eEuEZaDaxgN3CgfXezMWbCZ4VCeU/sv0F0/PK5n42qIgsPVD6q+j71qS7/62sp6wRFMHtDMpXRlN+tT/7NA==", "dependencies": { - "@babel/runtime": "^7.21.0", - "@mui/base": "5.0.0-alpha.127", - "@mui/core-downloads-tracker": "^5.12.2", - "@mui/system": "^5.12.1", - "@mui/types": "^7.2.4", - "@mui/utils": "^5.12.0", - "@types/react-transition-group": "^4.4.5", - "clsx": "^1.2.1", - "csstype": "^3.1.2", + "@babel/runtime": "^7.23.9", + "@mui/base": "5.0.0-beta.37", + "@mui/core-downloads-tracker": "^5.15.11", + "@mui/system": "^5.15.11", + "@mui/types": "^7.2.13", + "@mui/utils": "^5.15.11", + "@types/react-transition-group": "^4.4.10", + "clsx": "^2.1.0", + "csstype": "^3.1.3", "prop-types": "^15.8.1", "react-is": "^18.2.0", "react-transition-group": "^4.4.5" @@ -820,7 +858,7 @@ }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/mui" + "url": "https://opencollective.com/mui-org" }, "peerDependencies": { "@emotion/react": "^11.5.0", @@ -841,13 +879,21 @@ } } }, + "node_modules/@mui/material/node_modules/clsx": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.0.tgz", + "integrity": "sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==", + "engines": { + "node": ">=6" + } + }, "node_modules/@mui/private-theming": { - "version": "5.12.0", - "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.12.0.tgz", - "integrity": "sha512-w5dwMen1CUm1puAtubqxY9BIzrBxbOThsg2iWMvRJmWyJAPdf3Z583fPXpqeA2lhTW79uH2jajk5Ka4FuGlTPg==", + "version": "5.15.11", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.15.11.tgz", + "integrity": "sha512-jY/696SnSxSzO1u86Thym7ky5T9CgfidU3NFJjguldqK4f3Z5S97amZ6nffg8gTD0HBjY9scB+4ekqDEUmxZOA==", "dependencies": { - "@babel/runtime": "^7.21.0", - "@mui/utils": "^5.12.0", + "@babel/runtime": "^7.23.9", + "@mui/utils": "^5.15.11", "prop-types": "^15.8.1" }, "engines": { @@ -855,7 +901,7 @@ }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/mui" + "url": "https://opencollective.com/mui-org" }, "peerDependencies": { "@types/react": "^17.0.0 || ^18.0.0", @@ -868,13 +914,13 @@ } }, "node_modules/@mui/styled-engine": { - "version": "5.12.0", - "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.12.0.tgz", - "integrity": "sha512-frh8L7CRnvD0RDmIqEv6jFeKQUIXqW90BaZ6OrxJ2j4kIsiVLu29Gss4SbBvvrWwwatR72sBmC3w1aG4fjp9mQ==", + "version": "5.15.11", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.15.11.tgz", + "integrity": "sha512-So21AhAngqo07ces4S/JpX5UaMU2RHXpEA6hNzI6IQjd/1usMPxpgK8wkGgTe3JKmC2KDmH8cvoycq5H3Ii7/w==", "dependencies": { - "@babel/runtime": "^7.21.0", - "@emotion/cache": "^11.10.7", - "csstype": "^3.1.2", + "@babel/runtime": "^7.23.9", + "@emotion/cache": "^11.11.0", + "csstype": "^3.1.3", "prop-types": "^15.8.1" }, "engines": { @@ -882,7 +928,7 @@ }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/mui" + "url": "https://opencollective.com/mui-org" }, "peerDependencies": { "@emotion/react": "^11.4.1", @@ -899,17 +945,17 @@ } }, "node_modules/@mui/system": { - "version": "5.12.1", - "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.12.1.tgz", - "integrity": "sha512-Po+sicdV3bbRYXdU29XZaHPZrW7HUYUqU1qCu77GCCEMbahC756YpeyefdIYuPMUg0OdO3gKIUfDISBrkjJL+w==", + "version": "5.15.11", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.15.11.tgz", + "integrity": "sha512-9j35suLFq+MgJo5ktVSHPbkjDLRMBCV17NMBdEQurh6oWyGnLM4uhU4QGZZQ75o0vuhjJghOCA1jkO3+79wKsA==", "dependencies": { - "@babel/runtime": "^7.21.0", - "@mui/private-theming": "^5.12.0", - "@mui/styled-engine": "^5.12.0", - "@mui/types": "^7.2.4", - "@mui/utils": "^5.12.0", - "clsx": "^1.2.1", - "csstype": "^3.1.2", + "@babel/runtime": "^7.23.9", + "@mui/private-theming": "^5.15.11", + "@mui/styled-engine": "^5.15.11", + "@mui/types": "^7.2.13", + "@mui/utils": "^5.15.11", + "clsx": "^2.1.0", + "csstype": "^3.1.3", "prop-types": "^15.8.1" }, "engines": { @@ -917,7 +963,7 @@ }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/mui" + "url": "https://opencollective.com/mui-org" }, "peerDependencies": { "@emotion/react": "^11.5.0", @@ -937,12 +983,20 @@ } } }, + "node_modules/@mui/system/node_modules/clsx": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.0.tgz", + "integrity": "sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==", + "engines": { + "node": ">=6" + } + }, "node_modules/@mui/types": { - "version": "7.2.4", - "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.4.tgz", - "integrity": "sha512-LBcwa8rN84bKF+f5sDyku42w1NTxaPgPyYKODsh01U1fVstTClbUoSA96oyRBnSNyEiAVjKm6Gwx9vjR+xyqHA==", + "version": "7.2.13", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.13.tgz", + "integrity": "sha512-qP9OgacN62s+l8rdDhSFRe05HWtLLJ5TGclC9I1+tQngbssu0m2dmFZs+Px53AcOs9fD7TbYd4gc9AXzVqO/+g==", "peerDependencies": { - "@types/react": "*" + "@types/react": "^17.0.0 || ^18.0.0" }, "peerDependenciesMeta": { "@types/react": { @@ -951,13 +1005,12 @@ } }, "node_modules/@mui/utils": { - "version": "5.12.0", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.12.0.tgz", - "integrity": "sha512-RmQwgzF72p7Yr4+AAUO6j1v2uzt6wr7SWXn68KBsnfVpdOHyclCzH2lr/Xu6YOw9su4JRtdAIYfJFXsS6Cjkmw==", + "version": "5.15.11", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.15.11.tgz", + "integrity": "sha512-D6bwqprUa9Stf8ft0dcMqWyWDKEo7D+6pB1k8WajbqlYIRA8J8Kw9Ra7PSZKKePGBGWO+/xxrX1U8HpG/aXQCw==", "dependencies": { - "@babel/runtime": "^7.21.0", - "@types/prop-types": "^15.7.5", - "@types/react-is": "^16.7.1 || ^17.0.0", + "@babel/runtime": "^7.23.9", + "@types/prop-types": "^15.7.11", "prop-types": "^15.8.1", "react-is": "^18.2.0" }, @@ -966,16 +1019,22 @@ }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/mui" + "url": "https://opencollective.com/mui-org" }, "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, "node_modules/@popperjs/core": { - "version": "2.11.7", - "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.7.tgz", - "integrity": "sha512-Cr4OjIkipTtcXKjAsm8agyleBuDHvxzeBoa1v543lbv1YaIwQjESsVcmjiWiPEbC1FIeHOG/Op9kdCmAmiS3Kw==", + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", "funding": { "type": "opencollective", "url": "https://opencollective.com/popperjs" @@ -990,9 +1049,9 @@ } }, "node_modules/@sqlite.org/sqlite-wasm": { - "version": "3.41.2-build11", - "resolved": "https://registry.npmjs.org/@sqlite.org/sqlite-wasm/-/sqlite-wasm-3.41.2-build11.tgz", - "integrity": "sha512-NNBWCREak90Y6gKCgxFt3YUYFunmcdnKNCyPISBZKvpE09R3YF1PdJcJzgMqS9j66MtCY2TK3aeChNIYGaL2lw==", + "version": "3.45.1-build1", + "resolved": "https://registry.npmjs.org/@sqlite.org/sqlite-wasm/-/sqlite-wasm-3.45.1-build1.tgz", + "integrity": "sha512-1EgshFNhVeBtZ9KtQPm3PzzJ2CtpmXAq2DAPywy7WZ3gOK6p5n8TY+M+mBMpQCF5cLqrdNFb3Kp9uNie9rUAHw==", "bin": { "sqlite-wasm": "bin/index.js" } @@ -1042,9 +1101,9 @@ "dev": true }, "node_modules/@types/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==" + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", + "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==" }, "node_modules/@types/plotly.js": { "version": "2.12.18", @@ -1053,9 +1112,9 @@ "dev": true }, "node_modules/@types/prop-types": { - "version": "15.7.5", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", - "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==" + "version": "15.7.11", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz", + "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==" }, "node_modules/@types/react": { "version": "18.2.0", @@ -1076,24 +1135,6 @@ "@types/react": "*" } }, - "node_modules/@types/react-is": { - "version": "17.0.4", - "resolved": "https://registry.npmjs.org/@types/react-is/-/react-is-17.0.4.tgz", - "integrity": "sha512-FLzd0K9pnaEvKz4D1vYxK9JmgQPiGk1lu23o1kqGsLeT0iPbRSF7b76+S5T9fD8aRa0B8bY7I/3DebEj+1ysBA==", - "dependencies": { - "@types/react": "^17" - } - }, - "node_modules/@types/react-is/node_modules/@types/react": { - "version": "17.0.58", - "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.58.tgz", - "integrity": "sha512-c1GzVY97P0fGxwGxhYq989j4XwlcHQoto6wQISOC2v6wm3h0PORRWJFHlkRjfGsiG3y1609WdQ+J+tKxvrEd6A==", - "dependencies": { - "@types/prop-types": "*", - "@types/scheduler": "*", - "csstype": "^3.0.2" - } - }, "node_modules/@types/react-router": { "version": "5.1.20", "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.20.tgz", @@ -1116,9 +1157,9 @@ } }, "node_modules/@types/react-transition-group": { - "version": "4.4.5", - "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.5.tgz", - "integrity": "sha512-juKD/eiSM3/xZYzjuzH6ZwpP+/lejltmiS3QEzV/vmb/Q8+HfDmxu+Baga8UEMGBqV88Nbg4l2hY/K2DkyaLLA==", + "version": "4.4.10", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.10.tgz", + "integrity": "sha512-hT/+s0VQs2ojCX823m60m5f0sL5idt9SO6Tj6Dg+rdphGPIeJbJ6CxvBYkgkGKrYeDjvIpKTR38UzmtHJOGW3Q==", "dependencies": { "@types/react": "*" } @@ -1536,6 +1577,14 @@ "node": ">=4" } }, + "node_modules/chalk/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/chrome-trace-event": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", @@ -1700,9 +1749,9 @@ } }, "node_modules/csstype": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", - "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" }, "node_modules/dom-helpers": { "version": "5.2.1", @@ -1832,11 +1881,14 @@ } }, "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "engines": { - "node": ">=0.8.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/eslint-scope": { @@ -2234,6 +2286,18 @@ "loose-envify": "cli.js" } }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -2450,9 +2514,9 @@ } }, "node_modules/plotly.js-dist-min": { - "version": "2.22.0", - "resolved": "https://registry.npmjs.org/plotly.js-dist-min/-/plotly.js-dist-min-2.22.0.tgz", - "integrity": "sha512-2b7w4CQI06px8HVpKpgZtfuoDjuCLA26VlgdnG71UDBrJvtCYvXb39H4ElNv+CA1bbD4S98KanpWPRqTqlxBZw==" + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/plotly.js-dist-min/-/plotly.js-dist-min-2.29.1.tgz", + "integrity": "sha512-YvqX5TISWsJVTDIaUh2Qgt9uhLl0bWcQhO2rLPF0/hIY9BlinFa1JwSO2jFKcEmG0AJXSo4DnVdgKpsk9/8Apg==" }, "node_modules/prettier": { "version": "2.8.8", @@ -2607,9 +2671,9 @@ } }, "node_modules/regenerator-runtime": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" }, "node_modules/require-from-string": { "version": "2.0.2", @@ -2711,6 +2775,21 @@ "url": "https://opencollective.com/webpack" } }, + "node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/serialize-javascript": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", @@ -2787,9 +2866,9 @@ } }, "node_modules/stylis": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.1.4.tgz", - "integrity": "sha512-USf5pszRYwuE6hg9by0OkKChkQYEXfkeTtm0xKw+jqQhwyjCVLdYyMBK7R+n7dhzsblAWJnGxju4vxq5eH20GQ==" + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==" }, "node_modules/supports-color": { "version": "5.5.0", @@ -2971,33 +3050,6 @@ "node": ">=8" } }, - "node_modules/ts-loader/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/ts-loader/node_modules/semver": { - "version": "7.5.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz", - "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/ts-loader/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -3010,12 +3062,6 @@ "node": ">=8" } }, - "node_modules/ts-loader/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, "node_modules/typescript": { "version": "5.0.4", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz", @@ -3244,6 +3290,12 @@ "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", "dev": true }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "node_modules/yaml": { "version": "1.10.2", "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", @@ -3260,56 +3312,57 @@ }, "dependencies": { "@babel/code-frame": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.21.4.tgz", - "integrity": "sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", + "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", "requires": { - "@babel/highlight": "^7.18.6" + "@babel/highlight": "^7.23.4", + "chalk": "^2.4.2" } }, "@babel/helper-module-imports": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.21.4.tgz", - "integrity": "sha512-orajc5T2PsRYUN3ZryCEFeMDYwyw09c/pZeaQEZPH0MpKzSvn3e0uXsDBu3k03VI+9DBiRo+l22BfKTpKwa/Wg==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", + "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", "requires": { - "@babel/types": "^7.21.4" + "@babel/types": "^7.22.15" } }, "@babel/helper-string-parser": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", - "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==" + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", + "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==" }, "@babel/helper-validator-identifier": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", - "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==" + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==" }, "@babel/highlight": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", "requires": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", "js-tokens": "^4.0.0" } }, "@babel/runtime": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.5.tgz", - "integrity": "sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q==", + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.0.tgz", + "integrity": "sha512-Chk32uHMg6TnQdvw2e9IlqPpFX/6NLuK0Ys2PqLb7/gL5uFn9mXvK715FGLlOLQrcO4qIkNHkvPGktzzXexsFw==", "requires": { - "regenerator-runtime": "^0.13.11" + "regenerator-runtime": "^0.14.0" } }, "@babel/types": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.4.tgz", - "integrity": "sha512-rU2oY501qDxE8Pyo7i/Orqma4ziCOrby0/9mvbDUGEfvZjb279Nk9k19e2fiCxHbRRpY2ZyrgW1eq22mvmOIzA==", + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz", + "integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==", "requires": { - "@babel/helper-string-parser": "^7.19.4", - "@babel/helper-validator-identifier": "^7.19.1", + "@babel/helper-string-parser": "^7.23.4", + "@babel/helper-validator-identifier": "^7.22.20", "to-fast-properties": "^2.0.0" } }, @@ -3320,125 +3373,118 @@ "dev": true }, "@emotion/babel-plugin": { - "version": "11.10.8", - "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.10.8.tgz", - "integrity": "sha512-gxNky50AJL3AlkbjvTARiwAqei6/tNUxDZPSKd+3jqWVM3AmdVTTdpjHorR/an/M0VJqdsuq5oGcFH+rjtyujQ==", + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz", + "integrity": "sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==", "requires": { "@babel/helper-module-imports": "^7.16.7", "@babel/runtime": "^7.18.3", - "@emotion/hash": "^0.9.0", - "@emotion/memoize": "^0.8.0", - "@emotion/serialize": "^1.1.1", + "@emotion/hash": "^0.9.1", + "@emotion/memoize": "^0.8.1", + "@emotion/serialize": "^1.1.2", "babel-plugin-macros": "^3.1.0", "convert-source-map": "^1.5.0", "escape-string-regexp": "^4.0.0", "find-root": "^1.1.0", "source-map": "^0.5.7", - "stylis": "4.1.4" - }, - "dependencies": { - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" - } + "stylis": "4.2.0" } }, "@emotion/cache": { - "version": "11.10.8", - "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.10.8.tgz", - "integrity": "sha512-5fyqGHi51LU95o7qQ/vD1jyvC4uCY5GcBT+UgP4LHdpO9jPDlXqhrRr9/wCKmfoAvh5G/F7aOh4MwQa+8uEqhA==", + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.11.0.tgz", + "integrity": "sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==", "requires": { - "@emotion/memoize": "^0.8.0", - "@emotion/sheet": "^1.2.1", - "@emotion/utils": "^1.2.0", - "@emotion/weak-memoize": "^0.3.0", - "stylis": "4.1.4" + "@emotion/memoize": "^0.8.1", + "@emotion/sheet": "^1.2.2", + "@emotion/utils": "^1.2.1", + "@emotion/weak-memoize": "^0.3.1", + "stylis": "4.2.0" } }, "@emotion/hash": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.0.tgz", - "integrity": "sha512-14FtKiHhy2QoPIzdTcvh//8OyBlknNs2nXRwIhG904opCby3l+9Xaf/wuPvICBF0rc1ZCNBd3nKe9cd2mecVkQ==" + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.1.tgz", + "integrity": "sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==" }, "@emotion/is-prop-valid": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.0.tgz", - "integrity": "sha512-3aDpDprjM0AwaxGE09bOPkNxHpBd+kA6jty3RnaEXdweX1DF1U3VQpPYb0g1IStAuK7SVQ1cy+bNBBKp4W3Fjg==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.2.tgz", + "integrity": "sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw==", "requires": { - "@emotion/memoize": "^0.8.0" + "@emotion/memoize": "^0.8.1" } }, "@emotion/memoize": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz", - "integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==" + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", + "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==" }, "@emotion/react": { - "version": "11.10.8", - "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.10.8.tgz", - "integrity": "sha512-ZfGfiABtJ1P1OXqOBsW08EgCDp5fK6C5I8hUJauc/VcJBGSzqAirMnFslhFWnZJ/w5HxPI36XbvMV0l4KZHl+w==", + "version": "11.11.4", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.11.4.tgz", + "integrity": "sha512-t8AjMlF0gHpvvxk5mAtCqR4vmxiGHCeJBaQO6gncUSdklELOgtwjerNY2yuJNfwnc6vi16U/+uMF+afIawJ9iw==", "requires": { "@babel/runtime": "^7.18.3", - "@emotion/babel-plugin": "^11.10.8", - "@emotion/cache": "^11.10.8", - "@emotion/serialize": "^1.1.1", - "@emotion/use-insertion-effect-with-fallbacks": "^1.0.0", - "@emotion/utils": "^1.2.0", - "@emotion/weak-memoize": "^0.3.0", + "@emotion/babel-plugin": "^11.11.0", + "@emotion/cache": "^11.11.0", + "@emotion/serialize": "^1.1.3", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", + "@emotion/utils": "^1.2.1", + "@emotion/weak-memoize": "^0.3.1", "hoist-non-react-statics": "^3.3.1" } }, "@emotion/serialize": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.1.tgz", - "integrity": "sha512-Zl/0LFggN7+L1liljxXdsVSVlg6E/Z/olVWpfxUTxOAmi8NU7YoeWeLfi1RmnB2TATHoaWwIBRoL+FvAJiTUQA==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.3.tgz", + "integrity": "sha512-iD4D6QVZFDhcbH0RAG1uVu1CwVLMWUkCvAqqlewO/rxf8+87yIBAlt4+AxMiiKPLs5hFc0owNk/sLLAOROw3cA==", "requires": { - "@emotion/hash": "^0.9.0", - "@emotion/memoize": "^0.8.0", - "@emotion/unitless": "^0.8.0", - "@emotion/utils": "^1.2.0", + "@emotion/hash": "^0.9.1", + "@emotion/memoize": "^0.8.1", + "@emotion/unitless": "^0.8.1", + "@emotion/utils": "^1.2.1", "csstype": "^3.0.2" } }, "@emotion/sheet": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.1.tgz", - "integrity": "sha512-zxRBwl93sHMsOj4zs+OslQKg/uhF38MB+OMKoCrVuS0nyTkqnau+BM3WGEoOptg9Oz45T/aIGs1qbVAsEFo3nA==" + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.2.tgz", + "integrity": "sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==" }, "@emotion/styled": { - "version": "11.10.8", - "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.10.8.tgz", - "integrity": "sha512-gow0lF4Uw/QEdX2REMhI8v6wLOabPKJ+4HKNF0xdJ2DJdznN6fxaXpQOx6sNkyBhSUL558Rmcu1Lq/MYlVo4vw==", + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.11.0.tgz", + "integrity": "sha512-hM5Nnvu9P3midq5aaXj4I+lnSfNi7Pmd4EWk1fOZ3pxookaQTNew6bp4JaCBYM4HVFZF9g7UjJmsUmC2JlxOng==", "requires": { "@babel/runtime": "^7.18.3", - "@emotion/babel-plugin": "^11.10.8", - "@emotion/is-prop-valid": "^1.2.0", - "@emotion/serialize": "^1.1.1", - "@emotion/use-insertion-effect-with-fallbacks": "^1.0.0", - "@emotion/utils": "^1.2.0" + "@emotion/babel-plugin": "^11.11.0", + "@emotion/is-prop-valid": "^1.2.1", + "@emotion/serialize": "^1.1.2", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.1", + "@emotion/utils": "^1.2.1" } }, "@emotion/unitless": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.0.tgz", - "integrity": "sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw==" + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", + "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==" }, "@emotion/use-insertion-effect-with-fallbacks": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.0.tgz", - "integrity": "sha512-1eEgUGmkaljiBnRMTdksDV1W4kUnmwgp7X9G8B++9GYwl1lUdqSndSriIrTJ0N7LQaoauY9JJ2yhiOYK5+NI4A==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz", + "integrity": "sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==", "requires": {} }, "@emotion/utils": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.0.tgz", - "integrity": "sha512-sn3WH53Kzpw8oQ5mgMmIzzyAaH2ZqFEbozVVBSYp538E06OSE6ytOp7pRAjNQR+Q/orwqdQYJSe2m3hCOeznkw==" + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.1.tgz", + "integrity": "sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg==" }, "@emotion/weak-memoize": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.0.tgz", - "integrity": "sha512-AHPmaAx+RYfZz0eYu6Gviiagpmiyw98ySSlQvCUhVGDRtDFe4DBS0x1bSjdF3gqUDYOczB+yYvBTtEylYSdRhg==" + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz", + "integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==" }, "@esbuild/android-arm": { "version": "0.17.18", @@ -3594,6 +3640,36 @@ "dev": true, "optional": true }, + "@floating-ui/core": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.0.tgz", + "integrity": "sha512-PcF++MykgmTj3CIyOQbKA/hDzOAiqI3mhuoN44WRCopIs1sgoDoU4oty4Jtqaj/y3oDU6fnVSm4QG0a3t5i0+g==", + "requires": { + "@floating-ui/utils": "^0.2.1" + } + }, + "@floating-ui/dom": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.3.tgz", + "integrity": "sha512-RnDthu3mzPlQ31Ss/BTwQ1zjzIhr3lk1gZB1OC56h/1vEtaXkESrOqL5fQVMfXpwGtRwX+YsZBdyHtJMQnkArw==", + "requires": { + "@floating-ui/core": "^1.0.0", + "@floating-ui/utils": "^0.2.0" + } + }, + "@floating-ui/react-dom": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.0.8.tgz", + "integrity": "sha512-HOdqOt3R3OGeTKidaLvJKcgg75S6tibQ3Tif4eyd91QnIJWr0NLvoXFpJA/j8HqkFSL68GDca9AuyWEHlhyClw==", + "requires": { + "@floating-ui/dom": "^1.6.1" + } + }, + "@floating-ui/utils": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.1.tgz", + "integrity": "sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q==" + }, "@jridgewell/gen-mapping": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", @@ -3652,125 +3728,150 @@ } }, "@mui/base": { - "version": "5.0.0-alpha.127", - "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.127.tgz", - "integrity": "sha512-FoRQd0IOH9MnfyL5yXssyQRnC4vXI+1bwkU1idr+wNkP1ZfxE+JsThHcfl1dy5azLssVUGTtQFD9edQLdbyJog==", + "version": "5.0.0-beta.37", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.37.tgz", + "integrity": "sha512-/o3anbb+DeCng8jNsd3704XtmmLDZju1Fo8R2o7ugrVtPQ/QpcqddwKNzKPZwa0J5T8YNW3ZVuHyQgbTnQLisQ==", "requires": { - "@babel/runtime": "^7.21.0", - "@emotion/is-prop-valid": "^1.2.0", - "@mui/types": "^7.2.4", - "@mui/utils": "^5.12.0", - "@popperjs/core": "^2.11.7", - "clsx": "^1.2.1", - "prop-types": "^15.8.1", - "react-is": "^18.2.0" + "@babel/runtime": "^7.23.9", + "@floating-ui/react-dom": "^2.0.8", + "@mui/types": "^7.2.13", + "@mui/utils": "^5.15.11", + "@popperjs/core": "^2.11.8", + "clsx": "^2.1.0", + "prop-types": "^15.8.1" + }, + "dependencies": { + "clsx": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.0.tgz", + "integrity": "sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==" + } } }, "@mui/core-downloads-tracker": { - "version": "5.12.2", - "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.12.2.tgz", - "integrity": "sha512-Qn7dy8tql6T0hY6gTFPkpWlnqVVFGu5Z6QzEzUSzzmLZpfAx4kf8sFz0PHiB7gU5yrqcZF9picMx1shpRY/rXw==" + "version": "5.15.11", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.15.11.tgz", + "integrity": "sha512-JVrJ9Jo4gyU707ujnRzmE8ABBWpXd6FwL9GYULmwZRtfPg89ggXs/S3MStQkpJ1JRWfdLL6S5syXmgQGq5EDAw==" }, "@mui/icons-material": { - "version": "5.11.16", - "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.11.16.tgz", - "integrity": "sha512-oKkx9z9Kwg40NtcIajF9uOXhxiyTZrrm9nmIJ4UjkU2IdHpd4QVLbCc/5hZN/y0C6qzi2Zlxyr9TGddQx2vx2A==", + "version": "5.15.11", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.15.11.tgz", + "integrity": "sha512-R5ZoQqnKpd+5Ew7mBygTFLxgYsQHPhgR3TDXSgIHYIjGzYuyPLmGLSdcPUoMdi6kxiYqHlpPj4NJxlbaFD0UHA==", "requires": { - "@babel/runtime": "^7.21.0" + "@babel/runtime": "^7.23.9" } }, "@mui/lab": { - "version": "5.0.0-alpha.128", - "resolved": "https://registry.npmjs.org/@mui/lab/-/lab-5.0.0-alpha.128.tgz", - "integrity": "sha512-jsGP8bbAvnG+cBCveHhF49BHhVNojBvblWrNUuMkkLYS6T239Dela/+UvVnfIn/1hfUUNf/G/RiB42qC6ud7vQ==", + "version": "5.0.0-alpha.166", + "resolved": "https://registry.npmjs.org/@mui/lab/-/lab-5.0.0-alpha.166.tgz", + "integrity": "sha512-a+0yorrgxLIgfKhShVKQk0/5CnB4KBhMQ64SvEB+CsvKAKKJzjIU43m2nMqdBbWzfnEuj6wR9vQ9kambdn3ZKA==", "requires": { - "@babel/runtime": "^7.21.0", - "@mui/base": "5.0.0-alpha.127", - "@mui/system": "^5.12.1", - "@mui/types": "^7.2.4", - "@mui/utils": "^5.12.0", - "clsx": "^1.2.1", - "prop-types": "^15.8.1", - "react-is": "^18.2.0" + "@babel/runtime": "^7.23.9", + "@mui/base": "5.0.0-beta.37", + "@mui/system": "^5.15.11", + "@mui/types": "^7.2.13", + "@mui/utils": "^5.15.11", + "clsx": "^2.1.0", + "prop-types": "^15.8.1" + }, + "dependencies": { + "clsx": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.0.tgz", + "integrity": "sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==" + } } }, "@mui/material": { - "version": "5.12.2", - "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.12.2.tgz", - "integrity": "sha512-XOVy6fVC0rI2dEwDq/1s4Te2hewTUe6lznzeVnruyATGkdmM06WnHqkZOoLVIWo9hWwAxpcgTDcAIVpFtt1nrw==", + "version": "5.15.11", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.15.11.tgz", + "integrity": "sha512-FA3eEuEZaDaxgN3CgfXezMWbCZ4VCeU/sv0F0/PK5n42qIgsPVD6q+j71qS7/62sp6wRFMHtDMpXRlN+tT/7NA==", "requires": { - "@babel/runtime": "^7.21.0", - "@mui/base": "5.0.0-alpha.127", - "@mui/core-downloads-tracker": "^5.12.2", - "@mui/system": "^5.12.1", - "@mui/types": "^7.2.4", - "@mui/utils": "^5.12.0", - "@types/react-transition-group": "^4.4.5", - "clsx": "^1.2.1", - "csstype": "^3.1.2", + "@babel/runtime": "^7.23.9", + "@mui/base": "5.0.0-beta.37", + "@mui/core-downloads-tracker": "^5.15.11", + "@mui/system": "^5.15.11", + "@mui/types": "^7.2.13", + "@mui/utils": "^5.15.11", + "@types/react-transition-group": "^4.4.10", + "clsx": "^2.1.0", + "csstype": "^3.1.3", "prop-types": "^15.8.1", "react-is": "^18.2.0", "react-transition-group": "^4.4.5" + }, + "dependencies": { + "clsx": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.0.tgz", + "integrity": "sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==" + } } }, "@mui/private-theming": { - "version": "5.12.0", - "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.12.0.tgz", - "integrity": "sha512-w5dwMen1CUm1puAtubqxY9BIzrBxbOThsg2iWMvRJmWyJAPdf3Z583fPXpqeA2lhTW79uH2jajk5Ka4FuGlTPg==", + "version": "5.15.11", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.15.11.tgz", + "integrity": "sha512-jY/696SnSxSzO1u86Thym7ky5T9CgfidU3NFJjguldqK4f3Z5S97amZ6nffg8gTD0HBjY9scB+4ekqDEUmxZOA==", "requires": { - "@babel/runtime": "^7.21.0", - "@mui/utils": "^5.12.0", + "@babel/runtime": "^7.23.9", + "@mui/utils": "^5.15.11", "prop-types": "^15.8.1" } }, "@mui/styled-engine": { - "version": "5.12.0", - "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.12.0.tgz", - "integrity": "sha512-frh8L7CRnvD0RDmIqEv6jFeKQUIXqW90BaZ6OrxJ2j4kIsiVLu29Gss4SbBvvrWwwatR72sBmC3w1aG4fjp9mQ==", + "version": "5.15.11", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.15.11.tgz", + "integrity": "sha512-So21AhAngqo07ces4S/JpX5UaMU2RHXpEA6hNzI6IQjd/1usMPxpgK8wkGgTe3JKmC2KDmH8cvoycq5H3Ii7/w==", "requires": { - "@babel/runtime": "^7.21.0", - "@emotion/cache": "^11.10.7", - "csstype": "^3.1.2", + "@babel/runtime": "^7.23.9", + "@emotion/cache": "^11.11.0", + "csstype": "^3.1.3", "prop-types": "^15.8.1" } }, "@mui/system": { - "version": "5.12.1", - "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.12.1.tgz", - "integrity": "sha512-Po+sicdV3bbRYXdU29XZaHPZrW7HUYUqU1qCu77GCCEMbahC756YpeyefdIYuPMUg0OdO3gKIUfDISBrkjJL+w==", + "version": "5.15.11", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.15.11.tgz", + "integrity": "sha512-9j35suLFq+MgJo5ktVSHPbkjDLRMBCV17NMBdEQurh6oWyGnLM4uhU4QGZZQ75o0vuhjJghOCA1jkO3+79wKsA==", "requires": { - "@babel/runtime": "^7.21.0", - "@mui/private-theming": "^5.12.0", - "@mui/styled-engine": "^5.12.0", - "@mui/types": "^7.2.4", - "@mui/utils": "^5.12.0", - "clsx": "^1.2.1", - "csstype": "^3.1.2", + "@babel/runtime": "^7.23.9", + "@mui/private-theming": "^5.15.11", + "@mui/styled-engine": "^5.15.11", + "@mui/types": "^7.2.13", + "@mui/utils": "^5.15.11", + "clsx": "^2.1.0", + "csstype": "^3.1.3", "prop-types": "^15.8.1" + }, + "dependencies": { + "clsx": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.0.tgz", + "integrity": "sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==" + } } }, "@mui/types": { - "version": "7.2.4", - "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.4.tgz", - "integrity": "sha512-LBcwa8rN84bKF+f5sDyku42w1NTxaPgPyYKODsh01U1fVstTClbUoSA96oyRBnSNyEiAVjKm6Gwx9vjR+xyqHA==", + "version": "7.2.13", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.13.tgz", + "integrity": "sha512-qP9OgacN62s+l8rdDhSFRe05HWtLLJ5TGclC9I1+tQngbssu0m2dmFZs+Px53AcOs9fD7TbYd4gc9AXzVqO/+g==", "requires": {} }, "@mui/utils": { - "version": "5.12.0", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.12.0.tgz", - "integrity": "sha512-RmQwgzF72p7Yr4+AAUO6j1v2uzt6wr7SWXn68KBsnfVpdOHyclCzH2lr/Xu6YOw9su4JRtdAIYfJFXsS6Cjkmw==", + "version": "5.15.11", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.15.11.tgz", + "integrity": "sha512-D6bwqprUa9Stf8ft0dcMqWyWDKEo7D+6pB1k8WajbqlYIRA8J8Kw9Ra7PSZKKePGBGWO+/xxrX1U8HpG/aXQCw==", "requires": { - "@babel/runtime": "^7.21.0", - "@types/prop-types": "^15.7.5", - "@types/react-is": "^16.7.1 || ^17.0.0", + "@babel/runtime": "^7.23.9", + "@types/prop-types": "^15.7.11", "prop-types": "^15.8.1", "react-is": "^18.2.0" } }, "@popperjs/core": { - "version": "2.11.7", - "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.7.tgz", - "integrity": "sha512-Cr4OjIkipTtcXKjAsm8agyleBuDHvxzeBoa1v543lbv1YaIwQjESsVcmjiWiPEbC1FIeHOG/Op9kdCmAmiS3Kw==" + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==" }, "@remix-run/router": { "version": "1.6.0", @@ -3778,9 +3879,9 @@ "integrity": "sha512-N13NRw3T2+6Xi9J//3CGLsK2OqC8NMme3d/YX+nh05K9YHWGcv8DycHJrqGScSP4T75o8IN6nqIMhVFU8ohg8w==" }, "@sqlite.org/sqlite-wasm": { - "version": "3.41.2-build11", - "resolved": "https://registry.npmjs.org/@sqlite.org/sqlite-wasm/-/sqlite-wasm-3.41.2-build11.tgz", - "integrity": "sha512-NNBWCREak90Y6gKCgxFt3YUYFunmcdnKNCyPISBZKvpE09R3YF1PdJcJzgMqS9j66MtCY2TK3aeChNIYGaL2lw==" + "version": "3.45.1-build1", + "resolved": "https://registry.npmjs.org/@sqlite.org/sqlite-wasm/-/sqlite-wasm-3.45.1-build1.tgz", + "integrity": "sha512-1EgshFNhVeBtZ9KtQPm3PzzJ2CtpmXAq2DAPywy7WZ3gOK6p5n8TY+M+mBMpQCF5cLqrdNFb3Kp9uNie9rUAHw==" }, "@types/eslint": { "version": "8.37.0", @@ -3827,9 +3928,9 @@ "dev": true }, "@types/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==" + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", + "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==" }, "@types/plotly.js": { "version": "2.12.18", @@ -3838,9 +3939,9 @@ "dev": true }, "@types/prop-types": { - "version": "15.7.5", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", - "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==" + "version": "15.7.11", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz", + "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==" }, "@types/react": { "version": "18.2.0", @@ -3861,26 +3962,6 @@ "@types/react": "*" } }, - "@types/react-is": { - "version": "17.0.4", - "resolved": "https://registry.npmjs.org/@types/react-is/-/react-is-17.0.4.tgz", - "integrity": "sha512-FLzd0K9pnaEvKz4D1vYxK9JmgQPiGk1lu23o1kqGsLeT0iPbRSF7b76+S5T9fD8aRa0B8bY7I/3DebEj+1ysBA==", - "requires": { - "@types/react": "^17" - }, - "dependencies": { - "@types/react": { - "version": "17.0.58", - "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.58.tgz", - "integrity": "sha512-c1GzVY97P0fGxwGxhYq989j4XwlcHQoto6wQISOC2v6wm3h0PORRWJFHlkRjfGsiG3y1609WdQ+J+tKxvrEd6A==", - "requires": { - "@types/prop-types": "*", - "@types/scheduler": "*", - "csstype": "^3.0.2" - } - } - } - }, "@types/react-router": { "version": "5.1.20", "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.20.tgz", @@ -3903,9 +3984,9 @@ } }, "@types/react-transition-group": { - "version": "4.4.5", - "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.5.tgz", - "integrity": "sha512-juKD/eiSM3/xZYzjuzH6ZwpP+/lejltmiS3QEzV/vmb/Q8+HfDmxu+Baga8UEMGBqV88Nbg4l2hY/K2DkyaLLA==", + "version": "4.4.10", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.10.tgz", + "integrity": "sha512-hT/+s0VQs2ojCX823m60m5f0sL5idt9SO6Tj6Dg+rdphGPIeJbJ6CxvBYkgkGKrYeDjvIpKTR38UzmtHJOGW3Q==", "requires": { "@types/react": "*" } @@ -4225,6 +4306,13 @@ "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" + }, + "dependencies": { + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" + } } }, "chrome-trace-event": { @@ -4354,9 +4442,9 @@ } }, "csstype": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", - "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" }, "dom-helpers": { "version": "5.2.1", @@ -4458,9 +4546,9 @@ "dev": true }, "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" }, "eslint-scope": { "version": "5.1.1", @@ -4765,6 +4853,15 @@ "js-tokens": "^3.0.0 || ^4.0.0" } }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, "merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -4917,9 +5014,9 @@ } }, "plotly.js-dist-min": { - "version": "2.22.0", - "resolved": "https://registry.npmjs.org/plotly.js-dist-min/-/plotly.js-dist-min-2.22.0.tgz", - "integrity": "sha512-2b7w4CQI06px8HVpKpgZtfuoDjuCLA26VlgdnG71UDBrJvtCYvXb39H4ElNv+CA1bbD4S98KanpWPRqTqlxBZw==" + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/plotly.js-dist-min/-/plotly.js-dist-min-2.29.1.tgz", + "integrity": "sha512-YvqX5TISWsJVTDIaUh2Qgt9uhLl0bWcQhO2rLPF0/hIY9BlinFa1JwSO2jFKcEmG0AJXSo4DnVdgKpsk9/8Apg==" }, "prettier": { "version": "2.8.8", @@ -5027,9 +5124,9 @@ } }, "regenerator-runtime": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" }, "require-from-string": { "version": "2.0.2", @@ -5094,6 +5191,15 @@ "ajv-keywords": "^3.5.2" } }, + "semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, "serialize-javascript": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", @@ -5157,9 +5263,9 @@ } }, "stylis": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.1.4.tgz", - "integrity": "sha512-USf5pszRYwuE6hg9by0OkKChkQYEXfkeTtm0xKw+jqQhwyjCVLdYyMBK7R+n7dhzsblAWJnGxju4vxq5eH20GQ==" + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==" }, "supports-color": { "version": "5.5.0", @@ -5271,24 +5377,6 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "semver": { - "version": "7.5.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz", - "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -5297,12 +5385,6 @@ "requires": { "has-flag": "^4.0.0" } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true } } }, @@ -5453,6 +5535,12 @@ "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", "dev": true }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "yaml": { "version": "1.10.2", "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", diff --git a/standalone_app/package.json b/standalone_app/package.json index 05b5390f..fb890c21 100644 --- a/standalone_app/package.json +++ b/standalone_app/package.json @@ -23,16 +23,16 @@ "webpack-cli": "^5.1.1" }, "dependencies": { - "@emotion/react": "^11.10.8", - "@emotion/styled": "^11.10.8", - "@mui/icons-material": "^5.11.16", - "@mui/lab": "^5.0.0-alpha.128", - "@mui/material": "^5.12.2", - "@sqlite.org/sqlite-wasm": "^3.41.2-build11", + "@emotion/react": "^11.11.3", + "@emotion/styled": "^11.11.0", + "@mui/icons-material": "^5.15.6", + "@mui/lab": "^5.0.0-alpha.162", + "@mui/material": "^5.15.6", + "@sqlite.org/sqlite-wasm": "^3.45.1-build1", "module-workers-polyfill": "^0.3.2", "notistack": "^3.0.1", "optuna": "../rustlib/pkg", - "plotly.js-dist-min": "^2.22.0", + "plotly.js-dist-min": "^2.28.0", "react": "^18.2.0", "react-dom": "^18.2.0", "react-router-dom": "^6.11.0", From 149d497e1e88047821d1c16710803986731c416e Mon Sep 17 00:00:00 2001 From: c-bata Date: Mon, 4 Mar 2024 18:41:24 +0900 Subject: [PATCH 56/98] Use useDeferredValue in standalone app --- standalone_app/src/components/Debounce.tsx | 28 ----------- standalone_app/src/components/StudyList.tsx | 52 ++++++++++----------- 2 files changed, 26 insertions(+), 54 deletions(-) delete mode 100644 standalone_app/src/components/Debounce.tsx diff --git a/standalone_app/src/components/Debounce.tsx b/standalone_app/src/components/Debounce.tsx deleted file mode 100644 index 31e34739..00000000 --- a/standalone_app/src/components/Debounce.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import React, { FC, useEffect } from "react" -import { TextField, TextFieldProps } from "@mui/material" - -export const DebouncedInputTextField: FC<{ - onChange: (s: string, valid: boolean) => void - delay: number - textFieldProps: TextFieldProps -}> = ({ onChange, delay, textFieldProps }) => { - const [text, setText] = React.useState("") - const [valid, setValidity] = React.useState(true) - useEffect(() => { - const timer = setTimeout(() => { - onChange(text, valid) - }, delay) - return () => { - clearTimeout(timer) - } - }, [text, delay]) - return ( - { - setText(e.target.value) - setValidity(e.target.validity.valid) - }} - {...textFieldProps} - /> - ) -} diff --git a/standalone_app/src/components/StudyList.tsx b/standalone_app/src/components/StudyList.tsx index 4fdd4537..dcad8f27 100644 --- a/standalone_app/src/components/StudyList.tsx +++ b/standalone_app/src/components/StudyList.tsx @@ -1,4 +1,4 @@ -import React, { FC, useState } from "react" +import React, { FC, useState, useMemo, useDeferredValue } from "react" import { AppBar, Typography, @@ -22,7 +22,6 @@ import Brightness7Icon from "@mui/icons-material/Brightness7" import { useRecoilValue } from "recoil" import { studiesState } from "../state" import { Link } from "react-router-dom" -import { DebouncedInputTextField } from "./Debounce" import { Search } from "@mui/icons-material" import { StorageLoader } from "./StorageLoader" @@ -32,8 +31,9 @@ export const StudyList: FC<{ const theme = useTheme() const studies = useRecoilValue(studiesState) - const [studyFilterText, setStudyFilterText] = useState("") + const [_studyFilterText, setStudyFilterText] = useState("") const [sortBy, setSortBy] = useState<"id-asc" | "id-desc">("id-asc") + const studyFilterText = useDeferredValue(_studyFilterText) const studyFilter = (row: Study): boolean => { const keywords = studyFilterText.split(" ") return !keywords.every((k) => { @@ -43,10 +43,13 @@ export const StudyList: FC<{ return row.study_name.indexOf(k) >= 0 }) } - let filteredStudies: Study[] = studies.filter((s) => !studyFilter(s)) - if (sortBy === "id-desc") { - filteredStudies = filteredStudies.reverse() - } + const filteredStudies = useMemo(() => { + let filteredStudies: Study[] = studies.filter((s) => !studyFilter(s)) + if (sortBy === "id-desc") { + filteredStudies = filteredStudies.reverse() + } + return filteredStudies + }, [studyFilterText, studies, sortBy]) const Select = styled(TextField)(({ theme }) => ({ "& .MuiInputBase-input": { @@ -131,26 +134,23 @@ export const StudyList: FC<{ - { - setStudyFilterText(s) + { + setStudyFilterText(e.target.value) }} - delay={500} - textFieldProps={{ - fullWidth: true, - id: "search-study", - variant: "outlined", - placeholder: "Search study", - sx: { maxWidth: 500 }, - InputProps: { - startAdornment: ( - - - - - - ), - }, + id="search-study" + variant="outlined" + placeholder="Search study" + fullWidth + sx={{ maxWidth: 500 }} + InputProps={{ + startAdornment: ( + + + + + + ), }} /> {sortBySelect} From 7708a1fd12e903efc149c08a980a4ca9bc570b67 Mon Sep 17 00:00:00 2001 From: c-bata Date: Mon, 4 Mar 2024 18:51:09 +0900 Subject: [PATCH 57/98] Use useDeferredValue instead of Debounce.tsx --- optuna_dashboard/ts/components/Debounce.tsx | 1 + optuna_dashboard/ts/components/StudyList.tsx | 59 +++++++++++--------- 2 files changed, 33 insertions(+), 27 deletions(-) diff --git a/optuna_dashboard/ts/components/Debounce.tsx b/optuna_dashboard/ts/components/Debounce.tsx index 31e34739..c8ee1751 100644 --- a/optuna_dashboard/ts/components/Debounce.tsx +++ b/optuna_dashboard/ts/components/Debounce.tsx @@ -1,6 +1,7 @@ import React, { FC, useEffect } from "react" import { TextField, TextFieldProps } from "@mui/material" +// TODO(c-bata): Remove this and use `useDeferredValue` instead. export const DebouncedInputTextField: FC<{ onChange: (s: string, valid: boolean) => void delay: number diff --git a/optuna_dashboard/ts/components/StudyList.tsx b/optuna_dashboard/ts/components/StudyList.tsx index 6c662519..49d5c191 100644 --- a/optuna_dashboard/ts/components/StudyList.tsx +++ b/optuna_dashboard/ts/components/StudyList.tsx @@ -1,4 +1,10 @@ -import React, { FC, useEffect, useState } from "react" +import React, { + FC, + useEffect, + useState, + useDeferredValue, + useMemo, +} from "react" import { useNavigate } from "react-router-dom" import { useRecoilValue } from "recoil" import { Link } from "react-router-dom" @@ -26,7 +32,6 @@ import CompareIcon from "@mui/icons-material/Compare" import DriveFileRenameOutlineIcon from "@mui/icons-material/DriveFileRenameOutline" import { actionCreator } from "../action" -import { DebouncedInputTextField } from "./Debounce" import { studySummariesLoadingState, studySummariesState } from "../state" import { styled } from "@mui/system" import { AppDrawer } from "./AppDrawer" @@ -41,7 +46,8 @@ export const StudyList: FC<{ const theme = useTheme() const action = actionCreator() - const [studyFilterText, setStudyFilterText] = React.useState("") + const [_studyFilterText, setStudyFilterText] = React.useState("") + const studyFilterText = useDeferredValue(_studyFilterText) const studyFilter = (row: StudySummary) => { const keywords = studyFilterText.split(" ") return !keywords.every((k) => { @@ -64,12 +70,14 @@ export const StudyList: FC<{ const query = useQuery() const initialSortBy = query.get("studies_order_by") === "asc" ? "asc" : "desc" const [sortBy, setSortBy] = useState<"asc" | "desc">(initialSortBy) + const filteredStudies = useMemo(() => { + let filteredStudies: StudySummary[] = studies.filter((s) => !studyFilter(s)) + if (sortBy === "desc") { + filteredStudies = filteredStudies.reverse() + } + return filteredStudies + }, [studyFilterText, studies, sortBy]) - let filteredStudies = studies.filter((s) => !studyFilter(s)) - - if (sortBy === "desc") { - filteredStudies = filteredStudies.reverse() - } useEffect(() => { action.updateStudySummaries() }, []) @@ -201,26 +209,23 @@ export const StudyList: FC<{ - { - setStudyFilterText(s) + { + setStudyFilterText(e.target.value) }} - delay={500} - textFieldProps={{ - fullWidth: true, - id: "search-study", - variant: "outlined", - placeholder: "Search study", - sx: { maxWidth: 500 }, - InputProps: { - startAdornment: ( - - - - - - ), - }, + id="search-study" + variant="outlined" + placeholder="Search study" + fullWidth + sx={{ maxWidth: 500 }} + InputProps={{ + startAdornment: ( + + + + + + ), }} /> {sortBySelect} From dbec8c69ff49c9d56d8db103323fd09ff144cab7 Mon Sep 17 00:00:00 2001 From: c-bata Date: Tue, 5 Mar 2024 12:12:09 +0900 Subject: [PATCH 58/98] Remove a warning message of PedAnovaImportanceEvaluator --- optuna_dashboard/_importance.py | 1 - 1 file changed, 1 deletion(-) diff --git a/optuna_dashboard/_importance.py b/optuna_dashboard/_importance.py index 8aa4bb77..b7189412 100644 --- a/optuna_dashboard/_importance.py +++ b/optuna_dashboard/_importance.py @@ -29,7 +29,6 @@ except Exception as e: try: from optuna.importance import PedAnovaImportanceEvaluator # type: ignore[attr-defined] except ImportError: - _logger.warning("optuna>=3.6.0 is required for PedAnovaImportanceEvaluator.") PedAnovaImportanceEvaluator = None # type: ignore From a3f66871d8bc21bf31f0dc808c4911cd133a3dd9 Mon Sep 17 00:00:00 2001 From: keisuke-umezawa Date: Tue, 5 Mar 2024 14:40:15 +0900 Subject: [PATCH 59/98] Delete setup.py --- setup.py | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 setup.py diff --git a/setup.py b/setup.py deleted file mode 100644 index 26e08e48..00000000 --- a/setup.py +++ /dev/null @@ -1,5 +0,0 @@ -from setuptools import setup - - -if __name__ == "__main__": - setup() From 7a9a251ef1a1ecf61e506690394945cdc1e304ec Mon Sep 17 00:00:00 2001 From: keisuke-umezawa Date: Tue, 5 Mar 2024 14:54:11 +0900 Subject: [PATCH 60/98] Delete setup command --- .github/workflows/github-release.yml | 2 +- .github/workflows/pypi-publish.yml | 2 +- Dockerfile | 1 - Makefile | 4 ++-- docs/getting-started.rst | 2 +- 5 files changed, 5 insertions(+), 6 deletions(-) diff --git a/.github/workflows/github-release.yml b/.github/workflows/github-release.yml index 858876a5..13fc17b6 100644 --- a/.github/workflows/github-release.yml +++ b/.github/workflows/github-release.yml @@ -27,7 +27,7 @@ jobs: run: | python -m pip install --upgrade pip setuptools pip install --progress-bar off wheel twine - - run: python setup.py sdist bdist_wheel + - run: python -m build - run: twine check dist/* - name: Create GitHub release diff --git a/.github/workflows/pypi-publish.yml b/.github/workflows/pypi-publish.yml index a01c2d8c..7d79419e 100644 --- a/.github/workflows/pypi-publish.yml +++ b/.github/workflows/pypi-publish.yml @@ -29,7 +29,7 @@ jobs: run: | python -m pip install --upgrade pip setuptools pip install --progress-bar off wheel twine - - run: python setup.py sdist bdist_wheel + - run: python -m buil - name: Publish distribution to PyPI uses: pypa/gh-action-pypi-publish@release/v1 diff --git a/Dockerfile b/Dockerfile index a3a1d6f6..2f54020f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -18,7 +18,6 @@ RUN pip install --upgrade pip setuptools RUN pip install --progress-bar off PyMySQL[rsa] psycopg2-binary gunicorn optuna-fast-fanova ADD ./pyproject.toml /usr/src/pyproject.toml -ADD ./setup.py /usr/src/setup.py ADD ./optuna_dashboard /usr/src/optuna_dashboard COPY --from=front-builder /usr/src/optuna_dashboard/public/ /usr/src/optuna_dashboard/public/ RUN pip install --progress-bar off . diff --git a/Makefile b/Makefile index 4094fd57..917e4aac 100644 --- a/Makefile +++ b/Makefile @@ -32,11 +32,11 @@ vscode-extension: vscode/assets/bundle.js .PHONY: sdist sdist: pyproject.toml $(DASHBOARD_TS_OUT) - python setup.py sdist + python -m build .PHONY: wheel wheel: pyproject.toml $(DASHBOARD_TS_OUT) - python setup.py bdist_wheel + python -m build .PHONY: docs docs: docs/conf.py $(RST_FILES) diff --git a/docs/getting-started.rst b/docs/getting-started.rst index 3375c469..f0b8ac89 100644 --- a/docs/getting-started.rst +++ b/docs/getting-started.rst @@ -48,7 +48,7 @@ Please clone the git repository and execute following commands to build sdist pa # Node.js v16 is required to compile TypeScript files. $ npm install $ npm run build:prd - $ python setup.py sdist + $ python -m build Then you can install it like: From 54d8b1f1e9363957656f9d6834a3217bdc92f58d Mon Sep 17 00:00:00 2001 From: keisuke-umezawa Date: Tue, 5 Mar 2024 14:58:09 +0900 Subject: [PATCH 61/98] Add --sdist --wheel --- .github/workflows/github-release.yml | 2 +- .github/workflows/pypi-publish.yml | 2 +- Makefile | 4 ++-- docs/getting-started.rst | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/github-release.yml b/.github/workflows/github-release.yml index 13fc17b6..469c2e58 100644 --- a/.github/workflows/github-release.yml +++ b/.github/workflows/github-release.yml @@ -27,7 +27,7 @@ jobs: run: | python -m pip install --upgrade pip setuptools pip install --progress-bar off wheel twine - - run: python -m build + - run: python -m build --sdist --wheel - run: twine check dist/* - name: Create GitHub release diff --git a/.github/workflows/pypi-publish.yml b/.github/workflows/pypi-publish.yml index 7d79419e..d9a810af 100644 --- a/.github/workflows/pypi-publish.yml +++ b/.github/workflows/pypi-publish.yml @@ -29,7 +29,7 @@ jobs: run: | python -m pip install --upgrade pip setuptools pip install --progress-bar off wheel twine - - run: python -m buil + - run: python -m build --sdist --wheel - name: Publish distribution to PyPI uses: pypa/gh-action-pypi-publish@release/v1 diff --git a/Makefile b/Makefile index 917e4aac..184b59df 100644 --- a/Makefile +++ b/Makefile @@ -32,11 +32,11 @@ vscode-extension: vscode/assets/bundle.js .PHONY: sdist sdist: pyproject.toml $(DASHBOARD_TS_OUT) - python -m build + python -m build --sdist .PHONY: wheel wheel: pyproject.toml $(DASHBOARD_TS_OUT) - python -m build + python -m build --wheel .PHONY: docs docs: docs/conf.py $(RST_FILES) diff --git a/docs/getting-started.rst b/docs/getting-started.rst index f0b8ac89..5d84e8aa 100644 --- a/docs/getting-started.rst +++ b/docs/getting-started.rst @@ -48,7 +48,7 @@ Please clone the git repository and execute following commands to build sdist pa # Node.js v16 is required to compile TypeScript files. $ npm install $ npm run build:prd - $ python -m build + $ python -m build --sdist Then you can install it like: From e5ca8ea0d382b72b8fe9550b520d5dc0ed88ed20 Mon Sep 17 00:00:00 2001 From: keisuke-umezawa Date: Tue, 5 Mar 2024 14:59:26 +0900 Subject: [PATCH 62/98] Install build --- .github/workflows/github-release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/github-release.yml b/.github/workflows/github-release.yml index 469c2e58..84d0b83f 100644 --- a/.github/workflows/github-release.yml +++ b/.github/workflows/github-release.yml @@ -26,7 +26,7 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip setuptools - pip install --progress-bar off wheel twine + pip install --progress-bar off wheel twine build - run: python -m build --sdist --wheel - run: twine check dist/* From bda7538d5ab0a5b9c2adb4c9e7a8deaf08802659 Mon Sep 17 00:00:00 2001 From: keisuke-umezawa Date: Tue, 5 Mar 2024 22:40:23 +0900 Subject: [PATCH 63/98] Fix e2e test --- e2e_tests/test_standalone/test_study_list.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/e2e_tests/test_standalone/test_study_list.py b/e2e_tests/test_standalone/test_study_list.py index e84a7f5a..421798ce 100644 --- a/e2e_tests/test_standalone/test_study_list.py +++ b/e2e_tests/test_standalone/test_study_list.py @@ -52,9 +52,9 @@ def test_load_storage( create_storage_file(filename) page.goto(url) with page.expect_file_chooser() as fc_info: - page.get_by_role("button").nth(2).click() - file_chooser = fc_info.value - file_chooser.set_files(path) + page.get_by_role("button").filter(has_text="Storage").click() + file_chooser = fc_info.value + file_chooser.set_files(path) page.get_by_role("link", name=study_name).click() From 8a65c2253428d9624f0cafccee6f3318595fdc6b Mon Sep 17 00:00:00 2001 From: keisuke-umezawa Date: Wed, 6 Mar 2024 23:01:38 +0900 Subject: [PATCH 64/98] Add examples link and delete examples directory --- README.md | 5 +++++ examples/README.md | 5 ----- 2 files changed, 5 insertions(+), 5 deletions(-) delete mode 100644 examples/README.md diff --git a/README.md b/README.md index 0df883e6..662e21f7 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,11 @@ [![Read the Docs](https://readthedocs.org/projects/optuna-dashboard/badge/?version=latest)](https://optuna-dashboard.readthedocs.io/en/latest/?badge=latest) [![Codecov](https://codecov.io/gh/optuna/optuna-dashboard/branch/main/graph/badge.svg)](https://codecov.io/gh/optuna/optuna-dashboard) +:link: [**Website**](https://optuna.org/) +| :page_with_curl: [**Docs**](https://optuna-dashboard.readthedocs.io/en/stable/) +| :gear: [**Install Guide**](https://optuna-dashboard.readthedocs.io/en/stable/getting-started.html#installation) +| :pencil: [**Tutorial**](https://optuna-dashboard.readthedocs.io/en/stable/tutorials/index.html) +| :bulb: [**Examples**](https://github.com/optuna/optuna-examples/tree/main/dashboard) Real-time dashboard for [Optuna](https://github.com/optuna/optuna). Code files were originally taken from [Goptuna](https://github.com/c-bata/goptuna). diff --git a/examples/README.md b/examples/README.md deleted file mode 100644 index ab86ed0a..00000000 --- a/examples/README.md +++ /dev/null @@ -1,5 +0,0 @@ -Optuna Dashboard Examples -========================= - -Example files have been moved to the [optuna/optuna-examples](https://github.com/optuna/optuna-examples/) repoistory. -You can find the dashboard-related examples in the [dashboard](https://github.com/optuna/optuna-examples/tree/main/dashboard) directory. From f4822976b63d093658924b5842a806e108330a9e Mon Sep 17 00:00:00 2001 From: y0z Date: Thu, 7 Mar 2024 11:59:53 +0900 Subject: [PATCH 65/98] Apply review comments. --- optuna_dashboard/ts/components/TrialList.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/optuna_dashboard/ts/components/TrialList.tsx b/optuna_dashboard/ts/components/TrialList.tsx index a4444fa4..3d47f91a 100644 --- a/optuna_dashboard/ts/components/TrialList.tsx +++ b/optuna_dashboard/ts/components/TrialList.tsx @@ -346,7 +346,7 @@ export const TrialList: FC<{ studyDetail: StudyDetail | null }> = ({ const rowVirtualizer = useVirtualizer({ count: trials.length, getScrollElement: () => listParentRef.current, - estimateSize: () => 75, + estimateSize: () => 73.31, overscan: 10, }) @@ -431,7 +431,6 @@ export const TrialList: FC<{ studyDetail: StudyDetail | null }> = ({ }} > {rowVirtualizer.getVirtualItems().map((virtualItem) => { - console.log(virtualItem.index, virtualItem.start, virtualItem.end) const trial = trials[virtualItem.index] return ( = ({ -1 } sx={{ + width: "100%", display: "flex", flexDirection: "column", alignItems: "flex-start", From 711dcb3b5a52ea3c60088cb82bd55f79c0239229 Mon Sep 17 00:00:00 2001 From: c-bata Date: Thu, 7 Mar 2024 17:09:55 +0900 Subject: [PATCH 66/98] Update package.json --- standalone_app/package-lock.json | 1207 ++++++++++++++++-------------- standalone_app/package.json | 29 +- 2 files changed, 642 insertions(+), 594 deletions(-) diff --git a/standalone_app/package-lock.json b/standalone_app/package-lock.json index 6feadbc3..8c05f23a 100644 --- a/standalone_app/package-lock.json +++ b/standalone_app/package-lock.json @@ -10,31 +10,30 @@ "dependencies": { "@emotion/react": "^11.11.3", "@emotion/styled": "^11.11.0", - "@mui/icons-material": "^5.15.6", - "@mui/lab": "^5.0.0-alpha.162", - "@mui/material": "^5.15.6", + "@mui/icons-material": "^5.15.12", + "@mui/lab": "^5.0.0-alpha.167", + "@mui/material": "^5.15.12", "@sqlite.org/sqlite-wasm": "^3.45.1-build1", "module-workers-polyfill": "^0.3.2", "notistack": "^3.0.1", "optuna": "../rustlib/pkg", - "plotly.js-dist-min": "^2.28.0", + "plotly.js-dist-min": "^2.30.0", "react": "^18.2.0", "react-dom": "^18.2.0", - "react-router-dom": "^6.11.0", + "react-router-dom": "^6.22.2", "recoil": "^0.7.7" }, "devDependencies": { - "@types/plotly.js": "^2.12.18", - "@types/react": "^18.2.0", - "@types/react-dom": "^18.2.1", + "@types/plotly.js": "^2.29.2", + "@types/react": "^18.2.64", + "@types/react-dom": "^18.2.21", "@types/react-router-dom": "^5.3.3", - "compression-webpack-plugin": "^10.0.0", - "esbuild-loader": "^3.0.1", - "prettier": "^2.8.8", - "ts-loader": "^9.4.2", - "typescript": "^5.0.4", - "webpack": "^5.82.1", - "webpack-cli": "^5.1.1" + "compression-webpack-plugin": "^11.1.0", + "esbuild-loader": "^4.0.3", + "ts-loader": "^9.5.1", + "typescript": "^5.4.2", + "webpack": "^5.90.3", + "webpack-cli": "^5.1.4" } }, "../rustlib/pkg": { @@ -264,10 +263,26 @@ "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz", "integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==" }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz", + "integrity": "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/@esbuild/android-arm": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.18.tgz", - "integrity": "sha512-EmwL+vUBZJ7mhFCs5lA4ZimpUH3WMAoqvOIYhVQwdIgSpHC8ImHdsRyhHAVxpDYUSm0lWvd63z0XH1IlImS2Qw==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz", + "integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==", "cpu": [ "arm" ], @@ -281,9 +296,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.18.tgz", - "integrity": "sha512-/iq0aK0eeHgSC3z55ucMAHO05OIqmQehiGay8eP5l/5l+iEr4EIbh4/MI8xD9qRFjqzgkc0JkX0LculNC9mXBw==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz", + "integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==", "cpu": [ "arm64" ], @@ -297,9 +312,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.18.tgz", - "integrity": "sha512-x+0efYNBF3NPW2Xc5bFOSFW7tTXdAcpfEg2nXmxegm4mJuVeS+i109m/7HMiOQ6M12aVGGFlqJX3RhNdYM2lWg==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz", + "integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==", "cpu": [ "x64" ], @@ -313,9 +328,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.18.tgz", - "integrity": "sha512-6tY+djEAdF48M1ONWnQb1C+6LiXrKjmqjzPNPWXhu/GzOHTHX2nh8Mo2ZAmBFg0kIodHhciEgUBtcYCAIjGbjQ==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz", + "integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==", "cpu": [ "arm64" ], @@ -329,9 +344,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.18.tgz", - "integrity": "sha512-Qq84ykvLvya3dO49wVC9FFCNUfSrQJLbxhoQk/TE1r6MjHo3sFF2tlJCwMjhkBVq3/ahUisj7+EpRSz0/+8+9A==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz", + "integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==", "cpu": [ "x64" ], @@ -345,9 +360,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.18.tgz", - "integrity": "sha512-fw/ZfxfAzuHfaQeMDhbzxp9mc+mHn1Y94VDHFHjGvt2Uxl10mT4CDavHm+/L9KG441t1QdABqkVYwakMUeyLRA==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz", + "integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==", "cpu": [ "arm64" ], @@ -361,9 +376,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.18.tgz", - "integrity": "sha512-FQFbRtTaEi8ZBi/A6kxOC0V0E9B/97vPdYjY9NdawyLd4Qk5VD5g2pbWN2VR1c0xhzcJm74HWpObPszWC+qTew==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz", + "integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==", "cpu": [ "x64" ], @@ -377,9 +392,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.18.tgz", - "integrity": "sha512-jW+UCM40LzHcouIaqv3e/oRs0JM76JfhHjCavPxMUti7VAPh8CaGSlS7cmyrdpzSk7A+8f0hiedHqr/LMnfijg==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz", + "integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==", "cpu": [ "arm" ], @@ -393,9 +408,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.18.tgz", - "integrity": "sha512-R7pZvQZFOY2sxUG8P6A21eq6q+eBv7JPQYIybHVf1XkQYC+lT7nDBdC7wWKTrbvMXKRaGudp/dzZCwL/863mZQ==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz", + "integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==", "cpu": [ "arm64" ], @@ -409,9 +424,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.18.tgz", - "integrity": "sha512-ygIMc3I7wxgXIxk6j3V00VlABIjq260i967Cp9BNAk5pOOpIXmd1RFQJQX9Io7KRsthDrQYrtcx7QCof4o3ZoQ==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz", + "integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==", "cpu": [ "ia32" ], @@ -425,9 +440,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.18.tgz", - "integrity": "sha512-bvPG+MyFs5ZlwYclCG1D744oHk1Pv7j8psF5TfYx7otCVmcJsEXgFEhQkbhNW8otDHL1a2KDINW20cfCgnzgMQ==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz", + "integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==", "cpu": [ "loong64" ], @@ -441,9 +456,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.18.tgz", - "integrity": "sha512-oVqckATOAGuiUOa6wr8TXaVPSa+6IwVJrGidmNZS1cZVx0HqkTMkqFGD2HIx9H1RvOwFeWYdaYbdY6B89KUMxA==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz", + "integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==", "cpu": [ "mips64el" ], @@ -457,9 +472,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.18.tgz", - "integrity": "sha512-3dLlQO+b/LnQNxgH4l9rqa2/IwRJVN9u/bK63FhOPB4xqiRqlQAU0qDU3JJuf0BmaH0yytTBdoSBHrb2jqc5qQ==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz", + "integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==", "cpu": [ "ppc64" ], @@ -473,9 +488,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.18.tgz", - "integrity": "sha512-/x7leOyDPjZV3TcsdfrSI107zItVnsX1q2nho7hbbQoKnmoeUWjs+08rKKt4AUXju7+3aRZSsKrJtaRmsdL1xA==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz", + "integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==", "cpu": [ "riscv64" ], @@ -489,9 +504,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.18.tgz", - "integrity": "sha512-cX0I8Q9xQkL/6F5zWdYmVf5JSQt+ZfZD2bJudZrWD+4mnUvoZ3TDDXtDX2mUaq6upMFv9FlfIh4Gfun0tbGzuw==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz", + "integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==", "cpu": [ "s390x" ], @@ -505,9 +520,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.18.tgz", - "integrity": "sha512-66RmRsPlYy4jFl0vG80GcNRdirx4nVWAzJmXkevgphP1qf4dsLQCpSKGM3DUQCojwU1hnepI63gNZdrr02wHUA==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz", + "integrity": "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==", "cpu": [ "x64" ], @@ -521,9 +536,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.18.tgz", - "integrity": "sha512-95IRY7mI2yrkLlTLb1gpDxdC5WLC5mZDi+kA9dmM5XAGxCME0F8i4bYH4jZreaJ6lIZ0B8hTrweqG1fUyW7jbg==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz", + "integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==", "cpu": [ "x64" ], @@ -537,9 +552,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.18.tgz", - "integrity": "sha512-WevVOgcng+8hSZ4Q3BKL3n1xTv5H6Nb53cBrtzzEjDbbnOmucEVcZeGCsCOi9bAOcDYEeBZbD2SJNBxlfP3qiA==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz", + "integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==", "cpu": [ "x64" ], @@ -553,9 +568,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.18.tgz", - "integrity": "sha512-Rzf4QfQagnwhQXVBS3BYUlxmEbcV7MY+BH5vfDZekU5eYpcffHSyjU8T0xucKVuOcdCsMo+Ur5wmgQJH2GfNrg==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz", + "integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==", "cpu": [ "x64" ], @@ -569,9 +584,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.18.tgz", - "integrity": "sha512-Kb3Ko/KKaWhjeAm2YoT/cNZaHaD1Yk/pa3FTsmqo9uFh1D1Rfco7BBLIPdDOozrObj2sahslFuAQGvWbgWldAg==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz", + "integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==", "cpu": [ "arm64" ], @@ -585,9 +600,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.18.tgz", - "integrity": "sha512-0/xUMIdkVHwkvxfbd5+lfG7mHOf2FRrxNbPiKWg9C4fFrB8H0guClmaM3BFiRUYrznVoyxTIyC/Ou2B7QQSwmw==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz", + "integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==", "cpu": [ "ia32" ], @@ -601,9 +616,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.18.tgz", - "integrity": "sha512-qU25Ma1I3NqTSHJUOKi9sAH1/Mzuvlke0ioMJRthLXKm7JiSKVwFghlGbDLOO2sARECGhja4xYfRAZNPAkooYg==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz", + "integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==", "cpu": [ "x64" ], @@ -651,41 +666,41 @@ "integrity": "sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q==" }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "dev": true, "dependencies": { - "@jridgewell/set-array": "^1.0.1", + "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/trace-mapping": "^0.3.24" }, "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "dev": true, "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", "dev": true, "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/source-map": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.3.tgz", - "integrity": "sha512-b+fsZXeLYi9fEULmfBrhxn4IrPlINf8fiNarzTof004v3lFdntdwa9PF7vFJqm3mg7s+ScJMxXaE3Acp1irZcg==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", + "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", "dev": true, "dependencies": { "@jridgewell/gen-mapping": "^0.3.0", @@ -699,30 +714,24 @@ "dev": true }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.18", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", - "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dev": true, "dependencies": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@jridgewell/trace-mapping/node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "dev": true - }, "node_modules/@mui/base": { - "version": "5.0.0-beta.37", - "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.37.tgz", - "integrity": "sha512-/o3anbb+DeCng8jNsd3704XtmmLDZju1Fo8R2o7ugrVtPQ/QpcqddwKNzKPZwa0J5T8YNW3ZVuHyQgbTnQLisQ==", + "version": "5.0.0-beta.38", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.38.tgz", + "integrity": "sha512-AsjD6Y1X5A1qndxz8xCcR8LDqv31aiwlgWMPxFAX/kCKiIGKlK65yMeVZ62iQr/6LBz+9hSKLiD1i4TZdAHKcQ==", "dependencies": { "@babel/runtime": "^7.23.9", "@floating-ui/react-dom": "^2.0.8", "@mui/types": "^7.2.13", - "@mui/utils": "^5.15.11", + "@mui/utils": "^5.15.12", "@popperjs/core": "^2.11.8", "clsx": "^2.1.0", "prop-types": "^15.8.1" @@ -754,18 +763,18 @@ } }, "node_modules/@mui/core-downloads-tracker": { - "version": "5.15.11", - "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.15.11.tgz", - "integrity": "sha512-JVrJ9Jo4gyU707ujnRzmE8ABBWpXd6FwL9GYULmwZRtfPg89ggXs/S3MStQkpJ1JRWfdLL6S5syXmgQGq5EDAw==", + "version": "5.15.12", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.15.12.tgz", + "integrity": "sha512-brRO+tMFLpGyjEYHrX97bzqeF6jZmKpqqe1rY0LyIHAwP6xRVzh++zSecOQorDOCaZJg4XkGT9xfD+RWOWxZBA==", "funding": { "type": "opencollective", "url": "https://opencollective.com/mui-org" } }, "node_modules/@mui/icons-material": { - "version": "5.15.11", - "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.15.11.tgz", - "integrity": "sha512-R5ZoQqnKpd+5Ew7mBygTFLxgYsQHPhgR3TDXSgIHYIjGzYuyPLmGLSdcPUoMdi6kxiYqHlpPj4NJxlbaFD0UHA==", + "version": "5.15.12", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.15.12.tgz", + "integrity": "sha512-3BXiDlOd3AexZoEXa/VqpIpVIvosCzjLHsdMWzKMXbZdnBiJjmb9ECdqfjn5SpTClO49qvkKLhkTqdBH3fSFGw==", "dependencies": { "@babel/runtime": "^7.23.9" }, @@ -788,15 +797,15 @@ } }, "node_modules/@mui/lab": { - "version": "5.0.0-alpha.166", - "resolved": "https://registry.npmjs.org/@mui/lab/-/lab-5.0.0-alpha.166.tgz", - "integrity": "sha512-a+0yorrgxLIgfKhShVKQk0/5CnB4KBhMQ64SvEB+CsvKAKKJzjIU43m2nMqdBbWzfnEuj6wR9vQ9kambdn3ZKA==", + "version": "5.0.0-alpha.167", + "resolved": "https://registry.npmjs.org/@mui/lab/-/lab-5.0.0-alpha.167.tgz", + "integrity": "sha512-BNQJ7fBBvL68WGVnzAhbtTmabSuJDXaILr9dz/3RNK4TgGXPgWCAr7qtJeUdc4p1t7c4Z1ifG8UwgqD+5hzMNg==", "dependencies": { "@babel/runtime": "^7.23.9", - "@mui/base": "5.0.0-beta.37", - "@mui/system": "^5.15.11", + "@mui/base": "5.0.0-beta.38", + "@mui/system": "^5.15.12", "@mui/types": "^7.2.13", - "@mui/utils": "^5.15.11", + "@mui/utils": "^5.15.12", "clsx": "^2.1.0", "prop-types": "^15.8.1" }, @@ -836,16 +845,16 @@ } }, "node_modules/@mui/material": { - "version": "5.15.11", - "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.15.11.tgz", - "integrity": "sha512-FA3eEuEZaDaxgN3CgfXezMWbCZ4VCeU/sv0F0/PK5n42qIgsPVD6q+j71qS7/62sp6wRFMHtDMpXRlN+tT/7NA==", + "version": "5.15.12", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.15.12.tgz", + "integrity": "sha512-vXJGg6KNKucsvbW6l7w9zafnpOp0CWc0Wx4mDykuABTpQ5QQBnZxP7+oB4yAS1hDZQ1WobbeIl0CjxK4EEahkA==", "dependencies": { "@babel/runtime": "^7.23.9", - "@mui/base": "5.0.0-beta.37", - "@mui/core-downloads-tracker": "^5.15.11", - "@mui/system": "^5.15.11", + "@mui/base": "5.0.0-beta.38", + "@mui/core-downloads-tracker": "^5.15.12", + "@mui/system": "^5.15.12", "@mui/types": "^7.2.13", - "@mui/utils": "^5.15.11", + "@mui/utils": "^5.15.12", "@types/react-transition-group": "^4.4.10", "clsx": "^2.1.0", "csstype": "^3.1.3", @@ -888,12 +897,12 @@ } }, "node_modules/@mui/private-theming": { - "version": "5.15.11", - "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.15.11.tgz", - "integrity": "sha512-jY/696SnSxSzO1u86Thym7ky5T9CgfidU3NFJjguldqK4f3Z5S97amZ6nffg8gTD0HBjY9scB+4ekqDEUmxZOA==", + "version": "5.15.12", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.15.12.tgz", + "integrity": "sha512-cqoSo9sgA5HE+8vZClbLrq9EkyOnYysooepi5eKaKvJ41lReT2c5wOZAeDDM1+xknrMDos+0mT2zr3sZmUiRRA==", "dependencies": { "@babel/runtime": "^7.23.9", - "@mui/utils": "^5.15.11", + "@mui/utils": "^5.15.12", "prop-types": "^15.8.1" }, "engines": { @@ -945,15 +954,15 @@ } }, "node_modules/@mui/system": { - "version": "5.15.11", - "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.15.11.tgz", - "integrity": "sha512-9j35suLFq+MgJo5ktVSHPbkjDLRMBCV17NMBdEQurh6oWyGnLM4uhU4QGZZQ75o0vuhjJghOCA1jkO3+79wKsA==", + "version": "5.15.12", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.15.12.tgz", + "integrity": "sha512-/pq+GO6yN3X7r3hAwFTrzkAh7K1bTF5r8IzS79B9eyKJg7v6B/t4/zZYMR6OT9qEPtwf6rYN2Utg1e6Z7F1OgQ==", "dependencies": { "@babel/runtime": "^7.23.9", - "@mui/private-theming": "^5.15.11", + "@mui/private-theming": "^5.15.12", "@mui/styled-engine": "^5.15.11", "@mui/types": "^7.2.13", - "@mui/utils": "^5.15.11", + "@mui/utils": "^5.15.12", "clsx": "^2.1.0", "csstype": "^3.1.3", "prop-types": "^15.8.1" @@ -1005,9 +1014,9 @@ } }, "node_modules/@mui/utils": { - "version": "5.15.11", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.15.11.tgz", - "integrity": "sha512-D6bwqprUa9Stf8ft0dcMqWyWDKEo7D+6pB1k8WajbqlYIRA8J8Kw9Ra7PSZKKePGBGWO+/xxrX1U8HpG/aXQCw==", + "version": "5.15.12", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.15.12.tgz", + "integrity": "sha512-8SDGCnO2DY9Yy+5bGzu00NZowSDtuyHP4H8gunhHGQoIlhlY2Z3w64wBzAOLpYw/ZhJNzksDTnS/i8qdJvxuow==", "dependencies": { "@babel/runtime": "^7.23.9", "@types/prop-types": "^15.7.11", @@ -1041,11 +1050,11 @@ } }, "node_modules/@remix-run/router": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.6.0.tgz", - "integrity": "sha512-N13NRw3T2+6Xi9J//3CGLsK2OqC8NMme3d/YX+nh05K9YHWGcv8DycHJrqGScSP4T75o8IN6nqIMhVFU8ohg8w==", + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.15.2.tgz", + "integrity": "sha512-+Rnav+CaoTE5QJc4Jcwh5toUpnVLKYbpU6Ys0zqbakqbaLQHeglLVHPfxOiQqdNmUy5C2lXz5dwC6tQNX2JW2Q==", "engines": { - "node": ">=14" + "node": ">=14.0.0" } }, "node_modules/@sqlite.org/sqlite-wasm": { @@ -1077,9 +1086,9 @@ } }, "node_modules/@types/estree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", - "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", "dev": true }, "node_modules/@types/history": { @@ -1095,10 +1104,13 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.1.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.1.3.tgz", - "integrity": "sha512-NP2yfZpgmf2eDRPmgGq+fjGjSwFgYbihA8/gK+ey23qT9RkxsgNTZvGOEpXgzIGqesTYkElELLgtKoMQTys5vA==", - "dev": true + "version": "20.11.25", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.25.tgz", + "integrity": "sha512-TBHyJxk2b7HceLVGFcpAUjsa5zIdsPWlR6XHfyGzd0SFu+/NFgQgMAl96MSDZgQDvJAvV6BKsFOrt6zIL09JDw==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } }, "node_modules/@types/parse-json": { "version": "4.0.2", @@ -1106,9 +1118,9 @@ "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==" }, "node_modules/@types/plotly.js": { - "version": "2.12.18", - "resolved": "https://registry.npmjs.org/@types/plotly.js/-/plotly.js-2.12.18.tgz", - "integrity": "sha512-ff+CIEWnqZNjZqHtQZvkEAVuLs9fkm1f54QnPVmgoET7wMHdSqUka2hasVN4e5yfHD05YwGjsAtCseewJh/BMw==", + "version": "2.29.2", + "resolved": "https://registry.npmjs.org/@types/plotly.js/-/plotly.js-2.29.2.tgz", + "integrity": "sha512-tJqUVa6CmNHrzTANWO/ZLNmdvjZ6zHOAnM9iQUORVnnLvWmcO9DPdQCsrNumNvHD1aqGNxQJ8pla8CK/NUiZgA==", "dev": true }, "node_modules/@types/prop-types": { @@ -1117,9 +1129,9 @@ "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==" }, "node_modules/@types/react": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.0.tgz", - "integrity": "sha512-0FLj93y5USLHdnhIhABk83rm8XEGA7kH3cr+YUlvxoUGp1xNt/DINUMvqPxLyOQMzLmZe8i4RTHbvb8MC7NmrA==", + "version": "18.2.64", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.64.tgz", + "integrity": "sha512-MlmPvHgjj2p3vZaxbQgFUQFvD8QiZwACfGqEdDSWou5yISWxDQ4/74nCAwsUiX7UFLKZz3BbVSPj+YxeoGGCfg==", "dependencies": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -1127,9 +1139,9 @@ } }, "node_modules/@types/react-dom": { - "version": "18.2.1", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.1.tgz", - "integrity": "sha512-8QZEV9+Kwy7tXFmjJrp3XUKQSs9LTnE0KnoUb0YCguWBiNW0Yfb2iBMYZ08WPg35IR6P3Z0s00B15SwZnO26+w==", + "version": "18.2.21", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.21.tgz", + "integrity": "sha512-gnvBA/21SA4xxqNXEwNiVcP0xSGHh/gi1VhWv9Bl46a0ItbTT5nFY+G9VSQpaG/8N/qdJpJ+vftQ4zflTtnjLw==", "dev": true, "dependencies": { "@types/react": "*" @@ -1316,9 +1328,9 @@ } }, "node_modules/@webpack-cli/configtest": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.0.tgz", - "integrity": "sha512-K/vuv72vpfSEZoo5KIU0a2FsEoYdW0DUMtMpB5X3LlUwshetMZRZRxB7sCsVji/lFaSxtQQ3aM9O4eMolXkU9w==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.1.tgz", + "integrity": "sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==", "dev": true, "engines": { "node": ">=14.15.0" @@ -1329,9 +1341,9 @@ } }, "node_modules/@webpack-cli/info": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.1.tgz", - "integrity": "sha512-fE1UEWTwsAxRhrJNikE7v4EotYflkEhBL7EbajfkPlf6E37/2QshOy/D48Mw8G5XMFlQtS6YV42vtbG9zBpIQA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.2.tgz", + "integrity": "sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==", "dev": true, "engines": { "node": ">=14.15.0" @@ -1342,9 +1354,9 @@ } }, "node_modules/@webpack-cli/serve": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.4.tgz", - "integrity": "sha512-0xRgjgDLdz6G7+vvDLlaRpFatJaJ69uTalZLRSMX5B3VUrDmXcrVA3+6fXXQgmYz7bY9AAgs348XQdmtLsK41A==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.5.tgz", + "integrity": "sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==", "dev": true, "engines": { "node": ">=14.15.0" @@ -1503,9 +1515,9 @@ } }, "node_modules/browserslist": { - "version": "4.21.5", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz", - "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==", + "version": "4.23.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", + "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", "dev": true, "funding": [ { @@ -1515,13 +1527,17 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], "dependencies": { - "caniuse-lite": "^1.0.30001449", - "electron-to-chromium": "^1.4.284", - "node-releases": "^2.0.8", - "update-browserslist-db": "^1.0.10" + "caniuse-lite": "^1.0.30001587", + "electron-to-chromium": "^1.4.668", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" }, "bin": { "browserslist": "cli.js" @@ -1545,9 +1561,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001481", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001481.tgz", - "integrity": "sha512-KCqHwRnaa1InZBtqXzP98LPg0ajCVujMKjqKDhZEthIpAsJl/YEIa3YvXjGXPVqzZVguccuu7ga9KOE1J9rKPQ==", + "version": "1.0.30001596", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001596.tgz", + "integrity": "sha512-zpkZ+kEr6We7w63ORkoJ2pOfBwBkY/bJrG/UZ90qNb45Isblu8wzDgevEOrRL1r9dWayHjYiiyCMEXPn4DweGQ==", "dev": true, "funding": [ { @@ -1642,16 +1658,16 @@ "dev": true }, "node_modules/compression-webpack-plugin": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/compression-webpack-plugin/-/compression-webpack-plugin-10.0.0.tgz", - "integrity": "sha512-wLXLIBwpul/ALcm7Aj+69X0pYT3BYt6DdPn3qrgBIh9YejV9Bju9ShhlAsjujLyWMo6SAweFIWaUoFmXZNuNrg==", + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/compression-webpack-plugin/-/compression-webpack-plugin-11.1.0.tgz", + "integrity": "sha512-zDOQYp10+upzLxW+VRSjEpRRwBXJdsb5lBMlRxx1g8hckIFBpe3DTI0en2w7h+beuq89576RVzfiXrkdPGrHhA==", "dev": true, "dependencies": { - "schema-utils": "^4.0.0", - "serialize-javascript": "^6.0.0" + "schema-utils": "^4.2.0", + "serialize-javascript": "^6.0.2" }, "engines": { - "node": ">= 14.15.0" + "node": ">= 18.12.0" }, "funding": { "type": "opencollective", @@ -1763,9 +1779,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.372", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.372.tgz", - "integrity": "sha512-MrlFq/j+TYHOjeWsWGYfzevc25HNeJdsF6qaLFrqBTRWZQtWkb1myq/Q2veLWezVaa5OcSZ99CFwTT4aF4Mung==", + "version": "1.4.695", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.695.tgz", + "integrity": "sha512-eMijZmeqPtm774pCZIOrfUHMs/7ls++W1sLhxwqgu8KQ8E2WmMtzwyqOMt0XXUJ3HTIPfuwlfwF+I5cwnfItBA==", "dev": true }, "node_modules/emojis-list": { @@ -1778,9 +1794,9 @@ } }, "node_modules/enhanced-resolve": { - "version": "5.14.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.14.0.tgz", - "integrity": "sha512-+DCows0XNwLDcUhbFJPdlQEVnT2zXlCv7hPxemTz86/O+B/hCQ+mb7ydkPKiflpVraqLPCAfu7lDy+hBXueojw==", + "version": "5.15.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.1.tgz", + "integrity": "sha512-3d3JRbwsCLJsYgvb6NuWEG44jjPSOMuS73L/6+7BZuoKm3W+qXnSoIYVHi8dG7Qcg4inAY4jbzkZ7MnskePeDg==", "dev": true, "dependencies": { "graceful-fs": "^4.2.4", @@ -1817,9 +1833,9 @@ "dev": true }, "node_modules/esbuild": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.18.tgz", - "integrity": "sha512-z1lix43jBs6UKjcZVKOw2xx69ffE2aG0PygLL5qJ9OS/gy0Ewd1gW/PUQIOIQGXBHWNywSc0floSKoMFF8aK2w==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz", + "integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==", "dev": true, "hasInstallScript": true, "bin": { @@ -1829,52 +1845,53 @@ "node": ">=12" }, "optionalDependencies": { - "@esbuild/android-arm": "0.17.18", - "@esbuild/android-arm64": "0.17.18", - "@esbuild/android-x64": "0.17.18", - "@esbuild/darwin-arm64": "0.17.18", - "@esbuild/darwin-x64": "0.17.18", - "@esbuild/freebsd-arm64": "0.17.18", - "@esbuild/freebsd-x64": "0.17.18", - "@esbuild/linux-arm": "0.17.18", - "@esbuild/linux-arm64": "0.17.18", - "@esbuild/linux-ia32": "0.17.18", - "@esbuild/linux-loong64": "0.17.18", - "@esbuild/linux-mips64el": "0.17.18", - "@esbuild/linux-ppc64": "0.17.18", - "@esbuild/linux-riscv64": "0.17.18", - "@esbuild/linux-s390x": "0.17.18", - "@esbuild/linux-x64": "0.17.18", - "@esbuild/netbsd-x64": "0.17.18", - "@esbuild/openbsd-x64": "0.17.18", - "@esbuild/sunos-x64": "0.17.18", - "@esbuild/win32-arm64": "0.17.18", - "@esbuild/win32-ia32": "0.17.18", - "@esbuild/win32-x64": "0.17.18" + "@esbuild/aix-ppc64": "0.19.12", + "@esbuild/android-arm": "0.19.12", + "@esbuild/android-arm64": "0.19.12", + "@esbuild/android-x64": "0.19.12", + "@esbuild/darwin-arm64": "0.19.12", + "@esbuild/darwin-x64": "0.19.12", + "@esbuild/freebsd-arm64": "0.19.12", + "@esbuild/freebsd-x64": "0.19.12", + "@esbuild/linux-arm": "0.19.12", + "@esbuild/linux-arm64": "0.19.12", + "@esbuild/linux-ia32": "0.19.12", + "@esbuild/linux-loong64": "0.19.12", + "@esbuild/linux-mips64el": "0.19.12", + "@esbuild/linux-ppc64": "0.19.12", + "@esbuild/linux-riscv64": "0.19.12", + "@esbuild/linux-s390x": "0.19.12", + "@esbuild/linux-x64": "0.19.12", + "@esbuild/netbsd-x64": "0.19.12", + "@esbuild/openbsd-x64": "0.19.12", + "@esbuild/sunos-x64": "0.19.12", + "@esbuild/win32-arm64": "0.19.12", + "@esbuild/win32-ia32": "0.19.12", + "@esbuild/win32-x64": "0.19.12" } }, "node_modules/esbuild-loader": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/esbuild-loader/-/esbuild-loader-3.0.1.tgz", - "integrity": "sha512-aZfGybqTeuyCd4AsVvWOOfkhIuN+wfZFjMyh3gyQEU1Uvsl8L6vye9HqP93iRa0iTA+6Jclap514PJIC3cLnMA==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/esbuild-loader/-/esbuild-loader-4.0.3.tgz", + "integrity": "sha512-YpaSRisj7TSg6maKKKG9OJGGm0BZ7EXeov8J8cXEYdugjlAJ0wL7aj2JactoQvPJ113v2Ar204pdJWrZsAQc8Q==", "dev": true, "dependencies": { - "esbuild": "^0.17.6", - "get-tsconfig": "^4.4.0", + "esbuild": "^0.19.0", + "get-tsconfig": "^4.7.0", "loader-utils": "^2.0.4", "webpack-sources": "^1.4.3" }, "funding": { - "url": "https://github.com/esbuild-kit/esbuild-loader?sponsor=1" + "url": "https://github.com/privatenumber/esbuild-loader?sponsor=1" }, "peerDependencies": { "webpack": "^4.40.0 || ^5.0.0" } }, "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", "dev": true, "engines": { "node": ">=6" @@ -2000,10 +2017,13 @@ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, "node_modules/get-tsconfig": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.5.0.tgz", - "integrity": "sha512-MjhiaIWCJ1sAU4pIQ5i5OfOuHHxVo1oYeNsWTON7jxYkod8pHocXeh+SSbmu5OZZZK73B6cbJ2XADzXehLyovQ==", + "version": "4.7.3", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.3.tgz", + "integrity": "sha512-ZvkrzoUA0PQZM6fy6+/Hce561s+faD1rsNwhnO5FelNjyy7EMGJ3Rz1AQ8GYDWjhRs/7dBLOEJvhK8MiEJOAFg==", "dev": true, + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, "funding": { "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" } @@ -2350,9 +2370,9 @@ "dev": true }, "node_modules/node-releases": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz", - "integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==", + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", "dev": true }, "node_modules/notistack": { @@ -2514,24 +2534,9 @@ } }, "node_modules/plotly.js-dist-min": { - "version": "2.29.1", - "resolved": "https://registry.npmjs.org/plotly.js-dist-min/-/plotly.js-dist-min-2.29.1.tgz", - "integrity": "sha512-YvqX5TISWsJVTDIaUh2Qgt9uhLl0bWcQhO2rLPF0/hIY9BlinFa1JwSO2jFKcEmG0AJXSo4DnVdgKpsk9/8Apg==" - }, - "node_modules/prettier": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", - "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", - "dev": true, - "bin": { - "prettier": "bin-prettier.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } + "version": "2.30.0", + "resolved": "https://registry.npmjs.org/plotly.js-dist-min/-/plotly.js-dist-min-2.30.0.tgz", + "integrity": "sha512-LM7v0H8MZUNnOT0WmJt8apvXnrjytUgxvG9RAcGT2AsJNlCxLGMMFYQS5TEiYNRH96/hcV8KGQmw+NwjmXSFSA==" }, "node_modules/prop-types": { "version": "15.8.1", @@ -2595,29 +2600,29 @@ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" }, "node_modules/react-router": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.11.0.tgz", - "integrity": "sha512-hTm6KKNpj9SDG4syIWRjCU219O0RZY8RUPobCFt9p+PlF7nnkRgMoh2DieTKvw3F3Mw6zg565HGnSv8BuoY5oQ==", + "version": "6.22.2", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.22.2.tgz", + "integrity": "sha512-YD3Dzprzpcq+tBMHBS822tCjnWD3iIZbTeSXMY9LPSG541EfoBGyZ3bS25KEnaZjLcmQpw2AVLkFyfgXY8uvcw==", "dependencies": { - "@remix-run/router": "1.6.0" + "@remix-run/router": "1.15.2" }, "engines": { - "node": ">=14" + "node": ">=14.0.0" }, "peerDependencies": { "react": ">=16.8" } }, "node_modules/react-router-dom": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.11.0.tgz", - "integrity": "sha512-Q3mK1c/CYoF++J6ZINz7EZzwlgSOZK/kc7lxIA7PhtWhKju4KfF1WHqlx0kVCIFJAWztuYVpXZeljEbds8z4Og==", + "version": "6.22.2", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.22.2.tgz", + "integrity": "sha512-WgqxD2qySEIBPZ3w0sHH+PUAiamDeszls9tzqMPBDA1YYVucTBXLU7+gtRfcSnhe92A3glPnvSxK2dhNoAVOIQ==", "dependencies": { - "@remix-run/router": "1.6.0", - "react-router": "6.11.0" + "@remix-run/router": "1.15.2", + "react-router": "6.22.2" }, "engines": { - "node": ">=14" + "node": ">=14.0.0" }, "peerDependencies": { "react": ">=16.8", @@ -2729,6 +2734,15 @@ "node": ">=4" } }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -2758,9 +2772,9 @@ } }, "node_modules/schema-utils": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.2.tgz", - "integrity": "sha512-pvjEHOgWc9OWA/f/DE3ohBWTD6EleVLf7iFUkoSwAxttdBhB9QUebQgxER2kWueOvRJXPHNnyrvvh9eZINB8Eg==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", "dev": true, "dependencies": { "@types/json-schema": "^7.0.8", @@ -2791,9 +2805,9 @@ } }, "node_modules/serialize-javascript": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", - "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", "dev": true, "dependencies": { "randombytes": "^2.1.0" @@ -2902,13 +2916,13 @@ } }, "node_modules/terser": { - "version": "5.17.3", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.17.3.tgz", - "integrity": "sha512-AudpAZKmZHkG9jueayypz4duuCFJMMNGRMwaPvQKWfxKedh8Z2x3OCoDqIIi1xx5+iwx1u6Au8XQcc9Lke65Yg==", + "version": "5.29.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.29.1.tgz", + "integrity": "sha512-lZQ/fyaIGxsbGxApKmoPTODIzELy3++mXhS5hOqaAWZjQtpq/hFHAc+rm29NND1rYRxRWKcjuARNwULNXa5RtQ==", "dev": true, "dependencies": { - "@jridgewell/source-map": "^0.3.2", - "acorn": "^8.5.0", + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", "commander": "^2.20.0", "source-map-support": "~0.5.20" }, @@ -2920,16 +2934,16 @@ } }, "node_modules/terser-webpack-plugin": { - "version": "5.3.8", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.8.tgz", - "integrity": "sha512-WiHL3ElchZMsK27P8uIUh4604IgJyAW47LVXGbEoB21DbQcZ+OuMpGjVYnEUaqcWM6dO8uS2qUbA7LSCWqvsbg==", + "version": "5.3.10", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", + "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", "dev": true, "dependencies": { - "@jridgewell/trace-mapping": "^0.3.17", + "@jridgewell/trace-mapping": "^0.3.20", "jest-worker": "^27.4.5", "schema-utils": "^3.1.1", "serialize-javascript": "^6.0.1", - "terser": "^5.16.8" + "terser": "^5.26.0" }, "engines": { "node": ">= 10.13.0" @@ -2974,15 +2988,16 @@ } }, "node_modules/ts-loader": { - "version": "9.4.2", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.4.2.tgz", - "integrity": "sha512-OmlC4WVmFv5I0PpaxYb+qGeGOdm5giHU7HwDDUjw59emP2UYMHy9fFSDcYgSNoH8sXcj4hGCSEhlDZ9ULeDraA==", + "version": "9.5.1", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.1.tgz", + "integrity": "sha512-rNH3sK9kGZcH9dYzC7CewQm4NtxJTjSEVRJ2DyBZR7f8/wcta+iV44UPCXc5+nzDzivKtlzV6c9P4e+oFhDLYg==", "dev": true, "dependencies": { "chalk": "^4.1.0", "enhanced-resolve": "^5.0.0", "micromatch": "^4.0.0", - "semver": "^7.3.4" + "semver": "^7.3.4", + "source-map": "^0.7.4" }, "engines": { "node": ">=12.0.0" @@ -3050,6 +3065,15 @@ "node": ">=8" } }, + "node_modules/ts-loader/node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, "node_modules/ts-loader/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -3063,22 +3087,28 @@ } }, "node_modules/typescript": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz", - "integrity": "sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==", + "version": "5.4.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.2.tgz", + "integrity": "sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==", "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" }, "engines": { - "node": ">=12.20" + "node": ">=14.17" } }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, "node_modules/update-browserslist-db": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", - "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==", + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", "dev": true, "funding": [ { @@ -3128,21 +3158,21 @@ } }, "node_modules/webpack": { - "version": "5.82.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.82.1.tgz", - "integrity": "sha512-C6uiGQJ+Gt4RyHXXYt+v9f+SN1v83x68URwgxNQ98cvH8kxiuywWGP4XeNZ1paOzZ63aY3cTciCEQJNFUljlLw==", + "version": "5.90.3", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.90.3.tgz", + "integrity": "sha512-h6uDYlWCctQRuXBs1oYpVe6sFcWedl0dpcVaTf/YF67J9bKvwJajFulMVSYKHrksMB3I/pIagRzDxwxkebuzKA==", "dev": true, "dependencies": { "@types/eslint-scope": "^3.7.3", - "@types/estree": "^1.0.0", + "@types/estree": "^1.0.5", "@webassemblyjs/ast": "^1.11.5", "@webassemblyjs/wasm-edit": "^1.11.5", "@webassemblyjs/wasm-parser": "^1.11.5", "acorn": "^8.7.1", - "acorn-import-assertions": "^1.7.6", - "browserslist": "^4.14.5", + "acorn-import-assertions": "^1.9.0", + "browserslist": "^4.21.10", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.14.0", + "enhanced-resolve": "^5.15.0", "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", @@ -3152,9 +3182,9 @@ "loader-runner": "^4.2.0", "mime-types": "^2.1.27", "neo-async": "^2.6.2", - "schema-utils": "^3.1.2", + "schema-utils": "^3.2.0", "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.3.7", + "terser-webpack-plugin": "^5.3.10", "watchpack": "^2.4.0", "webpack-sources": "^3.2.3" }, @@ -3175,15 +3205,15 @@ } }, "node_modules/webpack-cli": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.1.tgz", - "integrity": "sha512-OLJwVMoXnXYH2ncNGU8gxVpUtm3ybvdioiTvHgUyBuyMLKiVvWy+QObzBsMtp5pH7qQoEuWgeEUQ/sU3ZJFzAw==", + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz", + "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==", "dev": true, "dependencies": { "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^2.1.0", - "@webpack-cli/info": "^2.0.1", - "@webpack-cli/serve": "^2.0.4", + "@webpack-cli/configtest": "^2.1.1", + "@webpack-cli/info": "^2.0.2", + "@webpack-cli/serve": "^2.0.5", "colorette": "^2.0.14", "commander": "^10.0.1", "cross-spawn": "^7.0.3", @@ -3486,157 +3516,164 @@ "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz", "integrity": "sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==" }, + "@esbuild/aix-ppc64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz", + "integrity": "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==", + "dev": true, + "optional": true + }, "@esbuild/android-arm": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.18.tgz", - "integrity": "sha512-EmwL+vUBZJ7mhFCs5lA4ZimpUH3WMAoqvOIYhVQwdIgSpHC8ImHdsRyhHAVxpDYUSm0lWvd63z0XH1IlImS2Qw==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz", + "integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==", "dev": true, "optional": true }, "@esbuild/android-arm64": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.18.tgz", - "integrity": "sha512-/iq0aK0eeHgSC3z55ucMAHO05OIqmQehiGay8eP5l/5l+iEr4EIbh4/MI8xD9qRFjqzgkc0JkX0LculNC9mXBw==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz", + "integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==", "dev": true, "optional": true }, "@esbuild/android-x64": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.18.tgz", - "integrity": "sha512-x+0efYNBF3NPW2Xc5bFOSFW7tTXdAcpfEg2nXmxegm4mJuVeS+i109m/7HMiOQ6M12aVGGFlqJX3RhNdYM2lWg==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz", + "integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==", "dev": true, "optional": true }, "@esbuild/darwin-arm64": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.18.tgz", - "integrity": "sha512-6tY+djEAdF48M1ONWnQb1C+6LiXrKjmqjzPNPWXhu/GzOHTHX2nh8Mo2ZAmBFg0kIodHhciEgUBtcYCAIjGbjQ==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz", + "integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==", "dev": true, "optional": true }, "@esbuild/darwin-x64": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.18.tgz", - "integrity": "sha512-Qq84ykvLvya3dO49wVC9FFCNUfSrQJLbxhoQk/TE1r6MjHo3sFF2tlJCwMjhkBVq3/ahUisj7+EpRSz0/+8+9A==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz", + "integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==", "dev": true, "optional": true }, "@esbuild/freebsd-arm64": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.18.tgz", - "integrity": "sha512-fw/ZfxfAzuHfaQeMDhbzxp9mc+mHn1Y94VDHFHjGvt2Uxl10mT4CDavHm+/L9KG441t1QdABqkVYwakMUeyLRA==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz", + "integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==", "dev": true, "optional": true }, "@esbuild/freebsd-x64": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.18.tgz", - "integrity": "sha512-FQFbRtTaEi8ZBi/A6kxOC0V0E9B/97vPdYjY9NdawyLd4Qk5VD5g2pbWN2VR1c0xhzcJm74HWpObPszWC+qTew==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz", + "integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==", "dev": true, "optional": true }, "@esbuild/linux-arm": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.18.tgz", - "integrity": "sha512-jW+UCM40LzHcouIaqv3e/oRs0JM76JfhHjCavPxMUti7VAPh8CaGSlS7cmyrdpzSk7A+8f0hiedHqr/LMnfijg==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz", + "integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==", "dev": true, "optional": true }, "@esbuild/linux-arm64": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.18.tgz", - "integrity": "sha512-R7pZvQZFOY2sxUG8P6A21eq6q+eBv7JPQYIybHVf1XkQYC+lT7nDBdC7wWKTrbvMXKRaGudp/dzZCwL/863mZQ==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz", + "integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==", "dev": true, "optional": true }, "@esbuild/linux-ia32": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.18.tgz", - "integrity": "sha512-ygIMc3I7wxgXIxk6j3V00VlABIjq260i967Cp9BNAk5pOOpIXmd1RFQJQX9Io7KRsthDrQYrtcx7QCof4o3ZoQ==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz", + "integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==", "dev": true, "optional": true }, "@esbuild/linux-loong64": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.18.tgz", - "integrity": "sha512-bvPG+MyFs5ZlwYclCG1D744oHk1Pv7j8psF5TfYx7otCVmcJsEXgFEhQkbhNW8otDHL1a2KDINW20cfCgnzgMQ==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz", + "integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==", "dev": true, "optional": true }, "@esbuild/linux-mips64el": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.18.tgz", - "integrity": "sha512-oVqckATOAGuiUOa6wr8TXaVPSa+6IwVJrGidmNZS1cZVx0HqkTMkqFGD2HIx9H1RvOwFeWYdaYbdY6B89KUMxA==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz", + "integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==", "dev": true, "optional": true }, "@esbuild/linux-ppc64": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.18.tgz", - "integrity": "sha512-3dLlQO+b/LnQNxgH4l9rqa2/IwRJVN9u/bK63FhOPB4xqiRqlQAU0qDU3JJuf0BmaH0yytTBdoSBHrb2jqc5qQ==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz", + "integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==", "dev": true, "optional": true }, "@esbuild/linux-riscv64": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.18.tgz", - "integrity": "sha512-/x7leOyDPjZV3TcsdfrSI107zItVnsX1q2nho7hbbQoKnmoeUWjs+08rKKt4AUXju7+3aRZSsKrJtaRmsdL1xA==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz", + "integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==", "dev": true, "optional": true }, "@esbuild/linux-s390x": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.18.tgz", - "integrity": "sha512-cX0I8Q9xQkL/6F5zWdYmVf5JSQt+ZfZD2bJudZrWD+4mnUvoZ3TDDXtDX2mUaq6upMFv9FlfIh4Gfun0tbGzuw==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz", + "integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==", "dev": true, "optional": true }, "@esbuild/linux-x64": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.18.tgz", - "integrity": "sha512-66RmRsPlYy4jFl0vG80GcNRdirx4nVWAzJmXkevgphP1qf4dsLQCpSKGM3DUQCojwU1hnepI63gNZdrr02wHUA==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz", + "integrity": "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==", "dev": true, "optional": true }, "@esbuild/netbsd-x64": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.18.tgz", - "integrity": "sha512-95IRY7mI2yrkLlTLb1gpDxdC5WLC5mZDi+kA9dmM5XAGxCME0F8i4bYH4jZreaJ6lIZ0B8hTrweqG1fUyW7jbg==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz", + "integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==", "dev": true, "optional": true }, "@esbuild/openbsd-x64": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.18.tgz", - "integrity": "sha512-WevVOgcng+8hSZ4Q3BKL3n1xTv5H6Nb53cBrtzzEjDbbnOmucEVcZeGCsCOi9bAOcDYEeBZbD2SJNBxlfP3qiA==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz", + "integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==", "dev": true, "optional": true }, "@esbuild/sunos-x64": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.18.tgz", - "integrity": "sha512-Rzf4QfQagnwhQXVBS3BYUlxmEbcV7MY+BH5vfDZekU5eYpcffHSyjU8T0xucKVuOcdCsMo+Ur5wmgQJH2GfNrg==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz", + "integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==", "dev": true, "optional": true }, "@esbuild/win32-arm64": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.18.tgz", - "integrity": "sha512-Kb3Ko/KKaWhjeAm2YoT/cNZaHaD1Yk/pa3FTsmqo9uFh1D1Rfco7BBLIPdDOozrObj2sahslFuAQGvWbgWldAg==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz", + "integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==", "dev": true, "optional": true }, "@esbuild/win32-ia32": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.18.tgz", - "integrity": "sha512-0/xUMIdkVHwkvxfbd5+lfG7mHOf2FRrxNbPiKWg9C4fFrB8H0guClmaM3BFiRUYrznVoyxTIyC/Ou2B7QQSwmw==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz", + "integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==", "dev": true, "optional": true }, "@esbuild/win32-x64": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.18.tgz", - "integrity": "sha512-qU25Ma1I3NqTSHJUOKi9sAH1/Mzuvlke0ioMJRthLXKm7JiSKVwFghlGbDLOO2sARECGhja4xYfRAZNPAkooYg==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz", + "integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==", "dev": true, "optional": true }, @@ -3671,32 +3708,32 @@ "integrity": "sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q==" }, "@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "dev": true, "requires": { - "@jridgewell/set-array": "^1.0.1", + "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/trace-mapping": "^0.3.24" } }, "@jridgewell/resolve-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "dev": true }, "@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", "dev": true }, "@jridgewell/source-map": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.3.tgz", - "integrity": "sha512-b+fsZXeLYi9fEULmfBrhxn4IrPlINf8fiNarzTof004v3lFdntdwa9PF7vFJqm3mg7s+ScJMxXaE3Acp1irZcg==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", + "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", "dev": true, "requires": { "@jridgewell/gen-mapping": "^0.3.0", @@ -3710,32 +3747,24 @@ "dev": true }, "@jridgewell/trace-mapping": { - "version": "0.3.18", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", - "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dev": true, "requires": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" - }, - "dependencies": { - "@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "dev": true - } + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, "@mui/base": { - "version": "5.0.0-beta.37", - "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.37.tgz", - "integrity": "sha512-/o3anbb+DeCng8jNsd3704XtmmLDZju1Fo8R2o7ugrVtPQ/QpcqddwKNzKPZwa0J5T8YNW3ZVuHyQgbTnQLisQ==", + "version": "5.0.0-beta.38", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.38.tgz", + "integrity": "sha512-AsjD6Y1X5A1qndxz8xCcR8LDqv31aiwlgWMPxFAX/kCKiIGKlK65yMeVZ62iQr/6LBz+9hSKLiD1i4TZdAHKcQ==", "requires": { "@babel/runtime": "^7.23.9", "@floating-ui/react-dom": "^2.0.8", "@mui/types": "^7.2.13", - "@mui/utils": "^5.15.11", + "@mui/utils": "^5.15.12", "@popperjs/core": "^2.11.8", "clsx": "^2.1.0", "prop-types": "^15.8.1" @@ -3749,28 +3778,28 @@ } }, "@mui/core-downloads-tracker": { - "version": "5.15.11", - "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.15.11.tgz", - "integrity": "sha512-JVrJ9Jo4gyU707ujnRzmE8ABBWpXd6FwL9GYULmwZRtfPg89ggXs/S3MStQkpJ1JRWfdLL6S5syXmgQGq5EDAw==" + "version": "5.15.12", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.15.12.tgz", + "integrity": "sha512-brRO+tMFLpGyjEYHrX97bzqeF6jZmKpqqe1rY0LyIHAwP6xRVzh++zSecOQorDOCaZJg4XkGT9xfD+RWOWxZBA==" }, "@mui/icons-material": { - "version": "5.15.11", - "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.15.11.tgz", - "integrity": "sha512-R5ZoQqnKpd+5Ew7mBygTFLxgYsQHPhgR3TDXSgIHYIjGzYuyPLmGLSdcPUoMdi6kxiYqHlpPj4NJxlbaFD0UHA==", + "version": "5.15.12", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.15.12.tgz", + "integrity": "sha512-3BXiDlOd3AexZoEXa/VqpIpVIvosCzjLHsdMWzKMXbZdnBiJjmb9ECdqfjn5SpTClO49qvkKLhkTqdBH3fSFGw==", "requires": { "@babel/runtime": "^7.23.9" } }, "@mui/lab": { - "version": "5.0.0-alpha.166", - "resolved": "https://registry.npmjs.org/@mui/lab/-/lab-5.0.0-alpha.166.tgz", - "integrity": "sha512-a+0yorrgxLIgfKhShVKQk0/5CnB4KBhMQ64SvEB+CsvKAKKJzjIU43m2nMqdBbWzfnEuj6wR9vQ9kambdn3ZKA==", + "version": "5.0.0-alpha.167", + "resolved": "https://registry.npmjs.org/@mui/lab/-/lab-5.0.0-alpha.167.tgz", + "integrity": "sha512-BNQJ7fBBvL68WGVnzAhbtTmabSuJDXaILr9dz/3RNK4TgGXPgWCAr7qtJeUdc4p1t7c4Z1ifG8UwgqD+5hzMNg==", "requires": { "@babel/runtime": "^7.23.9", - "@mui/base": "5.0.0-beta.37", - "@mui/system": "^5.15.11", + "@mui/base": "5.0.0-beta.38", + "@mui/system": "^5.15.12", "@mui/types": "^7.2.13", - "@mui/utils": "^5.15.11", + "@mui/utils": "^5.15.12", "clsx": "^2.1.0", "prop-types": "^15.8.1" }, @@ -3783,16 +3812,16 @@ } }, "@mui/material": { - "version": "5.15.11", - "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.15.11.tgz", - "integrity": "sha512-FA3eEuEZaDaxgN3CgfXezMWbCZ4VCeU/sv0F0/PK5n42qIgsPVD6q+j71qS7/62sp6wRFMHtDMpXRlN+tT/7NA==", + "version": "5.15.12", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.15.12.tgz", + "integrity": "sha512-vXJGg6KNKucsvbW6l7w9zafnpOp0CWc0Wx4mDykuABTpQ5QQBnZxP7+oB4yAS1hDZQ1WobbeIl0CjxK4EEahkA==", "requires": { "@babel/runtime": "^7.23.9", - "@mui/base": "5.0.0-beta.37", - "@mui/core-downloads-tracker": "^5.15.11", - "@mui/system": "^5.15.11", + "@mui/base": "5.0.0-beta.38", + "@mui/core-downloads-tracker": "^5.15.12", + "@mui/system": "^5.15.12", "@mui/types": "^7.2.13", - "@mui/utils": "^5.15.11", + "@mui/utils": "^5.15.12", "@types/react-transition-group": "^4.4.10", "clsx": "^2.1.0", "csstype": "^3.1.3", @@ -3809,12 +3838,12 @@ } }, "@mui/private-theming": { - "version": "5.15.11", - "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.15.11.tgz", - "integrity": "sha512-jY/696SnSxSzO1u86Thym7ky5T9CgfidU3NFJjguldqK4f3Z5S97amZ6nffg8gTD0HBjY9scB+4ekqDEUmxZOA==", + "version": "5.15.12", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.15.12.tgz", + "integrity": "sha512-cqoSo9sgA5HE+8vZClbLrq9EkyOnYysooepi5eKaKvJ41lReT2c5wOZAeDDM1+xknrMDos+0mT2zr3sZmUiRRA==", "requires": { "@babel/runtime": "^7.23.9", - "@mui/utils": "^5.15.11", + "@mui/utils": "^5.15.12", "prop-types": "^15.8.1" } }, @@ -3830,15 +3859,15 @@ } }, "@mui/system": { - "version": "5.15.11", - "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.15.11.tgz", - "integrity": "sha512-9j35suLFq+MgJo5ktVSHPbkjDLRMBCV17NMBdEQurh6oWyGnLM4uhU4QGZZQ75o0vuhjJghOCA1jkO3+79wKsA==", + "version": "5.15.12", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.15.12.tgz", + "integrity": "sha512-/pq+GO6yN3X7r3hAwFTrzkAh7K1bTF5r8IzS79B9eyKJg7v6B/t4/zZYMR6OT9qEPtwf6rYN2Utg1e6Z7F1OgQ==", "requires": { "@babel/runtime": "^7.23.9", - "@mui/private-theming": "^5.15.11", + "@mui/private-theming": "^5.15.12", "@mui/styled-engine": "^5.15.11", "@mui/types": "^7.2.13", - "@mui/utils": "^5.15.11", + "@mui/utils": "^5.15.12", "clsx": "^2.1.0", "csstype": "^3.1.3", "prop-types": "^15.8.1" @@ -3858,9 +3887,9 @@ "requires": {} }, "@mui/utils": { - "version": "5.15.11", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.15.11.tgz", - "integrity": "sha512-D6bwqprUa9Stf8ft0dcMqWyWDKEo7D+6pB1k8WajbqlYIRA8J8Kw9Ra7PSZKKePGBGWO+/xxrX1U8HpG/aXQCw==", + "version": "5.15.12", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.15.12.tgz", + "integrity": "sha512-8SDGCnO2DY9Yy+5bGzu00NZowSDtuyHP4H8gunhHGQoIlhlY2Z3w64wBzAOLpYw/ZhJNzksDTnS/i8qdJvxuow==", "requires": { "@babel/runtime": "^7.23.9", "@types/prop-types": "^15.7.11", @@ -3874,9 +3903,9 @@ "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==" }, "@remix-run/router": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.6.0.tgz", - "integrity": "sha512-N13NRw3T2+6Xi9J//3CGLsK2OqC8NMme3d/YX+nh05K9YHWGcv8DycHJrqGScSP4T75o8IN6nqIMhVFU8ohg8w==" + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.15.2.tgz", + "integrity": "sha512-+Rnav+CaoTE5QJc4Jcwh5toUpnVLKYbpU6Ys0zqbakqbaLQHeglLVHPfxOiQqdNmUy5C2lXz5dwC6tQNX2JW2Q==" }, "@sqlite.org/sqlite-wasm": { "version": "3.45.1-build1", @@ -3904,9 +3933,9 @@ } }, "@types/estree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", - "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", "dev": true }, "@types/history": { @@ -3922,10 +3951,13 @@ "dev": true }, "@types/node": { - "version": "20.1.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.1.3.tgz", - "integrity": "sha512-NP2yfZpgmf2eDRPmgGq+fjGjSwFgYbihA8/gK+ey23qT9RkxsgNTZvGOEpXgzIGqesTYkElELLgtKoMQTys5vA==", - "dev": true + "version": "20.11.25", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.25.tgz", + "integrity": "sha512-TBHyJxk2b7HceLVGFcpAUjsa5zIdsPWlR6XHfyGzd0SFu+/NFgQgMAl96MSDZgQDvJAvV6BKsFOrt6zIL09JDw==", + "dev": true, + "requires": { + "undici-types": "~5.26.4" + } }, "@types/parse-json": { "version": "4.0.2", @@ -3933,9 +3965,9 @@ "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==" }, "@types/plotly.js": { - "version": "2.12.18", - "resolved": "https://registry.npmjs.org/@types/plotly.js/-/plotly.js-2.12.18.tgz", - "integrity": "sha512-ff+CIEWnqZNjZqHtQZvkEAVuLs9fkm1f54QnPVmgoET7wMHdSqUka2hasVN4e5yfHD05YwGjsAtCseewJh/BMw==", + "version": "2.29.2", + "resolved": "https://registry.npmjs.org/@types/plotly.js/-/plotly.js-2.29.2.tgz", + "integrity": "sha512-tJqUVa6CmNHrzTANWO/ZLNmdvjZ6zHOAnM9iQUORVnnLvWmcO9DPdQCsrNumNvHD1aqGNxQJ8pla8CK/NUiZgA==", "dev": true }, "@types/prop-types": { @@ -3944,9 +3976,9 @@ "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==" }, "@types/react": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.0.tgz", - "integrity": "sha512-0FLj93y5USLHdnhIhABk83rm8XEGA7kH3cr+YUlvxoUGp1xNt/DINUMvqPxLyOQMzLmZe8i4RTHbvb8MC7NmrA==", + "version": "18.2.64", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.64.tgz", + "integrity": "sha512-MlmPvHgjj2p3vZaxbQgFUQFvD8QiZwACfGqEdDSWou5yISWxDQ4/74nCAwsUiX7UFLKZz3BbVSPj+YxeoGGCfg==", "requires": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -3954,9 +3986,9 @@ } }, "@types/react-dom": { - "version": "18.2.1", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.1.tgz", - "integrity": "sha512-8QZEV9+Kwy7tXFmjJrp3XUKQSs9LTnE0KnoUb0YCguWBiNW0Yfb2iBMYZ08WPg35IR6P3Z0s00B15SwZnO26+w==", + "version": "18.2.21", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.21.tgz", + "integrity": "sha512-gnvBA/21SA4xxqNXEwNiVcP0xSGHh/gi1VhWv9Bl46a0ItbTT5nFY+G9VSQpaG/8N/qdJpJ+vftQ4zflTtnjLw==", "dev": true, "requires": { "@types/react": "*" @@ -4143,23 +4175,23 @@ } }, "@webpack-cli/configtest": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.0.tgz", - "integrity": "sha512-K/vuv72vpfSEZoo5KIU0a2FsEoYdW0DUMtMpB5X3LlUwshetMZRZRxB7sCsVji/lFaSxtQQ3aM9O4eMolXkU9w==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.1.tgz", + "integrity": "sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==", "dev": true, "requires": {} }, "@webpack-cli/info": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.1.tgz", - "integrity": "sha512-fE1UEWTwsAxRhrJNikE7v4EotYflkEhBL7EbajfkPlf6E37/2QshOy/D48Mw8G5XMFlQtS6YV42vtbG9zBpIQA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.2.tgz", + "integrity": "sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==", "dev": true, "requires": {} }, "@webpack-cli/serve": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.4.tgz", - "integrity": "sha512-0xRgjgDLdz6G7+vvDLlaRpFatJaJ69uTalZLRSMX5B3VUrDmXcrVA3+6fXXQgmYz7bY9AAgs348XQdmtLsK41A==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.5.tgz", + "integrity": "sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==", "dev": true, "requires": {} }, @@ -4270,15 +4302,15 @@ } }, "browserslist": { - "version": "4.21.5", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz", - "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==", + "version": "4.23.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", + "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001449", - "electron-to-chromium": "^1.4.284", - "node-releases": "^2.0.8", - "update-browserslist-db": "^1.0.10" + "caniuse-lite": "^1.0.30001587", + "electron-to-chromium": "^1.4.668", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" } }, "buffer-from": { @@ -4293,9 +4325,9 @@ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" }, "caniuse-lite": { - "version": "1.0.30001481", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001481.tgz", - "integrity": "sha512-KCqHwRnaa1InZBtqXzP98LPg0ajCVujMKjqKDhZEthIpAsJl/YEIa3YvXjGXPVqzZVguccuu7ga9KOE1J9rKPQ==", + "version": "1.0.30001596", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001596.tgz", + "integrity": "sha512-zpkZ+kEr6We7w63ORkoJ2pOfBwBkY/bJrG/UZ90qNb45Isblu8wzDgevEOrRL1r9dWayHjYiiyCMEXPn4DweGQ==", "dev": true }, "chalk": { @@ -4363,13 +4395,13 @@ "dev": true }, "compression-webpack-plugin": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/compression-webpack-plugin/-/compression-webpack-plugin-10.0.0.tgz", - "integrity": "sha512-wLXLIBwpul/ALcm7Aj+69X0pYT3BYt6DdPn3qrgBIh9YejV9Bju9ShhlAsjujLyWMo6SAweFIWaUoFmXZNuNrg==", + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/compression-webpack-plugin/-/compression-webpack-plugin-11.1.0.tgz", + "integrity": "sha512-zDOQYp10+upzLxW+VRSjEpRRwBXJdsb5lBMlRxx1g8hckIFBpe3DTI0en2w7h+beuq89576RVzfiXrkdPGrHhA==", "dev": true, "requires": { - "schema-utils": "^4.0.0", - "serialize-javascript": "^6.0.0" + "schema-utils": "^4.2.0", + "serialize-javascript": "^6.0.2" }, "dependencies": { "ajv": { @@ -4456,9 +4488,9 @@ } }, "electron-to-chromium": { - "version": "1.4.372", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.372.tgz", - "integrity": "sha512-MrlFq/j+TYHOjeWsWGYfzevc25HNeJdsF6qaLFrqBTRWZQtWkb1myq/Q2veLWezVaa5OcSZ99CFwTT4aF4Mung==", + "version": "1.4.695", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.695.tgz", + "integrity": "sha512-eMijZmeqPtm774pCZIOrfUHMs/7ls++W1sLhxwqgu8KQ8E2WmMtzwyqOMt0XXUJ3HTIPfuwlfwF+I5cwnfItBA==", "dev": true }, "emojis-list": { @@ -4468,9 +4500,9 @@ "dev": true }, "enhanced-resolve": { - "version": "5.14.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.14.0.tgz", - "integrity": "sha512-+DCows0XNwLDcUhbFJPdlQEVnT2zXlCv7hPxemTz86/O+B/hCQ+mb7ydkPKiflpVraqLPCAfu7lDy+hBXueojw==", + "version": "5.15.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.1.tgz", + "integrity": "sha512-3d3JRbwsCLJsYgvb6NuWEG44jjPSOMuS73L/6+7BZuoKm3W+qXnSoIYVHi8dG7Qcg4inAY4jbzkZ7MnskePeDg==", "dev": true, "requires": { "graceful-fs": "^4.2.4", @@ -4498,51 +4530,52 @@ "dev": true }, "esbuild": { - "version": "0.17.18", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.18.tgz", - "integrity": "sha512-z1lix43jBs6UKjcZVKOw2xx69ffE2aG0PygLL5qJ9OS/gy0Ewd1gW/PUQIOIQGXBHWNywSc0floSKoMFF8aK2w==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz", + "integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==", "dev": true, "requires": { - "@esbuild/android-arm": "0.17.18", - "@esbuild/android-arm64": "0.17.18", - "@esbuild/android-x64": "0.17.18", - "@esbuild/darwin-arm64": "0.17.18", - "@esbuild/darwin-x64": "0.17.18", - "@esbuild/freebsd-arm64": "0.17.18", - "@esbuild/freebsd-x64": "0.17.18", - "@esbuild/linux-arm": "0.17.18", - "@esbuild/linux-arm64": "0.17.18", - "@esbuild/linux-ia32": "0.17.18", - "@esbuild/linux-loong64": "0.17.18", - "@esbuild/linux-mips64el": "0.17.18", - "@esbuild/linux-ppc64": "0.17.18", - "@esbuild/linux-riscv64": "0.17.18", - "@esbuild/linux-s390x": "0.17.18", - "@esbuild/linux-x64": "0.17.18", - "@esbuild/netbsd-x64": "0.17.18", - "@esbuild/openbsd-x64": "0.17.18", - "@esbuild/sunos-x64": "0.17.18", - "@esbuild/win32-arm64": "0.17.18", - "@esbuild/win32-ia32": "0.17.18", - "@esbuild/win32-x64": "0.17.18" + "@esbuild/aix-ppc64": "0.19.12", + "@esbuild/android-arm": "0.19.12", + "@esbuild/android-arm64": "0.19.12", + "@esbuild/android-x64": "0.19.12", + "@esbuild/darwin-arm64": "0.19.12", + "@esbuild/darwin-x64": "0.19.12", + "@esbuild/freebsd-arm64": "0.19.12", + "@esbuild/freebsd-x64": "0.19.12", + "@esbuild/linux-arm": "0.19.12", + "@esbuild/linux-arm64": "0.19.12", + "@esbuild/linux-ia32": "0.19.12", + "@esbuild/linux-loong64": "0.19.12", + "@esbuild/linux-mips64el": "0.19.12", + "@esbuild/linux-ppc64": "0.19.12", + "@esbuild/linux-riscv64": "0.19.12", + "@esbuild/linux-s390x": "0.19.12", + "@esbuild/linux-x64": "0.19.12", + "@esbuild/netbsd-x64": "0.19.12", + "@esbuild/openbsd-x64": "0.19.12", + "@esbuild/sunos-x64": "0.19.12", + "@esbuild/win32-arm64": "0.19.12", + "@esbuild/win32-ia32": "0.19.12", + "@esbuild/win32-x64": "0.19.12" } }, "esbuild-loader": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/esbuild-loader/-/esbuild-loader-3.0.1.tgz", - "integrity": "sha512-aZfGybqTeuyCd4AsVvWOOfkhIuN+wfZFjMyh3gyQEU1Uvsl8L6vye9HqP93iRa0iTA+6Jclap514PJIC3cLnMA==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/esbuild-loader/-/esbuild-loader-4.0.3.tgz", + "integrity": "sha512-YpaSRisj7TSg6maKKKG9OJGGm0BZ7EXeov8J8cXEYdugjlAJ0wL7aj2JactoQvPJ113v2Ar204pdJWrZsAQc8Q==", "dev": true, "requires": { - "esbuild": "^0.17.6", - "get-tsconfig": "^4.4.0", + "esbuild": "^0.19.0", + "get-tsconfig": "^4.7.0", "loader-utils": "^2.0.4", "webpack-sources": "^1.4.3" } }, "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", "dev": true }, "escape-string-regexp": { @@ -4637,10 +4670,13 @@ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, "get-tsconfig": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.5.0.tgz", - "integrity": "sha512-MjhiaIWCJ1sAU4pIQ5i5OfOuHHxVo1oYeNsWTON7jxYkod8pHocXeh+SSbmu5OZZZK73B6cbJ2XADzXehLyovQ==", - "dev": true + "version": "4.7.3", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.3.tgz", + "integrity": "sha512-ZvkrzoUA0PQZM6fy6+/Hce561s+faD1rsNwhnO5FelNjyy7EMGJ3Rz1AQ8GYDWjhRs/7dBLOEJvhK8MiEJOAFg==", + "dev": true, + "requires": { + "resolve-pkg-maps": "^1.0.0" + } }, "glob-to-regexp": { "version": "0.4.1", @@ -4905,9 +4941,9 @@ "dev": true }, "node-releases": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz", - "integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==", + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", "dev": true }, "notistack": { @@ -5014,15 +5050,9 @@ } }, "plotly.js-dist-min": { - "version": "2.29.1", - "resolved": "https://registry.npmjs.org/plotly.js-dist-min/-/plotly.js-dist-min-2.29.1.tgz", - "integrity": "sha512-YvqX5TISWsJVTDIaUh2Qgt9uhLl0bWcQhO2rLPF0/hIY9BlinFa1JwSO2jFKcEmG0AJXSo4DnVdgKpsk9/8Apg==" - }, - "prettier": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", - "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", - "dev": true + "version": "2.30.0", + "resolved": "https://registry.npmjs.org/plotly.js-dist-min/-/plotly.js-dist-min-2.30.0.tgz", + "integrity": "sha512-LM7v0H8MZUNnOT0WmJt8apvXnrjytUgxvG9RAcGT2AsJNlCxLGMMFYQS5TEiYNRH96/hcV8KGQmw+NwjmXSFSA==" }, "prop-types": { "version": "15.8.1", @@ -5079,20 +5109,20 @@ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" }, "react-router": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.11.0.tgz", - "integrity": "sha512-hTm6KKNpj9SDG4syIWRjCU219O0RZY8RUPobCFt9p+PlF7nnkRgMoh2DieTKvw3F3Mw6zg565HGnSv8BuoY5oQ==", + "version": "6.22.2", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.22.2.tgz", + "integrity": "sha512-YD3Dzprzpcq+tBMHBS822tCjnWD3iIZbTeSXMY9LPSG541EfoBGyZ3bS25KEnaZjLcmQpw2AVLkFyfgXY8uvcw==", "requires": { - "@remix-run/router": "1.6.0" + "@remix-run/router": "1.15.2" } }, "react-router-dom": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.11.0.tgz", - "integrity": "sha512-Q3mK1c/CYoF++J6ZINz7EZzwlgSOZK/kc7lxIA7PhtWhKju4KfF1WHqlx0kVCIFJAWztuYVpXZeljEbds8z4Og==", + "version": "6.22.2", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.22.2.tgz", + "integrity": "sha512-WgqxD2qySEIBPZ3w0sHH+PUAiamDeszls9tzqMPBDA1YYVucTBXLU7+gtRfcSnhe92A3glPnvSxK2dhNoAVOIQ==", "requires": { - "@remix-run/router": "1.6.0", - "react-router": "6.11.0" + "@remix-run/router": "1.15.2", + "react-router": "6.22.2" } }, "react-transition-group": { @@ -5166,6 +5196,12 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" }, + "resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true + }, "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -5181,9 +5217,9 @@ } }, "schema-utils": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.2.tgz", - "integrity": "sha512-pvjEHOgWc9OWA/f/DE3ohBWTD6EleVLf7iFUkoSwAxttdBhB9QUebQgxER2kWueOvRJXPHNnyrvvh9eZINB8Eg==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", "dev": true, "requires": { "@types/json-schema": "^7.0.8", @@ -5201,9 +5237,9 @@ } }, "serialize-javascript": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", - "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", "dev": true, "requires": { "randombytes": "^2.1.0" @@ -5287,28 +5323,28 @@ "dev": true }, "terser": { - "version": "5.17.3", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.17.3.tgz", - "integrity": "sha512-AudpAZKmZHkG9jueayypz4duuCFJMMNGRMwaPvQKWfxKedh8Z2x3OCoDqIIi1xx5+iwx1u6Au8XQcc9Lke65Yg==", + "version": "5.29.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.29.1.tgz", + "integrity": "sha512-lZQ/fyaIGxsbGxApKmoPTODIzELy3++mXhS5hOqaAWZjQtpq/hFHAc+rm29NND1rYRxRWKcjuARNwULNXa5RtQ==", "dev": true, "requires": { - "@jridgewell/source-map": "^0.3.2", - "acorn": "^8.5.0", + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", "commander": "^2.20.0", "source-map-support": "~0.5.20" } }, "terser-webpack-plugin": { - "version": "5.3.8", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.8.tgz", - "integrity": "sha512-WiHL3ElchZMsK27P8uIUh4604IgJyAW47LVXGbEoB21DbQcZ+OuMpGjVYnEUaqcWM6dO8uS2qUbA7LSCWqvsbg==", + "version": "5.3.10", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", + "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", "dev": true, "requires": { - "@jridgewell/trace-mapping": "^0.3.17", + "@jridgewell/trace-mapping": "^0.3.20", "jest-worker": "^27.4.5", "schema-utils": "^3.1.1", "serialize-javascript": "^6.0.1", - "terser": "^5.16.8" + "terser": "^5.26.0" } }, "to-fast-properties": { @@ -5326,15 +5362,16 @@ } }, "ts-loader": { - "version": "9.4.2", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.4.2.tgz", - "integrity": "sha512-OmlC4WVmFv5I0PpaxYb+qGeGOdm5giHU7HwDDUjw59emP2UYMHy9fFSDcYgSNoH8sXcj4hGCSEhlDZ9ULeDraA==", + "version": "9.5.1", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.1.tgz", + "integrity": "sha512-rNH3sK9kGZcH9dYzC7CewQm4NtxJTjSEVRJ2DyBZR7f8/wcta+iV44UPCXc5+nzDzivKtlzV6c9P4e+oFhDLYg==", "dev": true, "requires": { "chalk": "^4.1.0", "enhanced-resolve": "^5.0.0", "micromatch": "^4.0.0", - "semver": "^7.3.4" + "semver": "^7.3.4", + "source-map": "^0.7.4" }, "dependencies": { "ansi-styles": { @@ -5377,6 +5414,12 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, + "source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "dev": true + }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -5389,15 +5432,21 @@ } }, "typescript": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz", - "integrity": "sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==", + "version": "5.4.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.2.tgz", + "integrity": "sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==", + "dev": true + }, + "undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", "dev": true }, "update-browserslist-db": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", - "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==", + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", "dev": true, "requires": { "escalade": "^3.1.1", @@ -5424,21 +5473,21 @@ } }, "webpack": { - "version": "5.82.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.82.1.tgz", - "integrity": "sha512-C6uiGQJ+Gt4RyHXXYt+v9f+SN1v83x68URwgxNQ98cvH8kxiuywWGP4XeNZ1paOzZ63aY3cTciCEQJNFUljlLw==", + "version": "5.90.3", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.90.3.tgz", + "integrity": "sha512-h6uDYlWCctQRuXBs1oYpVe6sFcWedl0dpcVaTf/YF67J9bKvwJajFulMVSYKHrksMB3I/pIagRzDxwxkebuzKA==", "dev": true, "requires": { "@types/eslint-scope": "^3.7.3", - "@types/estree": "^1.0.0", + "@types/estree": "^1.0.5", "@webassemblyjs/ast": "^1.11.5", "@webassemblyjs/wasm-edit": "^1.11.5", "@webassemblyjs/wasm-parser": "^1.11.5", "acorn": "^8.7.1", - "acorn-import-assertions": "^1.7.6", - "browserslist": "^4.14.5", + "acorn-import-assertions": "^1.9.0", + "browserslist": "^4.21.10", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.14.0", + "enhanced-resolve": "^5.15.0", "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", @@ -5448,9 +5497,9 @@ "loader-runner": "^4.2.0", "mime-types": "^2.1.27", "neo-async": "^2.6.2", - "schema-utils": "^3.1.2", + "schema-utils": "^3.2.0", "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.3.7", + "terser-webpack-plugin": "^5.3.10", "watchpack": "^2.4.0", "webpack-sources": "^3.2.3" }, @@ -5464,15 +5513,15 @@ } }, "webpack-cli": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.1.tgz", - "integrity": "sha512-OLJwVMoXnXYH2ncNGU8gxVpUtm3ybvdioiTvHgUyBuyMLKiVvWy+QObzBsMtp5pH7qQoEuWgeEUQ/sU3ZJFzAw==", + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz", + "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==", "dev": true, "requires": { "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^2.1.0", - "@webpack-cli/info": "^2.0.1", - "@webpack-cli/serve": "^2.0.4", + "@webpack-cli/configtest": "^2.1.1", + "@webpack-cli/info": "^2.0.2", + "@webpack-cli/serve": "^2.0.5", "colorette": "^2.0.14", "commander": "^10.0.1", "cross-spawn": "^7.0.3", diff --git a/standalone_app/package.json b/standalone_app/package.json index fb890c21..ebb7c15f 100644 --- a/standalone_app/package.json +++ b/standalone_app/package.json @@ -10,32 +10,31 @@ "build:prd": "NODE_ENV=production webpack" }, "devDependencies": { - "@types/plotly.js": "^2.12.18", - "@types/react": "^18.2.0", - "@types/react-dom": "^18.2.1", + "@types/plotly.js": "^2.29.2", + "@types/react": "^18.2.64", + "@types/react-dom": "^18.2.21", "@types/react-router-dom": "^5.3.3", - "compression-webpack-plugin": "^10.0.0", - "esbuild-loader": "^3.0.1", - "prettier": "^2.8.8", - "ts-loader": "^9.4.2", - "typescript": "^5.0.4", - "webpack": "^5.82.1", - "webpack-cli": "^5.1.1" + "compression-webpack-plugin": "^11.1.0", + "esbuild-loader": "^4.0.3", + "ts-loader": "^9.5.1", + "typescript": "^5.4.2", + "webpack": "^5.90.3", + "webpack-cli": "^5.1.4" }, "dependencies": { "@emotion/react": "^11.11.3", "@emotion/styled": "^11.11.0", - "@mui/icons-material": "^5.15.6", - "@mui/lab": "^5.0.0-alpha.162", - "@mui/material": "^5.15.6", + "@mui/icons-material": "^5.15.12", + "@mui/lab": "^5.0.0-alpha.167", + "@mui/material": "^5.15.12", "@sqlite.org/sqlite-wasm": "^3.45.1-build1", "module-workers-polyfill": "^0.3.2", "notistack": "^3.0.1", "optuna": "../rustlib/pkg", - "plotly.js-dist-min": "^2.28.0", + "plotly.js-dist-min": "^2.30.0", "react": "^18.2.0", "react-dom": "^18.2.0", - "react-router-dom": "^6.11.0", + "react-router-dom": "^6.22.2", "recoil": "^0.7.7" } } From 6f0f783dab88271d1de5dae6cebe90010a43fd1f Mon Sep 17 00:00:00 2001 From: c-bata Date: Fri, 8 Mar 2024 01:41:41 +0900 Subject: [PATCH 67/98] Migrate to Vite on standalone app --- .github/workflows/e2e-standalone-tests.yml | 5 +- .github/workflows/gh-pages.yml | 11 +- .gitignore | 1 - Makefile | 18 +- e2e_tests/test_server.py | 2 +- standalone_app/github-pages.html | 19 - standalone_app/index.html | 9 +- standalone_app/package-lock.json | 1540 +++++++++++++++----- standalone_app/package.json | 10 +- standalone_app/{ => public}/favicon.ico | Bin standalone_app/vite.config.js | 18 + standalone_app/webpack.config.js | 133 +- 12 files changed, 1281 insertions(+), 485 deletions(-) delete mode 100644 standalone_app/github-pages.html rename standalone_app/{ => public}/favicon.ico (100%) create mode 100644 standalone_app/vite.config.js diff --git a/.github/workflows/e2e-standalone-tests.yml b/.github/workflows/e2e-standalone-tests.yml index 501e233a..ade4472e 100644 --- a/.github/workflows/e2e-standalone-tests.yml +++ b/.github/workflows/e2e-standalone-tests.yml @@ -42,7 +42,10 @@ jobs: python -m pip install --progress-bar off pytest-playwright==0.4.3 # next version is flaky - name: Build standalone_app - run: make MODE="prd" standalone_app/public/bundle.js + working-directory: standalone_app + run: | + npm install + npx vite build --outDir dist - name: Install the required browsers run: playwright install diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml index 311d606f..873de6a7 100644 --- a/.github/workflows/gh-pages.yml +++ b/.github/workflows/gh-pages.yml @@ -31,15 +31,8 @@ jobs: with: node-version: '18' - name: Build standalone_app - env: - PUBLIC_PATH: /optuna-dashboard/public/ - run: make MODE="prd" standalone_app/public/bundle.js - - name: Create publish directory - run: | - mkdir gh-publish - cp -r standalone_app/public gh-publish/public - cp standalone_app/favicon.ico gh-publish/favicon.ico - cp standalone_app/github-pages.html gh-publish/index.html + working-directory: standalone_app + run: npx vite build --base=/optuna-dashboard/public/ --outDir ../gh-pages - name: Upload artifact uses: actions/upload-pages-artifact@v2 with: diff --git a/.gitignore b/.gitignore index 646c1439..a3ecd382 100644 --- a/.gitignore +++ b/.gitignore @@ -10,7 +10,6 @@ optuna_dashboard/public/ # JS node_modules/ -standalone_app/public/ # VSCode vscode/assets/ diff --git a/Makefile b/Makefile index 184b59df..55e8e69d 100644 --- a/Makefile +++ b/Makefile @@ -4,27 +4,23 @@ PYTHON ?= python3 MODE ?= dev RST_FILES := $(shell find docs -name '*.rst') PYTHON_FILES := $(shell find optuna_dashboard/ -name '*.py') -DASHBOARD_TS_IN := $(shell find ./optuna_dashboard -name '*.ts' -o -name '*.tsx') +DASHBOARD_TS_SRC := $(shell find ./optuna_dashboard -name '*.ts' -o -name '*.tsx') DASHBOARD_TS_OUT = optuna_dashboard/public/bundle.js optuna_dashboard/public/favicon.ico RUSTLIB_OUT = rustlib/pkg/optuna_wasm.js rustlib/pkg/optuna_wasm_bg.wasm rustlib/pkg/package.json -STANDALONE_OUT = standalone_app/public/bundle.js vscode/assets/bundle.js +STANDALONE_SRC := $(shell find ./standalone_app/src -name '*.ts' -o -name '*.tsx') $(RUSTLIB_OUT): rustlib/src/*.rs rustlib/Cargo.toml cd rustlib && wasm-pack build --target web -$(STANDALONE_OUT): $(RUSTLIB_OUT) - cd standalone_app && npm install && npm run build:$(MODE) +vscode/assets/bundle.js: $(RUSTLIB_OUT) $(STANDALONE_SRC) + cd standalone_app && npm install && npm run build:vscode -$(DASHBOARD_TS_OUT): $(DASHBOARD_TS_IN) +$(DASHBOARD_TS_OUT): $(DASHBOARD_TS_SRC) npm install && npm run build:$(MODE) -.PHONY: watch-standalone-app -watch-standalone-app: standalone_app/public/bundle.js - cd standalone_app && npm run watch - .PHONY: serve-browser-app -serve-browser-app: standalone_app/public/bundle.js - $(PYTHON) -m http.server 9000 --directory ./standalone_app/ +serve-browser-app: $(RUSTLIB_OUT) + cd standalone_app && npm run watch .PHONY: vscode-extension vscode-extension: vscode/assets/bundle.js diff --git a/e2e_tests/test_server.py b/e2e_tests/test_server.py index cbf65a29..03083c61 100644 --- a/e2e_tests/test_server.py +++ b/e2e_tests/test_server.py @@ -43,7 +43,7 @@ def make_test_server( def make_standalone_server(request: pytest.FixtureRequest) -> str: addr = "127.0.0.1" port = get_free_port() - directory = "./standalone_app/" + directory = "./standalone_app/dist/" Handler = http.server.SimpleHTTPRequestHandler httpd = socketserver.TCPServer( diff --git a/standalone_app/github-pages.html b/standalone_app/github-pages.html deleted file mode 100644 index 609c5c30..00000000 --- a/standalone_app/github-pages.html +++ /dev/null @@ -1,19 +0,0 @@ - - - - - Optuna Dashboard (Wasm ver.) - - - - - - - - - - - -
- - diff --git a/standalone_app/index.html b/standalone_app/index.html index 9669dbf9..2a957984 100644 --- a/standalone_app/index.html +++ b/standalone_app/index.html @@ -3,8 +3,13 @@ Optuna Dashboard (Wasm ver.) - - + + + + + + +
diff --git a/standalone_app/package-lock.json b/standalone_app/package-lock.json index 8c05f23a..1c9a76a9 100644 --- a/standalone_app/package-lock.json +++ b/standalone_app/package-lock.json @@ -28,10 +28,10 @@ "@types/react": "^18.2.64", "@types/react-dom": "^18.2.21", "@types/react-router-dom": "^5.3.3", + "@vitejs/plugin-react": "^4.2.1", "compression-webpack-plugin": "^11.1.0", "esbuild-loader": "^4.0.3", - "ts-loader": "^9.5.1", - "typescript": "^5.4.2", + "vite": "^5.1.5", "webpack": "^5.90.3", "webpack-cli": "^5.1.4" } @@ -45,6 +45,19 @@ "extraneous": true, "license": "MIT" }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/@babel/code-frame": { "version": "7.23.5", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", @@ -57,6 +70,116 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/compat-data": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz", + "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.0.tgz", + "integrity": "sha512-fQfkg0Gjkza3nf0c7/w6Xf34BW4YvzNfACRLmmb7XRLa6XHdR+K9AlJlxneFfWYf6uhOzuzZVTjF/8KfndZANw==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helpers": "^7.24.0", + "@babel/parser": "^7.24.0", + "@babel/template": "^7.24.0", + "@babel/traverse": "^7.24.0", + "@babel/types": "^7.24.0", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, + "node_modules/@babel/generator": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", + "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.23.6", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", + "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.23.5", + "@babel/helper-validator-option": "^7.23.5", + "browserslist": "^4.22.2", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", + "dev": true, + "dependencies": { + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helper-module-imports": { "version": "7.22.15", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", @@ -68,6 +191,58 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", + "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/helper-validator-identifier": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.0.tgz", + "integrity": "sha512-9cUznXMG0+FxRuJfvL82QlTqIzhVW9sL0KjMPHhAOOvpQGL8QtdxnBKILjBqxlHyliz0yCa1G903ZXI/FuHy2w==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", + "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helper-string-parser": { "version": "7.23.4", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", @@ -84,6 +259,29 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/helper-validator-option": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", + "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.0.tgz", + "integrity": "sha512-ulDZdc0Aj5uLc5nETsa7EPx2L7rM0YJM8r7ck7U73AXi7qOV44IHHRAYZHY6iU1rr3C5N4NtTmMRUJP6kwCWeA==", + "dev": true, + "dependencies": { + "@babel/template": "^7.24.0", + "@babel/traverse": "^7.24.0", + "@babel/types": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/highlight": { "version": "7.23.4", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", @@ -97,6 +295,48 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/parser": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.0.tgz", + "integrity": "sha512-QuP/FxEAzMSjXygs8v4N9dvdXzEHN4W1oF3PxuWAtPo08UdM17u89RDMgjLn/mlc56iM0HlLmVkO/wgR+rDgHg==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.23.3.tgz", + "integrity": "sha512-qXRvbeKDSfwnlJnanVRp0SfuWE5DQhwQr5xtLBzp56Wabyo+4CMosF6Kfp+eOD/4FYpql64XVJ2W0pVLlJZxOQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.23.3.tgz", + "integrity": "sha512-91RS0MDnAWDNvGC6Wio5XYkyWI39FMFO+JK9+4AlgaTH+yWwVTsw7/sn6LK0lH7c5F+TFkpv/3LfCJ1Ydwof/g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/runtime": { "version": "7.24.0", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.0.tgz", @@ -108,6 +348,41 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/template": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.0.tgz", + "integrity": "sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.23.5", + "@babel/parser": "^7.24.0", + "@babel/types": "^7.24.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.0.tgz", + "integrity": "sha512-HfuJlI8qq3dEDmNU5ChzzpZRWq+oxCZQyMzIMEqLho+AQnhMnKQUzH6ydo3RBl/YjPCuk68Y6s0Gx0AeyULiWw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.24.0", + "@babel/types": "^7.24.0", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/types": { "version": "7.24.0", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz", @@ -1057,6 +1332,175 @@ "node": ">=14.0.0" } }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.12.1.tgz", + "integrity": "sha512-iU2Sya8hNn1LhsYyf0N+L4Gf9Qc+9eBTJJJsaOGUp+7x4n2M9dxTt8UvhJl3oeftSjblSlpCfvjA/IfP3g5VjQ==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.12.1.tgz", + "integrity": "sha512-wlzcWiH2Ir7rdMELxFE5vuM7D6TsOcJ2Yw0c3vaBR3VOsJFVTx9xvwnAvhgU5Ii8Gd6+I11qNHwndDscIm0HXg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.12.1.tgz", + "integrity": "sha512-YRXa1+aZIFN5BaImK+84B3uNK8C6+ynKLPgvn29X9s0LTVCByp54TB7tdSMHDR7GTV39bz1lOmlLDuedgTwwHg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.12.1.tgz", + "integrity": "sha512-opjWJ4MevxeA8FhlngQWPBOvVWYNPFkq6/25rGgG+KOy0r8clYwL1CFd+PGwRqqMFVQ4/Qd3sQu5t7ucP7C/Uw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.12.1.tgz", + "integrity": "sha512-uBkwaI+gBUlIe+EfbNnY5xNyXuhZbDSx2nzzW8tRMjUmpScd6lCQYKY2V9BATHtv5Ef2OBq6SChEP8h+/cxifQ==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.12.1.tgz", + "integrity": "sha512-0bK9aG1kIg0Su7OcFTlexkVeNZ5IzEsnz1ept87a0TUgZ6HplSgkJAnFpEVRW7GRcikT4GlPV0pbtVedOaXHQQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.12.1.tgz", + "integrity": "sha512-qB6AFRXuP8bdkBI4D7UPUbE7OQf7u5OL+R94JE42Z2Qjmyj74FtDdLGeriRyBDhm4rQSvqAGCGC01b8Fu2LthQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.12.1.tgz", + "integrity": "sha512-sHig3LaGlpNgDj5o8uPEoGs98RII8HpNIqFtAI8/pYABO8i0nb1QzT0JDoXF/pxzqO+FkxvwkHZo9k0NJYDedg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.12.1.tgz", + "integrity": "sha512-nD3YcUv6jBJbBNFvSbp0IV66+ba/1teuBcu+fBBPZ33sidxitc6ErhON3JNavaH8HlswhWMC3s5rgZpM4MtPqQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.12.1.tgz", + "integrity": "sha512-7/XVZqgBby2qp/cO0TQ8uJK+9xnSdJ9ct6gSDdEr4MfABrjTyrW6Bau7HQ73a2a5tPB7hno49A0y1jhWGDN9OQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.12.1.tgz", + "integrity": "sha512-CYc64bnICG42UPL7TrhIwsJW4QcKkIt9gGlj21gq3VV0LL6XNb1yAdHVp1pIi9gkts9gGcT3OfUYHjGP7ETAiw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.12.1.tgz", + "integrity": "sha512-LN+vnlZ9g0qlHGlS920GR4zFCqAwbv2lULrR29yGaWP9u7wF5L7GqWu9Ah6/kFZPXPUkpdZwd//TNR+9XC9hvA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.12.1.tgz", + "integrity": "sha512-n+vkrSyphvmU0qkQ6QBNXCGr2mKjhP08mPRM/Xp5Ck2FV4NrHU+y6axzDeixUrCBHVUS51TZhjqrKBBsHLKb2Q==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@sqlite.org/sqlite-wasm": { "version": "3.45.1-build1", "resolved": "https://registry.npmjs.org/@sqlite.org/sqlite-wasm/-/sqlite-wasm-3.45.1-build1.tgz", @@ -1065,6 +1509,47 @@ "sqlite-wasm": "bin/index.js" } }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.8", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", + "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.5.tgz", + "integrity": "sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.20.7" + } + }, "node_modules/@types/eslint": { "version": "8.37.0", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.37.0.tgz", @@ -1181,6 +1666,25 @@ "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz", "integrity": "sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==" }, + "node_modules/@vitejs/plugin-react": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.2.1.tgz", + "integrity": "sha512-oojO9IDc4nCUUi8qIR11KoQm0XFFLIwsRBwHRR4d/88IWghn1y6ckz/bJ8GHDCsYEJee8mDzqtJxh15/cisJNQ==", + "dev": true, + "dependencies": { + "@babel/core": "^7.23.5", + "@babel/plugin-transform-react-jsx-self": "^7.23.3", + "@babel/plugin-transform-react-jsx-source": "^7.23.3", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.14.0" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0" + } + }, "node_modules/@webassemblyjs/ast": { "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", @@ -1502,18 +2006,6 @@ "node": "*" } }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/browserslist": { "version": "4.23.0", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", @@ -1769,6 +2261,23 @@ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, "node_modules/dom-helpers": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", @@ -1981,18 +2490,6 @@ "node": ">= 4.9.1" } }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/find-root": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", @@ -2011,11 +2508,34 @@ "node": ">=8" } }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/get-tsconfig": { "version": "4.7.3", "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.3.tgz", @@ -2034,6 +2554,15 @@ "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", "dev": true }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/goober": { "version": "2.1.13", "resolved": "https://registry.npmjs.org/goober/-/goober-2.1.13.tgz", @@ -2144,15 +2673,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, "node_modules/is-plain-object": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", @@ -2223,6 +2743,18 @@ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", @@ -2307,15 +2839,12 @@ } }, "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dev": true, "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" + "yallist": "^3.0.2" } }, "node_modules/merge-stream": { @@ -2324,19 +2853,6 @@ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", "dev": true }, - "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dev": true, - "dependencies": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, "node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", @@ -2363,6 +2879,30 @@ "resolved": "https://registry.npmjs.org/module-workers-polyfill/-/module-workers-polyfill-0.3.2.tgz", "integrity": "sha512-zcEMj8vUGYu1Tc5s2GK84MBzRSweec/Ef6F7phRF8QlTfTf2upFNsR3W0lDhvN2E6o1TTXbFIYynD0rQSlynPw==" }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, "node_modules/neo-async": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", @@ -2509,18 +3049,6 @@ "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", "dev": true }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/pkg-dir": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", @@ -2538,6 +3066,34 @@ "resolved": "https://registry.npmjs.org/plotly.js-dist-min/-/plotly.js-dist-min-2.30.0.tgz", "integrity": "sha512-LM7v0H8MZUNnOT0WmJt8apvXnrjytUgxvG9RAcGT2AsJNlCxLGMMFYQS5TEiYNRH96/hcV8KGQmw+NwjmXSFSA==" }, + "node_modules/postcss": { + "version": "8.4.35", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.35.tgz", + "integrity": "sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, "node_modules/prop-types": { "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", @@ -2599,6 +3155,15 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" }, + "node_modules/react-refresh": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.0.tgz", + "integrity": "sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/react-router": { "version": "6.22.2", "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.22.2.tgz", @@ -2743,6 +3308,38 @@ "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" } }, + "node_modules/rollup": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.12.1.tgz", + "integrity": "sha512-ggqQKvx/PsB0FaWXhIvVkSWh7a/PCLQAsMjBc+nA2M8Rv2/HG0X6zvixAB7KyZBRtifBUhy5k8voQX/mRnABPg==", + "dev": true, + "dependencies": { + "@types/estree": "1.0.5" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.12.1", + "@rollup/rollup-android-arm64": "4.12.1", + "@rollup/rollup-darwin-arm64": "4.12.1", + "@rollup/rollup-darwin-x64": "4.12.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.12.1", + "@rollup/rollup-linux-arm64-gnu": "4.12.1", + "@rollup/rollup-linux-arm64-musl": "4.12.1", + "@rollup/rollup-linux-riscv64-gnu": "4.12.1", + "@rollup/rollup-linux-x64-gnu": "4.12.1", + "@rollup/rollup-linux-x64-musl": "4.12.1", + "@rollup/rollup-win32-arm64-msvc": "4.12.1", + "@rollup/rollup-win32-ia32-msvc": "4.12.1", + "@rollup/rollup-win32-x64-msvc": "4.12.1", + "fsevents": "~2.3.2" + } + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -2790,18 +3387,12 @@ } }, "node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, "bin": { "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" } }, "node_modules/serialize-javascript": { @@ -2860,6 +3451,15 @@ "node": ">=0.10.0" } }, + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/source-map-support": { "version": "0.5.21", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", @@ -2975,130 +3575,6 @@ "node": ">=4" } }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/ts-loader": { - "version": "9.5.1", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.1.tgz", - "integrity": "sha512-rNH3sK9kGZcH9dYzC7CewQm4NtxJTjSEVRJ2DyBZR7f8/wcta+iV44UPCXc5+nzDzivKtlzV6c9P4e+oFhDLYg==", - "dev": true, - "dependencies": { - "chalk": "^4.1.0", - "enhanced-resolve": "^5.0.0", - "micromatch": "^4.0.0", - "semver": "^7.3.4", - "source-map": "^0.7.4" - }, - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "typescript": "*", - "webpack": "^5.0.0" - } - }, - "node_modules/ts-loader/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/ts-loader/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/ts-loader/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/ts-loader/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/ts-loader/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/ts-loader/node_modules/source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/ts-loader/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/typescript": { - "version": "5.4.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.2.tgz", - "integrity": "sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, "node_modules/undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", @@ -3144,6 +3620,61 @@ "punycode": "^2.1.0" } }, + "node_modules/vite": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.1.5.tgz", + "integrity": "sha512-BdN1xh0Of/oQafhU+FvopafUp6WaYenLU/NFoL5WyJL++GxkNfieKzBhM24H3HVsPQrlAqB7iJYTHabzaRed5Q==", + "dev": true, + "dependencies": { + "esbuild": "^0.19.3", + "postcss": "^8.4.35", + "rollup": "^4.2.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, "node_modules/watchpack": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", @@ -3321,9 +3852,9 @@ "dev": true }, "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true }, "node_modules/yaml": { @@ -3341,6 +3872,16 @@ } }, "dependencies": { + "@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, + "requires": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, "@babel/code-frame": { "version": "7.23.5", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", @@ -3350,6 +3891,93 @@ "chalk": "^2.4.2" } }, + "@babel/compat-data": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz", + "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==", + "dev": true + }, + "@babel/core": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.0.tgz", + "integrity": "sha512-fQfkg0Gjkza3nf0c7/w6Xf34BW4YvzNfACRLmmb7XRLa6XHdR+K9AlJlxneFfWYf6uhOzuzZVTjF/8KfndZANw==", + "dev": true, + "requires": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helpers": "^7.24.0", + "@babel/parser": "^7.24.0", + "@babel/template": "^7.24.0", + "@babel/traverse": "^7.24.0", + "@babel/types": "^7.24.0", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "dependencies": { + "convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + } + } + }, + "@babel/generator": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", + "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", + "dev": true, + "requires": { + "@babel/types": "^7.23.6", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + } + }, + "@babel/helper-compilation-targets": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", + "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.23.5", + "@babel/helper-validator-option": "^7.23.5", + "browserslist": "^4.22.2", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + } + }, + "@babel/helper-environment-visitor": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", + "dev": true + }, + "@babel/helper-function-name": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", + "dev": true, + "requires": { + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "dev": true, + "requires": { + "@babel/types": "^7.22.5" + } + }, "@babel/helper-module-imports": { "version": "7.22.15", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", @@ -3358,6 +3986,43 @@ "@babel/types": "^7.22.15" } }, + "@babel/helper-module-transforms": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", + "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", + "dev": true, + "requires": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/helper-validator-identifier": "^7.22.20" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.0.tgz", + "integrity": "sha512-9cUznXMG0+FxRuJfvL82QlTqIzhVW9sL0KjMPHhAOOvpQGL8QtdxnBKILjBqxlHyliz0yCa1G903ZXI/FuHy2w==", + "dev": true + }, + "@babel/helper-simple-access": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", + "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", + "dev": true, + "requires": { + "@babel/types": "^7.22.5" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "dev": true, + "requires": { + "@babel/types": "^7.22.5" + } + }, "@babel/helper-string-parser": { "version": "7.23.4", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", @@ -3368,6 +4033,23 @@ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==" }, + "@babel/helper-validator-option": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", + "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", + "dev": true + }, + "@babel/helpers": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.0.tgz", + "integrity": "sha512-ulDZdc0Aj5uLc5nETsa7EPx2L7rM0YJM8r7ck7U73AXi7qOV44IHHRAYZHY6iU1rr3C5N4NtTmMRUJP6kwCWeA==", + "dev": true, + "requires": { + "@babel/template": "^7.24.0", + "@babel/traverse": "^7.24.0", + "@babel/types": "^7.24.0" + } + }, "@babel/highlight": { "version": "7.23.4", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", @@ -3378,6 +4060,30 @@ "js-tokens": "^4.0.0" } }, + "@babel/parser": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.0.tgz", + "integrity": "sha512-QuP/FxEAzMSjXygs8v4N9dvdXzEHN4W1oF3PxuWAtPo08UdM17u89RDMgjLn/mlc56iM0HlLmVkO/wgR+rDgHg==", + "dev": true + }, + "@babel/plugin-transform-react-jsx-self": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.23.3.tgz", + "integrity": "sha512-qXRvbeKDSfwnlJnanVRp0SfuWE5DQhwQr5xtLBzp56Wabyo+4CMosF6Kfp+eOD/4FYpql64XVJ2W0pVLlJZxOQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, + "@babel/plugin-transform-react-jsx-source": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.23.3.tgz", + "integrity": "sha512-91RS0MDnAWDNvGC6Wio5XYkyWI39FMFO+JK9+4AlgaTH+yWwVTsw7/sn6LK0lH7c5F+TFkpv/3LfCJ1Ydwof/g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.22.5" + } + }, "@babel/runtime": { "version": "7.24.0", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.0.tgz", @@ -3386,6 +4092,35 @@ "regenerator-runtime": "^0.14.0" } }, + "@babel/template": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.0.tgz", + "integrity": "sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.23.5", + "@babel/parser": "^7.24.0", + "@babel/types": "^7.24.0" + } + }, + "@babel/traverse": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.0.tgz", + "integrity": "sha512-HfuJlI8qq3dEDmNU5ChzzpZRWq+oxCZQyMzIMEqLho+AQnhMnKQUzH6ydo3RBl/YjPCuk68Y6s0Gx0AeyULiWw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.24.0", + "@babel/types": "^7.24.0", + "debug": "^4.3.1", + "globals": "^11.1.0" + } + }, "@babel/types": { "version": "7.24.0", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz", @@ -3907,11 +4642,143 @@ "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.15.2.tgz", "integrity": "sha512-+Rnav+CaoTE5QJc4Jcwh5toUpnVLKYbpU6Ys0zqbakqbaLQHeglLVHPfxOiQqdNmUy5C2lXz5dwC6tQNX2JW2Q==" }, + "@rollup/rollup-android-arm-eabi": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.12.1.tgz", + "integrity": "sha512-iU2Sya8hNn1LhsYyf0N+L4Gf9Qc+9eBTJJJsaOGUp+7x4n2M9dxTt8UvhJl3oeftSjblSlpCfvjA/IfP3g5VjQ==", + "dev": true, + "optional": true + }, + "@rollup/rollup-android-arm64": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.12.1.tgz", + "integrity": "sha512-wlzcWiH2Ir7rdMELxFE5vuM7D6TsOcJ2Yw0c3vaBR3VOsJFVTx9xvwnAvhgU5Ii8Gd6+I11qNHwndDscIm0HXg==", + "dev": true, + "optional": true + }, + "@rollup/rollup-darwin-arm64": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.12.1.tgz", + "integrity": "sha512-YRXa1+aZIFN5BaImK+84B3uNK8C6+ynKLPgvn29X9s0LTVCByp54TB7tdSMHDR7GTV39bz1lOmlLDuedgTwwHg==", + "dev": true, + "optional": true + }, + "@rollup/rollup-darwin-x64": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.12.1.tgz", + "integrity": "sha512-opjWJ4MevxeA8FhlngQWPBOvVWYNPFkq6/25rGgG+KOy0r8clYwL1CFd+PGwRqqMFVQ4/Qd3sQu5t7ucP7C/Uw==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.12.1.tgz", + "integrity": "sha512-uBkwaI+gBUlIe+EfbNnY5xNyXuhZbDSx2nzzW8tRMjUmpScd6lCQYKY2V9BATHtv5Ef2OBq6SChEP8h+/cxifQ==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-arm64-gnu": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.12.1.tgz", + "integrity": "sha512-0bK9aG1kIg0Su7OcFTlexkVeNZ5IzEsnz1ept87a0TUgZ6HplSgkJAnFpEVRW7GRcikT4GlPV0pbtVedOaXHQQ==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-arm64-musl": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.12.1.tgz", + "integrity": "sha512-qB6AFRXuP8bdkBI4D7UPUbE7OQf7u5OL+R94JE42Z2Qjmyj74FtDdLGeriRyBDhm4rQSvqAGCGC01b8Fu2LthQ==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-riscv64-gnu": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.12.1.tgz", + "integrity": "sha512-sHig3LaGlpNgDj5o8uPEoGs98RII8HpNIqFtAI8/pYABO8i0nb1QzT0JDoXF/pxzqO+FkxvwkHZo9k0NJYDedg==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-x64-gnu": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.12.1.tgz", + "integrity": "sha512-nD3YcUv6jBJbBNFvSbp0IV66+ba/1teuBcu+fBBPZ33sidxitc6ErhON3JNavaH8HlswhWMC3s5rgZpM4MtPqQ==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-x64-musl": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.12.1.tgz", + "integrity": "sha512-7/XVZqgBby2qp/cO0TQ8uJK+9xnSdJ9ct6gSDdEr4MfABrjTyrW6Bau7HQ73a2a5tPB7hno49A0y1jhWGDN9OQ==", + "dev": true, + "optional": true + }, + "@rollup/rollup-win32-arm64-msvc": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.12.1.tgz", + "integrity": "sha512-CYc64bnICG42UPL7TrhIwsJW4QcKkIt9gGlj21gq3VV0LL6XNb1yAdHVp1pIi9gkts9gGcT3OfUYHjGP7ETAiw==", + "dev": true, + "optional": true + }, + "@rollup/rollup-win32-ia32-msvc": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.12.1.tgz", + "integrity": "sha512-LN+vnlZ9g0qlHGlS920GR4zFCqAwbv2lULrR29yGaWP9u7wF5L7GqWu9Ah6/kFZPXPUkpdZwd//TNR+9XC9hvA==", + "dev": true, + "optional": true + }, + "@rollup/rollup-win32-x64-msvc": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.12.1.tgz", + "integrity": "sha512-n+vkrSyphvmU0qkQ6QBNXCGr2mKjhP08mPRM/Xp5Ck2FV4NrHU+y6axzDeixUrCBHVUS51TZhjqrKBBsHLKb2Q==", + "dev": true, + "optional": true + }, "@sqlite.org/sqlite-wasm": { "version": "3.45.1-build1", "resolved": "https://registry.npmjs.org/@sqlite.org/sqlite-wasm/-/sqlite-wasm-3.45.1-build1.tgz", "integrity": "sha512-1EgshFNhVeBtZ9KtQPm3PzzJ2CtpmXAq2DAPywy7WZ3gOK6p5n8TY+M+mBMpQCF5cLqrdNFb3Kp9uNie9rUAHw==" }, + "@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "requires": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "@types/babel__generator": { + "version": "7.6.8", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", + "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@types/babel__traverse": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.5.tgz", + "integrity": "sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ==", + "dev": true, + "requires": { + "@babel/types": "^7.20.7" + } + }, "@types/eslint": { "version": "8.37.0", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.37.0.tgz", @@ -4028,6 +4895,19 @@ "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz", "integrity": "sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==" }, + "@vitejs/plugin-react": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.2.1.tgz", + "integrity": "sha512-oojO9IDc4nCUUi8qIR11KoQm0XFFLIwsRBwHRR4d/88IWghn1y6ckz/bJ8GHDCsYEJee8mDzqtJxh15/cisJNQ==", + "dev": true, + "requires": { + "@babel/core": "^7.23.5", + "@babel/plugin-transform-react-jsx-self": "^7.23.3", + "@babel/plugin-transform-react-jsx-source": "^7.23.3", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.14.0" + } + }, "@webassemblyjs/ast": { "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", @@ -4292,15 +5172,6 @@ "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", "dev": true }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, "browserslist": { "version": "4.23.0", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", @@ -4478,6 +5349,15 @@ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, "dom-helpers": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", @@ -4640,15 +5520,6 @@ "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", "dev": true }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, "find-root": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", @@ -4664,11 +5535,24 @@ "path-exists": "^4.0.0" } }, + "fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "optional": true + }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, + "gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true + }, "get-tsconfig": { "version": "4.7.3", "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.3.tgz", @@ -4684,6 +5568,12 @@ "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", "dev": true }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, "goober": { "version": "2.1.13", "resolved": "https://registry.npmjs.org/goober/-/goober-2.1.13.tgz", @@ -4767,12 +5657,6 @@ "has": "^1.0.3" } }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, "is-plain-object": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", @@ -4827,6 +5711,12 @@ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, "json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", @@ -4890,12 +5780,12 @@ } }, "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dev": true, "requires": { - "yallist": "^4.0.0" + "yallist": "^3.0.2" } }, "merge-stream": { @@ -4904,16 +5794,6 @@ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", "dev": true }, - "micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dev": true, - "requires": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - } - }, "mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", @@ -4934,6 +5814,18 @@ "resolved": "https://registry.npmjs.org/module-workers-polyfill/-/module-workers-polyfill-0.3.2.tgz", "integrity": "sha512-zcEMj8vUGYu1Tc5s2GK84MBzRSweec/Ef6F7phRF8QlTfTf2upFNsR3W0lDhvN2E6o1TTXbFIYynD0rQSlynPw==" }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true + }, "neo-async": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", @@ -5034,12 +5926,6 @@ "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", "dev": true }, - "picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true - }, "pkg-dir": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", @@ -5054,6 +5940,17 @@ "resolved": "https://registry.npmjs.org/plotly.js-dist-min/-/plotly.js-dist-min-2.30.0.tgz", "integrity": "sha512-LM7v0H8MZUNnOT0WmJt8apvXnrjytUgxvG9RAcGT2AsJNlCxLGMMFYQS5TEiYNRH96/hcV8KGQmw+NwjmXSFSA==" }, + "postcss": { + "version": "8.4.35", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.35.tgz", + "integrity": "sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==", + "dev": true, + "requires": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + } + }, "prop-types": { "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", @@ -5108,6 +6005,12 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" }, + "react-refresh": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.0.tgz", + "integrity": "sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==", + "dev": true + }, "react-router": { "version": "6.22.2", "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.22.2.tgz", @@ -5202,6 +6105,29 @@ "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", "dev": true }, + "rollup": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.12.1.tgz", + "integrity": "sha512-ggqQKvx/PsB0FaWXhIvVkSWh7a/PCLQAsMjBc+nA2M8Rv2/HG0X6zvixAB7KyZBRtifBUhy5k8voQX/mRnABPg==", + "dev": true, + "requires": { + "@rollup/rollup-android-arm-eabi": "4.12.1", + "@rollup/rollup-android-arm64": "4.12.1", + "@rollup/rollup-darwin-arm64": "4.12.1", + "@rollup/rollup-darwin-x64": "4.12.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.12.1", + "@rollup/rollup-linux-arm64-gnu": "4.12.1", + "@rollup/rollup-linux-arm64-musl": "4.12.1", + "@rollup/rollup-linux-riscv64-gnu": "4.12.1", + "@rollup/rollup-linux-x64-gnu": "4.12.1", + "@rollup/rollup-linux-x64-musl": "4.12.1", + "@rollup/rollup-win32-arm64-msvc": "4.12.1", + "@rollup/rollup-win32-ia32-msvc": "4.12.1", + "@rollup/rollup-win32-x64-msvc": "4.12.1", + "@types/estree": "1.0.5", + "fsevents": "~2.3.2" + } + }, "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -5228,13 +6154,10 @@ } }, "semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true }, "serialize-javascript": { "version": "6.0.2", @@ -5280,6 +6203,12 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==" }, + "source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "dev": true + }, "source-map-support": { "version": "0.5.21", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", @@ -5352,91 +6281,6 @@ "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==" }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - }, - "ts-loader": { - "version": "9.5.1", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.1.tgz", - "integrity": "sha512-rNH3sK9kGZcH9dYzC7CewQm4NtxJTjSEVRJ2DyBZR7f8/wcta+iV44UPCXc5+nzDzivKtlzV6c9P4e+oFhDLYg==", - "dev": true, - "requires": { - "chalk": "^4.1.0", - "enhanced-resolve": "^5.0.0", - "micromatch": "^4.0.0", - "semver": "^7.3.4", - "source-map": "^0.7.4" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "typescript": { - "version": "5.4.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.2.tgz", - "integrity": "sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==", - "dev": true - }, "undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", @@ -5462,6 +6306,18 @@ "punycode": "^2.1.0" } }, + "vite": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.1.5.tgz", + "integrity": "sha512-BdN1xh0Of/oQafhU+FvopafUp6WaYenLU/NFoL5WyJL++GxkNfieKzBhM24H3HVsPQrlAqB7iJYTHabzaRed5Q==", + "dev": true, + "requires": { + "esbuild": "^0.19.3", + "fsevents": "~2.3.3", + "postcss": "^8.4.35", + "rollup": "^4.2.0" + } + }, "watchpack": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", @@ -5585,9 +6441,9 @@ "dev": true }, "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true }, "yaml": { diff --git a/standalone_app/package.json b/standalone_app/package.json index ebb7c15f..c3c471e9 100644 --- a/standalone_app/package.json +++ b/standalone_app/package.json @@ -4,20 +4,18 @@ "version": "0.0.0", "description": "", "scripts": { - "watch": "NODE_ENV=development TYPESCRIPT_LOADER=esbuild-loader webpack --watch", - "serve": "python3 -m http.server 9000 --directory .", - "build:dev": "NODE_ENV=development TYPESCRIPT_LOADER=esbuild-loader webpack", - "build:prd": "NODE_ENV=production webpack" + "watch": "vite", + "build:vscode": "webpack" }, "devDependencies": { "@types/plotly.js": "^2.29.2", "@types/react": "^18.2.64", "@types/react-dom": "^18.2.21", "@types/react-router-dom": "^5.3.3", + "@vitejs/plugin-react": "^4.2.1", "compression-webpack-plugin": "^11.1.0", "esbuild-loader": "^4.0.3", - "ts-loader": "^9.5.1", - "typescript": "^5.4.2", + "vite": "^5.1.5", "webpack": "^5.90.3", "webpack-cli": "^5.1.4" }, diff --git a/standalone_app/favicon.ico b/standalone_app/public/favicon.ico similarity index 100% rename from standalone_app/favicon.ico rename to standalone_app/public/favicon.ico diff --git a/standalone_app/vite.config.js b/standalone_app/vite.config.js new file mode 100644 index 00000000..a2de5bac --- /dev/null +++ b/standalone_app/vite.config.js @@ -0,0 +1,18 @@ +import { defineConfig } from 'vite'; +import react from '@vitejs/plugin-react' + +export default defineConfig({ + plugins: [react()], + define: { + 'IS_VSCODE': JSON.stringify(false), + }, + optimizeDeps: { + exclude: ['@sqlite.org/sqlite-wasm'], + }, + server: { + fs: { + // Allow serving wasm files in node_modules + allow: ['..'], + }, + }, +}); diff --git a/standalone_app/webpack.config.js b/standalone_app/webpack.config.js index 1e876959..4c599a49 100644 --- a/standalone_app/webpack.config.js +++ b/standalone_app/webpack.config.js @@ -1,101 +1,48 @@ const webpack = require('webpack'); const path = require('path'); +const CompressionPlugin = require("compression-webpack-plugin"); -const mode = process.env.NODE_ENV === 'production' ? 'production' : 'development'; -const isDev = mode === 'development'; -const PUBLIC_PATH = process.env.PUBLIC_PATH ?? '/public/'; -if (!PUBLIC_PATH.endsWith('/')) { - PUBLIC_PATH += '/'; -} - -const typeScriptLoader = process.env.TYPESCRIPT_LOADER === "esbuild-loader" ? { - test: /\.tsx?$/, - exclude: [/node_modules/], - loader: 'esbuild-loader', - options: { - loader: 'tsx', - tsconfigRaw: require('./tsconfig.json') - } -} : { - test: /\.tsx?$/, - exclude: [/node_modules/], - loader: 'ts-loader', - options: { - configFile: __dirname + '/tsconfig.json', - transpileOnly: isDev, - happyPackMode: true - } -} - -var config = [ - { - mode, - experiments: { - syncWebAssembly: true, - asyncWebAssembly: true, - }, - entry: [__dirname + '/src/browser_app_entry.tsx'], - output: { - path: __dirname + '/public/', - filename: 'bundle.js', - publicPath: PUBLIC_PATH - }, - module: { - rules: [{ oneOf: [typeScriptLoader] }] - }, - resolve: { - extensions: ['.ts', '.tsx', '.js'] - }, - plugins: [ - new webpack.DefinePlugin({'IS_VSCODE': JSON.stringify(false)}) - ] +module.exports = { + mode: "production", + devtool: 'source-map', + experiments: { + syncWebAssembly: true, + asyncWebAssembly: true, }, - { - mode, - experiments: { - syncWebAssembly: true, - asyncWebAssembly: true, - }, - entry: [__dirname + '/src/vscode_entry.tsx'], - output: { - path: path.resolve(__dirname, '../vscode/assets/'), - filename: 'bundle.js', - publicPath: '/' - }, - module: { - rules: [ - { oneOf: [typeScriptLoader] }, - { - test: /\.wasm$/, - type: "asset/inline", - }, - ] - }, - resolve: { - extensions: ['.ts', '.tsx', '.js'] - }, - plugins: [ - new webpack.DefinePlugin({'IS_VSCODE': JSON.stringify(true)}) - ] - }, -]; - -if (isDev) { - config[0].devtool = 'source-map'; - config[0].cache = { + cache: { type: 'filesystem', buildDependencies: { config: [__filename], } - } - console.log('= = = = = = = = = = = = = = = = = = ='); - console.log('DEVELOPMENT BUILD'); - console.log(process.env.TYPESCRIPT_LOADER === 'esbuild-loader' ? 'esbuild-loader' : 'ts-loader'); - console.log('= = = = = = = = = = = = = = = = = = ='); -} else { - const CompressionPlugin = require("compression-webpack-plugin"); - config[0].plugins.push(new CompressionPlugin()) - config[1].plugins.push(new CompressionPlugin()) -} - -module.exports = config; + }, + entry: [__dirname + '/src/vscode_entry.tsx'], + output: { + path: path.resolve(__dirname, '../vscode/assets/'), + filename: 'bundle.js', + publicPath: '/' + }, + module: { + rules: [ + { oneOf: [{ + test: /\.tsx?$/, + exclude: [/node_modules/], + loader: 'esbuild-loader', + options: { + loader: 'tsx', + tsconfigRaw: require('./tsconfig.json') + } + }] }, + { + test: /\.wasm$/, + type: "asset/inline", + }, + ] + }, + resolve: { + extensions: ['.ts', '.tsx', '.js'] + }, + plugins: [ + new webpack.DefinePlugin({ 'IS_VSCODE': JSON.stringify(true) }), + new CompressionPlugin() + ] +}; From 5bd228d51a74cb40bb98b7abca11d692b69c6b37 Mon Sep 17 00:00:00 2001 From: c-bata Date: Fri, 8 Mar 2024 10:03:39 +0900 Subject: [PATCH 68/98] Fix gh action workflows --- .github/workflows/e2e-standalone-tests.yml | 5 +++++ .github/workflows/gh-pages.yml | 8 +++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/.github/workflows/e2e-standalone-tests.yml b/.github/workflows/e2e-standalone-tests.yml index ade4472e..ca9c0317 100644 --- a/.github/workflows/e2e-standalone-tests.yml +++ b/.github/workflows/e2e-standalone-tests.yml @@ -41,6 +41,11 @@ jobs: python -m pip install --progress-bar off . python -m pip install --progress-bar off pytest-playwright==0.4.3 # next version is flaky + - name: Build rustlib + working-directory: rustlib + run: | + wasm-pack build --target web + - name: Build standalone_app working-directory: standalone_app run: | diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml index 873de6a7..26c31e3c 100644 --- a/.github/workflows/gh-pages.yml +++ b/.github/workflows/gh-pages.yml @@ -30,9 +30,15 @@ jobs: uses: actions/setup-node@v2 with: node-version: '18' + - name: Build rustlib + working-directory: rustlib + run: | + wasm-pack build --target web - name: Build standalone_app working-directory: standalone_app - run: npx vite build --base=/optuna-dashboard/public/ --outDir ../gh-pages + run: | + npm install + npx vite build --base=/optuna-dashboard/public/ --outDir ../gh-pages - name: Upload artifact uses: actions/upload-pages-artifact@v2 with: From 9c13fbfda40c1dac18bee41b973357a52def764f Mon Sep 17 00:00:00 2001 From: c-bata Date: Fri, 8 Mar 2024 10:13:17 +0900 Subject: [PATCH 69/98] Fix e2e-standalone-tests.yml --- .github/workflows/e2e-standalone-tests.yml | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/.github/workflows/e2e-standalone-tests.yml b/.github/workflows/e2e-standalone-tests.yml index ca9c0317..7dc6fcaa 100644 --- a/.github/workflows/e2e-standalone-tests.yml +++ b/.github/workflows/e2e-standalone-tests.yml @@ -5,18 +5,18 @@ on: - main paths: - '.github/workflows/e2e-standalone-tests.yml' - - '**.py' - - '**.ts' - - '**.tsx' - - 'package.json' - - 'package-lock.json' - - 'tsconfig.json' + - 'standalone_app/**.ts' + - 'standalone_app/**.tsx' + - 'standalone_app/package.json' + - 'standalone_app/package-lock.json' + - 'standalone_app/tsconfig.json' + - 'standalone_app/vite.config.js' jobs: test: - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest strategy: matrix: - optuna-version: ['git+https://github.com/optuna/optuna.git'] + optuna-version: ['optuna'] steps: - uses: actions/checkout@v3 @@ -43,8 +43,7 @@ jobs: - name: Build rustlib working-directory: rustlib - run: | - wasm-pack build --target web + run: wasm-pack build --target web - name: Build standalone_app working-directory: standalone_app From 7102334b2ffa199d008ccb5041dd90a6f81c3131 Mon Sep 17 00:00:00 2001 From: c-bata Date: Fri, 8 Mar 2024 10:20:28 +0900 Subject: [PATCH 70/98] Update gh-pages action --- .github/workflows/gh-pages.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml index 26c31e3c..9eeddc69 100644 --- a/.github/workflows/gh-pages.yml +++ b/.github/workflows/gh-pages.yml @@ -32,17 +32,16 @@ jobs: node-version: '18' - name: Build rustlib working-directory: rustlib - run: | - wasm-pack build --target web + run: wasm-pack build --target web - name: Build standalone_app working-directory: standalone_app run: | npm install - npx vite build --base=/optuna-dashboard/public/ --outDir ../gh-pages + npx vite build --base=/optuna-dashboard/public/ --outDir ./gh-pages - name: Upload artifact uses: actions/upload-pages-artifact@v2 with: - path: './gh-publish' + path: './standalone_app/gh-pages' - name: Deploy to GitHub Pages id: deployment uses: actions/deploy-pages@v2 From 24fef6f956121295b2340925398378baf36161d7 Mon Sep 17 00:00:00 2001 From: c-bata Date: Fri, 8 Mar 2024 13:26:15 +0900 Subject: [PATCH 71/98] Fix gh-pages --- .github/workflows/gh-pages.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml index 9eeddc69..74c42a31 100644 --- a/.github/workflows/gh-pages.yml +++ b/.github/workflows/gh-pages.yml @@ -37,7 +37,7 @@ jobs: working-directory: standalone_app run: | npm install - npx vite build --base=/optuna-dashboard/public/ --outDir ./gh-pages + npx vite build --base=/optuna-dashboard/ --outDir ./gh-pages - name: Upload artifact uses: actions/upload-pages-artifact@v2 with: From f667ce0c87825da7d858b81810e790c58ce18941 Mon Sep 17 00:00:00 2001 From: keisuke-umezawa Date: Sun, 10 Mar 2024 16:36:20 +0900 Subject: [PATCH 72/98] Move isLoading into action --- optuna_dashboard/ts/action.ts | 3 +++ optuna_dashboard/ts/components/StudyDetail.tsx | 11 ++--------- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/optuna_dashboard/ts/action.ts b/optuna_dashboard/ts/action.ts index 04c3532b..ff66b8e9 100644 --- a/optuna_dashboard/ts/action.ts +++ b/optuna_dashboard/ts/action.ts @@ -235,6 +235,9 @@ export const actionCreator = () => { } const updateStudyDetail = (studyId: number) => { + if (studyDetailLoading[studyId]) { + return + } setStudyDetailLoading({ ...studyDetailLoading, [studyId]: true }) let nLocalFixedTrials = 0 if (studyId in studyDetails) { diff --git a/optuna_dashboard/ts/components/StudyDetail.tsx b/optuna_dashboard/ts/components/StudyDetail.tsx index eaa17bb0..7a29c63e 100644 --- a/optuna_dashboard/ts/components/StudyDetail.tsx +++ b/optuna_dashboard/ts/components/StudyDetail.tsx @@ -54,9 +54,6 @@ export const StudyDetail: FC<{ const action = actionCreator() const studyId = useURLVars() const studyDetail = useStudyDetailValue(studyId) - const isLoading = useRecoilValue>( - studyDetailLoadingState - ) const reloadInterval = useRecoilValue(reloadIntervalState) const studyName = useStudyName(studyId) const isPreferential = useStudyIsPreferential(studyId) @@ -65,9 +62,7 @@ export const StudyDetail: FC<{ studyName !== null ? `${studyName} (id=${studyId})` : `Study #${studyId}` useEffect(() => { - if (!isLoading[studyId]) { - action.updateStudyDetail(studyId) - } + action.updateStudyDetail(studyId) action.updateAPIMeta() }, []) @@ -92,9 +87,7 @@ export const StudyDetail: FC<{ } const intervalId = setInterval(function () { - if (!isLoading[studyId]) { - action.updateStudyDetail(studyId) - } + action.updateStudyDetail(studyId) }, interval) return () => clearInterval(intervalId) }, [reloadInterval, studyDetail, page]) From 324301d53eb90ae935d8dd58b1c66e00e9264306 Mon Sep 17 00:00:00 2001 From: c-bata Date: Mon, 11 Mar 2024 01:37:53 +0900 Subject: [PATCH 73/98] Use biome ci in standalone_app --- .eslintignore | 5 +- package.json | 4 +- standalone_app/src/browser_app_entry.tsx | 4 +- standalone_app/src/components/App.tsx | 16 +-- standalone_app/src/components/DataGrid.tsx | 20 ++-- standalone_app/src/components/PlotHistory.tsx | 19 +-- .../src/components/PlotImportance.tsx | 9 +- .../src/components/PlotIntermediateValues.tsx | 4 +- .../src/components/StorageLoader.tsx | 20 ++-- standalone_app/src/components/StudyDetail.tsx | 34 +++--- standalone_app/src/components/StudyList.tsx | 69 +++++------ standalone_app/src/components/TrialTable.tsx | 36 +++--- standalone_app/src/journalStorage.ts | 45 ++++--- standalone_app/src/sqlite3.ts | 113 ++++++++---------- standalone_app/src/vscode_entry.tsx | 10 +- 15 files changed, 209 insertions(+), 199 deletions(-) diff --git a/.eslintignore b/.eslintignore index 92ff5e55..8ca6e026 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,2 +1,3 @@ -venv/**/*.ts -venv/**/*.js \ No newline at end of file +venv +.venv +standalone_app \ No newline at end of file diff --git a/package.json b/package.json index bfefbb00..4785f085 100644 --- a/package.json +++ b/package.json @@ -6,9 +6,9 @@ "main": "index.js", "scripts": { "fmt": "biome format --write .", - "lint": "npm run lint:eslint && npm run lint:fmt", + "lint": "npm run lint:eslint && npm run lint:biome", "lint:eslint": "eslint . --ext .ts,.tsx --max-warnings 0", - "lint:fmt": "biome format .", + "lint:biome": "biome format . && biome ci standalone_app", "watch": "NODE_ENV=development TYPESCRIPT_LOADER=esbuild-loader webpack --watch", "build": "webpack", "build:dev": "NODE_ENV=development TYPESCRIPT_LOADER=esbuild-loader webpack", diff --git a/standalone_app/src/browser_app_entry.tsx b/standalone_app/src/browser_app_entry.tsx index 146198b1..705200cc 100644 --- a/standalone_app/src/browser_app_entry.tsx +++ b/standalone_app/src/browser_app_entry.tsx @@ -1,8 +1,8 @@ import React from "react" import ReactDOM from "react-dom/client" -import "./index.css" -import { App } from "./components/App" import { RecoilRoot } from "recoil" +import { App } from "./components/App" +import "./index.css" ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render( diff --git a/standalone_app/src/components/App.tsx b/standalone_app/src/components/App.tsx index fc24c7a1..0a9b0532 100644 --- a/standalone_app/src/components/App.tsx +++ b/standalone_app/src/components/App.tsx @@ -1,15 +1,15 @@ -import React, { FC, useMemo, useState, useEffect } from "react" -import { HashRouter as Router, Routes, Route } from "react-router-dom" -import { SnackbarProvider } from "notistack" -import blue from "@mui/material/colors/blue" -import pink from "@mui/material/colors/pink" import { - createTheme, - useMediaQuery, - ThemeProvider, Box, CssBaseline, + ThemeProvider, + createTheme, + useMediaQuery, } from "@mui/material" +import blue from "@mui/material/colors/blue" +import pink from "@mui/material/colors/pink" +import { SnackbarProvider } from "notistack" +import React, { FC, useMemo, useState, useEffect } from "react" +import { HashRouter as Router, Route, Routes } from "react-router-dom" import { StudyDetail } from "./StudyDetail" import { StudyList } from "./StudyList" diff --git a/standalone_app/src/components/DataGrid.tsx b/standalone_app/src/components/DataGrid.tsx index ec70e294..1d91883d 100644 --- a/standalone_app/src/components/DataGrid.tsx +++ b/standalone_app/src/components/DataGrid.tsx @@ -1,5 +1,9 @@ -import React from "react" +import { Clear } from "@mui/icons-material" +import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown" +import KeyboardArrowUpIcon from "@mui/icons-material/KeyboardArrowUp" import { + Collapse, + IconButton, Table, TableBody, TableCell, @@ -8,18 +12,14 @@ import { TablePagination, TableRow, TableSortLabel, - Collapse, - IconButton, useTheme, } from "@mui/material" import { styled } from "@mui/system" -import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown" -import KeyboardArrowUpIcon from "@mui/icons-material/KeyboardArrowUp" -import { Clear } from "@mui/icons-material" +import React from "react" type Order = "asc" | "desc" -// eslint-disable-next-line @typescript-eslint/no-explicit-any +// biome-ignore lint/suspicious/noExplicitAny: type Value = any const defaultRowsPerPageOption = [10, 50, 100, { label: "All", value: -1 }] @@ -97,7 +97,7 @@ function DataGrid(props: { } const filteredRows = rows.filter((row, rowIdx) => { - if (defaultFilter !== undefined && defaultFilter(row)) { + if (defaultFilter?.(row)) { return false } return filters.length === 0 @@ -162,6 +162,7 @@ function DataGrid(props: { {collapseBody ? : null} {columns.map((column, columnIdx) => ( key={columnIdx} padding={column.padding || "normal"} sortDirection={orderBy === column.field ? order : false} @@ -378,4 +379,5 @@ const isNumber = ( return typeof rowsPerPage === "number" } -export { DataGrid, DataGridColumn } +export { DataGrid } +export type { DataGridColumn } diff --git a/standalone_app/src/components/PlotHistory.tsx b/standalone_app/src/components/PlotHistory.tsx index b94c5ac8..44a65e49 100644 --- a/standalone_app/src/components/PlotHistory.tsx +++ b/standalone_app/src/components/PlotHistory.tsx @@ -1,20 +1,20 @@ -import * as plotly from "plotly.js-dist-min" -import React, { ChangeEvent, FC, useEffect, useState } from "react" import { - Grid, - FormControl, - FormLabel, - FormControlLabel, Checkbox, + FormControl, + FormControlLabel, + FormLabel, + Grid, MenuItem, - Switch, - Select, Radio, RadioGroup, - Typography, + Select, SelectChangeEvent, + Switch, + Typography, useTheme, } from "@mui/material" +import * as plotly from "plotly.js-dist-min" +import React, { ChangeEvent, FC, useEffect, useState } from "react" import { plotlyDarkTemplate } from "../PlotlyDarkMode" const plotDomId = "plot-history" @@ -91,6 +91,7 @@ export const PlotHistory: FC<{ Objective ID: