From aedae391816adb0a1609288ae5c0634f13602bd7 Mon Sep 17 00:00:00 2001 From: Alexandre Neuwald CTW <162589552+aneuwald-ctw@users.noreply.github.com> Date: Mon, 29 Jul 2024 15:59:17 +0100 Subject: [PATCH] Feature/load default layouts from local folder (#113) **User-Facing Changes** This pull request introduces the ability for the software to automatically load "default layouts" from the user's `~/.lichtblick/layouts` directory upon startup. This feature ensures that users have access to predefined layouts immediately after launching the application (desktop version). **Description** - Added functionality to load "default layouts" from the `~/.lichtblick/layouts` directory. This enables the software to open with pre-configured layouts already available. - Implemented a check to prevent duplicate uploads based on file names. If a file is renamed, it will be loaded again. If the file content is changed but the name remains the same, the software will not detect the change. - The software will load and save the files in memory. The layout functionality remains the same as before. New layouts created within the application will not be saved in the `~/.lichtblick/layouts` directory. - This feature works only for the desktop version, because modern browsers (web version) are not allowed to access local files, for security reasons. **Checklist** - [x] The web version was tested and it is running ok - [x] The desktop version was tested and it is running ok - [x] The release version was updated on package.json files --- package.json | 2 +- packages/studio-base/src/App.tsx | 5 +- packages/studio-base/src/index.ts | 3 + .../providers/LayoutManagerProvider.test.tsx | 304 ++++++ .../src/providers/LayoutManagerProvider.tsx | 59 +- .../studio-base/src/services/ILayoutLoader.ts | 14 + .../src/services/ILayoutStorage.ts | 1 + .../services/LayoutManager/LayoutManager.ts | 3 + .../LayoutManager/MockLayoutManager.ts | 26 + .../studio-base/src/services/migrateLayout.ts | 1 + packages/studio-base/src/types/layouts.ts | 11 + packages/studio-desktop/src/common/types.ts | 10 +- packages/studio-desktop/src/preload/index.ts | 6 + .../src/preload/layouts.test.ts | 108 +++ .../studio-desktop/src/preload/layouts.ts | 39 + packages/studio-desktop/src/renderer/Root.tsx | 5 + .../services/DesktopLayoutLoader.test.ts | 48 + .../renderer/services/DesktopLayoutLoader.ts | 32 + packages/studio/package.json | 2 +- yarn.lock | 862 ++++++++++-------- 20 files changed, 1144 insertions(+), 397 deletions(-) create mode 100644 packages/studio-base/src/providers/LayoutManagerProvider.test.tsx create mode 100644 packages/studio-base/src/services/ILayoutLoader.ts create mode 100644 packages/studio-base/src/services/LayoutManager/MockLayoutManager.ts create mode 100644 packages/studio-desktop/src/preload/layouts.test.ts create mode 100644 packages/studio-desktop/src/preload/layouts.ts create mode 100644 packages/studio-desktop/src/renderer/services/DesktopLayoutLoader.test.ts create mode 100644 packages/studio-desktop/src/renderer/services/DesktopLayoutLoader.ts diff --git a/package.json b/package.json index 557065769f..63a6aad318 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "lichtblick", - "version": "1.2.1", + "version": "1.3.0", "license": "MPL-2.0", "private": true, "productName": "Lichtblick", diff --git a/packages/studio-base/src/App.tsx b/packages/studio-base/src/App.tsx index 98e92bc4cd..9f5f9f80a4 100644 --- a/packages/studio-base/src/App.tsx +++ b/packages/studio-base/src/App.tsx @@ -16,6 +16,7 @@ import ProblemsContextProvider from "@foxglove/studio-base/providers/ProblemsCon import { StudioLogsSettingsProvider } from "@foxglove/studio-base/providers/StudioLogsSettingsProvider"; import TimelineInteractionStateProvider from "@foxglove/studio-base/providers/TimelineInteractionStateProvider"; import UserProfileLocalStorageProvider from "@foxglove/studio-base/providers/UserProfileLocalStorageProvider"; +import { LayoutLoader } from "@foxglove/studio-base/services/ILayoutLoader"; import Workspace from "./Workspace"; import { CustomWindowControlsProps } from "./components/AppBar/CustomWindowControls"; @@ -43,6 +44,7 @@ type AppProps = CustomWindowControlsProps & { appConfiguration: IAppConfiguration; dataSources: IDataSourceFactory[]; extensionLoaders: readonly ExtensionLoader[]; + layoutLoaders: readonly LayoutLoader[]; nativeAppMenu?: INativeAppMenu; nativeWindow?: INativeWindow; enableLaunchPreferenceScreen?: boolean; @@ -67,6 +69,7 @@ export function App(props: AppProps): JSX.Element { appConfiguration, dataSources, extensionLoaders, + layoutLoaders, nativeAppMenu, nativeWindow, deepLinks, @@ -106,7 +109,7 @@ export function App(props: AppProps): JSX.Element { providers.unshift(); providers.unshift(); providers.unshift(); - providers.unshift(); + providers.unshift(); const layoutStorage = useMemo(() => new IdbLayoutStorage(), []); providers.unshift(); diff --git a/packages/studio-base/src/index.ts b/packages/studio-base/src/index.ts index 53e0e81419..24136b22ba 100644 --- a/packages/studio-base/src/index.ts +++ b/packages/studio-base/src/index.ts @@ -29,6 +29,9 @@ export { default as overwriteFetch } from "./util/overwriteFetch"; export { default as waitForFonts } from "./util/waitForFonts"; export { initI18n } from "./i18n"; export type { ExtensionLoader } from "./services/ExtensionLoader"; +export type { LayoutLoader } from "./services/ILayoutLoader"; +export type { LayoutInfo } from "./types/layouts"; +export type { LayoutData } from "./context/CurrentLayoutContext"; export type { ExtensionInfo, ExtensionNamespace } from "./types/Extensions"; export { AppSetting } from "./AppSetting"; export { default as FoxgloveWebSocketDataSourceFactory } from "./dataSources/FoxgloveWebSocketDataSourceFactory"; diff --git a/packages/studio-base/src/providers/LayoutManagerProvider.test.tsx b/packages/studio-base/src/providers/LayoutManagerProvider.test.tsx new file mode 100644 index 0000000000..7f92c9b5d7 --- /dev/null +++ b/packages/studio-base/src/providers/LayoutManagerProvider.test.tsx @@ -0,0 +1,304 @@ +/** @jest-environment jsdom */ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/ + +import { render, waitFor } from "@testing-library/react"; +import { useNetworkState } from "react-use"; + +import { useVisibilityState } from "@foxglove/hooks"; +import { LayoutData } from "@foxglove/studio-base/context/CurrentLayoutContext"; +import { useLayoutStorage } from "@foxglove/studio-base/context/LayoutStorageContext"; +import { useRemoteLayoutStorage } from "@foxglove/studio-base/context/RemoteLayoutStorageContext"; +import LayoutManagerProvider from "@foxglove/studio-base/providers/LayoutManagerProvider"; +import { LayoutLoader } from "@foxglove/studio-base/services/ILayoutLoader"; +import MockLayoutManager from "@foxglove/studio-base/services/LayoutManager/MockLayoutManager"; + +// Mock dependencies +jest.mock("react-use"); +jest.mock("@foxglove/hooks"); +jest.mock("@foxglove/studio-base/context/LayoutStorageContext"); +jest.mock("@foxglove/studio-base/context/RemoteLayoutStorageContext"); + +const mockLayoutManager = new MockLayoutManager(); + +jest.mock("@foxglove/studio-base/services/LayoutManager/LayoutManager", () => + jest.fn(() => mockLayoutManager), +); + +describe("LayoutManagerProvider", () => { + const mockLayoutLoader: jest.Mocked = { + fetchLayouts: jest.fn(), + namespace: "local", + }; + + // Mock necessary hooks to render component, otherwise it will fail + (useNetworkState as jest.Mock).mockReturnValue({ online: true }); + (useVisibilityState as jest.Mock).mockReturnValue("visible"); + (useLayoutStorage as jest.Mock).mockReturnValue({}); + (useRemoteLayoutStorage as jest.Mock).mockReturnValue({}); + + const consoleErrorMock = console.error as ReturnType; + + beforeEach(() => { + jest.clearAllMocks(); + }); + + it("should call layoutManager.setOnline accordingly with useNetworkState", async () => { + (useNetworkState as jest.Mock).mockResolvedValueOnce({ online: false }); + + // 1 render with true and another with false. + render(); + render(); + + await waitFor(() => { + expect(mockLayoutManager.setOnline).toHaveBeenCalledTimes(2); + expect(mockLayoutManager.setOnline).toHaveBeenCalledWith(true); + expect(mockLayoutManager.setOnline).toHaveBeenCalledWith(false); + }); + }); + + it("should not call getLayouts or saveNewLayout if layout loaders is undefined or an empty array", async () => { + // 1 render with no loaders and another with empty array. + render(); + render(); + + await waitFor(() => { + expect(mockLayoutManager.getLayouts).toHaveBeenCalledTimes(0); + expect(mockLayoutManager.saveNewLayout).toHaveBeenCalledTimes(0); + }); + }); + + it("should not call layoutManager.saveNewLayout if there is no layouts", async () => { + mockLayoutLoader.fetchLayouts.mockResolvedValueOnce([]); + + render(); + + await waitFor(() => { + expect(mockLayoutManager.getLayouts).toHaveBeenCalledTimes(1); + expect(mockLayoutLoader.fetchLayouts).toHaveBeenCalledTimes(1); + expect(mockLayoutManager.saveNewLayout).toHaveBeenCalledTimes(0); + }); + }); + + it("should fetch layouts from loaders and save the new layouts", async () => { + mockLayoutLoader.fetchLayouts.mockResolvedValueOnce([ + { from: "layout1.json", name: "layout1", data: {} as LayoutData }, + { from: "layout2.json", name: "layout2", data: {} as LayoutData }, + ]); + + render(); + + await waitFor(() => { + // Should be called 2 times, because only one loader. + expect(mockLayoutLoader.fetchLayouts).toHaveBeenCalledTimes(1); + + // Should be called 1 time, once for all loaders. + expect(mockLayoutManager.getLayouts).toHaveBeenCalledTimes(1); + + // Expect all layouts to be saved. + expect(mockLayoutManager.saveNewLayout).toHaveBeenCalledTimes(2); + expect(mockLayoutManager.saveNewLayout).toHaveBeenCalledWith( + expect.objectContaining({ from: "layout1.json", name: "layout1" }), + ); + expect(mockLayoutManager.saveNewLayout).toHaveBeenCalledWith( + expect.objectContaining({ from: "layout2.json", name: "layout2" }), + ); + }); + }); + + it("should fetch layouts from multiple loaders and save the new layouts", async () => { + // Mock two loaders with different layouts. + mockLayoutLoader.fetchLayouts + .mockResolvedValueOnce([ + { from: "layout1.json", name: "layout1", data: {} as LayoutData }, + { from: "layout2.json", name: "layout2", data: {} as LayoutData }, + ]) + .mockResolvedValueOnce([ + { from: "layout3.json", name: "layout3", data: {} as LayoutData }, + { from: "layout4.json", name: "layout4", data: {} as LayoutData }, + ]); + + render(); + + await waitFor(() => { + // Should be called 2 times, one per loader. + expect(mockLayoutLoader.fetchLayouts).toHaveBeenCalledTimes(2); + + // Should be called 1 time, once for all loaders. + expect(mockLayoutManager.getLayouts).toHaveBeenCalledTimes(1); + + // Expect all layouts to be saved. + expect(mockLayoutManager.saveNewLayout).toHaveBeenCalledTimes(4); + + expect(mockLayoutManager.saveNewLayout).toHaveBeenCalledWith( + expect.objectContaining({ from: "layout1.json", name: "layout1" }), + ); + expect(mockLayoutManager.saveNewLayout).toHaveBeenCalledWith( + expect.objectContaining({ from: "layout2.json", name: "layout2" }), + ); + expect(mockLayoutManager.saveNewLayout).toHaveBeenCalledWith( + expect.objectContaining({ from: "layout3.json", name: "layout3" }), + ); + expect(mockLayoutManager.saveNewLayout).toHaveBeenCalledWith( + expect.objectContaining({ from: "layout4.json", name: "layout4" }), + ); + }); + }); + + it("should fetch layouts from loaders and not save duplicated layouts", async () => { + // Make layouts with same name, but different "from" + mockLayoutLoader.fetchLayouts.mockResolvedValueOnce([ + { from: "layout1.json", name: "layout", data: {} as LayoutData }, + { from: "layout2.json", name: "layout", data: {} as LayoutData }, + { from: "layout3.json", name: "layout", data: {} as LayoutData }, + ]); + + // Mock an existing layout with "from" equals to "layout2" + mockLayoutManager.getLayouts.mockResolvedValueOnce([{ from: "layout2.json", name: "layout" }]); + + render(); + + await waitFor(() => { + expect(mockLayoutLoader.fetchLayouts).toHaveBeenCalledTimes(1); + expect(mockLayoutManager.getLayouts).toHaveBeenCalledTimes(1); + + // Expect only "layout1.json" and "layout3.json" to be saved. + expect(mockLayoutManager.saveNewLayout).toHaveBeenCalledTimes(2); + + expect(mockLayoutManager.saveNewLayout).toHaveBeenCalledWith( + expect.objectContaining({ from: "layout1.json", name: "layout" }), + ); + expect(mockLayoutManager.saveNewLayout).toHaveBeenCalledWith( + expect.objectContaining({ from: "layout3.json", name: "layout" }), + ); + + // Expect "layout2.json" to not be saved, because it has been already loaded. + expect(mockLayoutManager.saveNewLayout).not.toHaveBeenCalledWith( + expect.objectContaining({ from: "layout2.json", name: "layout" }), + ); + }); + }); + + it("should log the correct error when fetchLayouts fails", async () => { + const errorMessage = "Failed to fetch layouts"; + const expectedError = `Failed to fetch layouts from loader: ${errorMessage}`; + + mockLayoutLoader.fetchLayouts.mockRejectedValueOnce(errorMessage); + + render(); + + await waitFor(() => { + expect(consoleErrorMock.mock.calls[0]).toContain(expectedError); + consoleErrorMock.mockClear(); + }); + }); + + it("should log the correct error when saveNewLayout fails", async () => { + const errorMessage = "Failed to save layout"; + const expectedError = `Failed to save layout: ${errorMessage}`; + + mockLayoutLoader.fetchLayouts.mockResolvedValueOnce([ + { from: "layout1.json", name: "layout1", data: {} as LayoutData }, + ]); + + mockLayoutManager.saveNewLayout.mockRejectedValueOnce(errorMessage); + + render(); + + await waitFor(() => { + expect(mockLayoutLoader.fetchLayouts).toHaveBeenCalledTimes(1); + expect(mockLayoutManager.getLayouts).toHaveBeenCalledTimes(1); + expect(mockLayoutManager.saveNewLayout).toHaveBeenCalledTimes(1); + expect(consoleErrorMock.mock.calls[0]).toContain(expectedError); + consoleErrorMock.mockClear(); + }); + }); + + it("should log the correct error when the entire loadAndSaveLayouts process fails", async () => { + const errorMessage = "General loading error"; + const expectedError = `Loading default layouts failed: ${errorMessage}`; + + mockLayoutManager.getLayouts.mockRejectedValueOnce(errorMessage); + + render(); + + await waitFor(() => { + expect(mockLayoutManager.getLayouts).toHaveBeenCalledTimes(1); + expect(mockLayoutLoader.fetchLayouts).toHaveBeenCalledTimes(0); + expect(consoleErrorMock.mock.calls[0]).toContain(expectedError); + consoleErrorMock.mockClear(); + }); + }); + + it("should handle partial successes and log correct errors", async () => { + const fetchErrorMessage = "Fetch failed"; + const expectedFetchError = `Failed to fetch layouts from loader: ${fetchErrorMessage}`; + + const saveErrorMessage = "Save failed"; + const expectedSaveError = `Failed to save layout: ${saveErrorMessage}`; + + const layouts = [ + { from: "layout1.json", name: "layout1", data: {} as LayoutData }, + { from: "layout2.json", name: "layout2", data: {} as LayoutData }, + ]; + + mockLayoutLoader.fetchLayouts + .mockResolvedValueOnce(layouts) + .mockRejectedValueOnce(fetchErrorMessage); + + mockLayoutManager.saveNewLayout + .mockResolvedValueOnce("sucess") + .mockRejectedValueOnce(saveErrorMessage); + + render(); + + await waitFor(() => { + expect(mockLayoutLoader.fetchLayouts).toHaveBeenCalledTimes(2); + expect(mockLayoutManager.getLayouts).toHaveBeenCalledTimes(1); + expect(mockLayoutManager.saveNewLayout).toHaveBeenCalledTimes(2); + expect(consoleErrorMock.mock.calls[0]).toContain(expectedFetchError); + expect(consoleErrorMock.mock.calls[1]).toContain(expectedSaveError); + + consoleErrorMock.mockClear(); + }); + }); + + it("should call layoutManager.syncWithRemote", async () => { + render(); + + await waitFor(() => { + expect(mockLayoutManager.syncWithRemote).toHaveBeenCalledTimes(1); + }); + }); + + it("should not call layoutManager.syncWithRemote if offline", async () => { + (useNetworkState as jest.Mock).mockReturnValueOnce({ online: false }); + + render(); + + await waitFor(() => { + expect(mockLayoutManager.syncWithRemote).toHaveBeenCalledTimes(0); + }); + }); + + it("should not call layoutManager.syncWithRemote if not visible", async () => { + (useVisibilityState as jest.Mock).mockReturnValueOnce("invisible"); + + render(); + + await waitFor(() => { + expect(mockLayoutManager.syncWithRemote).toHaveBeenCalledTimes(0); + }); + }); + + it("should not call layoutManager.syncWithRemote if there is not remote storage", async () => { + (useRemoteLayoutStorage as jest.Mock).mockReturnValueOnce(undefined); + + render(); + + await waitFor(() => { + expect(mockLayoutManager.syncWithRemote).toHaveBeenCalledTimes(0); + }); + }); +}); diff --git a/packages/studio-base/src/providers/LayoutManagerProvider.tsx b/packages/studio-base/src/providers/LayoutManagerProvider.tsx index 2df860b6e2..53de4ff4c1 100644 --- a/packages/studio-base/src/providers/LayoutManagerProvider.tsx +++ b/packages/studio-base/src/providers/LayoutManagerProvider.tsx @@ -10,6 +10,7 @@ import Logger from "@foxglove/log"; import LayoutManagerContext from "@foxglove/studio-base/context/LayoutManagerContext"; import { useLayoutStorage } from "@foxglove/studio-base/context/LayoutStorageContext"; import { useRemoteLayoutStorage } from "@foxglove/studio-base/context/RemoteLayoutStorageContext"; +import { LayoutLoader } from "@foxglove/studio-base/services/ILayoutLoader"; import LayoutManager from "@foxglove/studio-base/services/LayoutManager/LayoutManager"; import delay from "@foxglove/studio-base/util/delay"; @@ -18,7 +19,18 @@ const log = Logger.getLogger(__filename); const SYNC_INTERVAL_BASE_MS = 30_000; const SYNC_INTERVAL_MAX_MS = 3 * 60_000; -export default function LayoutManagerProvider({ children }: React.PropsWithChildren): JSX.Element { +const isFulfilled = (result: PromiseSettledResult): result is PromiseFulfilledResult => + result.status === "fulfilled"; + +const isRejected = (result: PromiseSettledResult): result is PromiseRejectedResult => + result.status === "rejected"; + +export default function LayoutManagerProvider({ + children, + loaders = [], +}: React.PropsWithChildren<{ + loaders?: readonly LayoutLoader[]; +}>): JSX.Element { const layoutStorage = useLayoutStorage(); const remoteLayoutStorage = useRemoteLayoutStorage(); @@ -33,6 +45,51 @@ export default function LayoutManagerProvider({ children }: React.PropsWithChild layoutManager.setOnline(online); }, [layoutManager, online]); + useEffect(() => { + if (loaders.length === 0) { + return; + } + + const loadAndSaveLayouts = async () => { + try { + const currentLayouts = await layoutManager.getLayouts(); + const currentLayoutsFroms = new Set(currentLayouts.map((layout) => layout.from)); + + const loaderPromises = loaders.map(async (loader) => await loader.fetchLayouts()); + const loaderResults = await Promise.allSettled(loaderPromises); + + const newLayouts = loaderResults + .filter(isFulfilled) + .flatMap((result) => result.value) + .filter((layout) => !currentLayoutsFroms.has(layout.from)); + + // Log errors cause failed to fetch some layout from a specific loader + loaderResults.filter(isRejected).forEach((result) => { + log.error(`Failed to fetch layouts from loader: ${result.reason}`); + }); + + const savedPromises = newLayouts.map( + async (layout) => + await layoutManager.saveNewLayout({ + ...layout, + permission: "CREATOR_WRITE", + }), + ); + + // Try to save all layouts + const saveResults = await Promise.allSettled(savedPromises); + + // Log errors cause failed to save a layout + saveResults.filter(isRejected).forEach((result) => { + log.error(`Failed to save layout: ${result.reason}`); + }); + } catch (err) { + log.error(`Loading default layouts failed: ${err}`); + } + }; + void loadAndSaveLayouts(); + }, [layoutManager, loaders]); + // Sync periodically when logged in, online, and the app is not hidden const enableSyncing = remoteLayoutStorage != undefined && online && visibilityState === "visible"; useEffect(() => { diff --git a/packages/studio-base/src/services/ILayoutLoader.ts b/packages/studio-base/src/services/ILayoutLoader.ts new file mode 100644 index 0000000000..c8a0ac18ae --- /dev/null +++ b/packages/studio-base/src/services/ILayoutLoader.ts @@ -0,0 +1,14 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/ + +import { LayoutInfo } from "@foxglove/studio-base/types/layouts"; + +/** + * LayoutLoader is an object used by lichtblick to load local layouts. + */ +export interface LayoutLoader { + readonly namespace: "local"; + + fetchLayouts: () => Promise; +} diff --git a/packages/studio-base/src/services/ILayoutStorage.ts b/packages/studio-base/src/services/ILayoutStorage.ts index b5f1212a38..eefeb86193 100644 --- a/packages/studio-base/src/services/ILayoutStorage.ts +++ b/packages/studio-base/src/services/ILayoutStorage.ts @@ -20,6 +20,7 @@ export type LayoutSyncStatus = export type Layout = { id: LayoutID; name: string; + from?: string; permission: LayoutPermission; /** @deprecated old field name, migrated to working/baseline */ diff --git a/packages/studio-base/src/services/LayoutManager/LayoutManager.ts b/packages/studio-base/src/services/LayoutManager/LayoutManager.ts index a7255c30ed..faa4e05292 100644 --- a/packages/studio-base/src/services/LayoutManager/LayoutManager.ts +++ b/packages/studio-base/src/services/LayoutManager/LayoutManager.ts @@ -220,10 +220,12 @@ export default class LayoutManager implements ILayoutManager { name, data: unmigratedData, permission, + from, }: { name: string; data: LayoutData; permission: LayoutPermission; + from?: string; }): Promise { const data = migratePanelsState(unmigratedData); if (layoutPermissionIsShared(permission)) { @@ -260,6 +262,7 @@ export default class LayoutManager implements ILayoutManager { await local.put({ id: uuidv4() as LayoutID, name, + from, permission, baseline: { data, savedAt: new Date().toISOString() as ISO8601Timestamp }, working: undefined, diff --git a/packages/studio-base/src/services/LayoutManager/MockLayoutManager.ts b/packages/studio-base/src/services/LayoutManager/MockLayoutManager.ts new file mode 100644 index 0000000000..71d218a6eb --- /dev/null +++ b/packages/studio-base/src/services/LayoutManager/MockLayoutManager.ts @@ -0,0 +1,26 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/ + +import { ILayoutManager } from "@foxglove/studio-base/services/ILayoutManager"; + +export default class MockLayoutManager implements ILayoutManager { + public supportsSharing = false; + public isBusy = false; + public isOnline = false; + public error: Error | undefined = undefined; + + public on = jest.fn(); + public off = jest.fn(); + public setError = jest.fn(); + public setOnline = jest.fn(); + public getLayouts = jest.fn().mockResolvedValue([]); + public getLayout = jest.fn(); + public saveNewLayout = jest.fn(); + public updateLayout = jest.fn(); + public deleteLayout = jest.fn(); + public overwriteLayout = jest.fn(); + public revertLayout = jest.fn(); + public makePersonalCopy = jest.fn(); + public syncWithRemote = jest.fn(); +} diff --git a/packages/studio-base/src/services/migrateLayout.ts b/packages/studio-base/src/services/migrateLayout.ts index ee4e18441f..f597dee4ac 100644 --- a/packages/studio-base/src/services/migrateLayout.ts +++ b/packages/studio-base/src/services/migrateLayout.ts @@ -54,6 +54,7 @@ export function migrateLayout(value: unknown): Layout { return { id: layout.id, + from: layout.from, name: layout.name ?? `Unnamed (${now})`, permission: layout.permission?.toUpperCase() ?? "CREATOR_WRITE", working: layout.working diff --git a/packages/studio-base/src/types/layouts.ts b/packages/studio-base/src/types/layouts.ts index 37ce3926b6..68b9f99d0e 100644 --- a/packages/studio-base/src/types/layouts.ts +++ b/packages/studio-base/src/types/layouts.ts @@ -13,6 +13,8 @@ import { MosaicNode } from "react-mosaic-component"; +import { LayoutData } from "@foxglove/studio-base/context/CurrentLayoutContext"; + export type TabConfig = { title: string; layout?: MosaicNode }; export type TabPanelConfig = { @@ -24,3 +26,12 @@ export type TabLocation = { panelId: string; tabIndex?: number; }; + +/** + * Metadata describing a layout. + */ +export type LayoutInfo = { + name: string; + from: string; + data: LayoutData; +}; diff --git a/packages/studio-desktop/src/common/types.ts b/packages/studio-desktop/src/common/types.ts index afbf50c0c5..f057b99487 100644 --- a/packages/studio-desktop/src/common/types.ts +++ b/packages/studio-desktop/src/common/types.ts @@ -67,6 +67,11 @@ type DesktopExtension = { directory: string; }; +type DesktopLayout = { + layoutJson: unknown; + from: string; +}; + interface Desktop { /** https://www.electronjs.org/docs/tutorial/represented-file */ setRepresentedFilename(path: string | undefined): Promise; @@ -91,6 +96,9 @@ interface Desktop { // Load the source code for an extension loadExtension: (id: string) => Promise; + // Fetch default layouts from local folder + fetchLayouts: () => Promise; + // Install a Lichtblick extension (.foxe file) locally. The extension id is returned installExtension: (foxeFileData: Uint8Array) => Promise; @@ -112,4 +120,4 @@ interface Desktop { updateLanguage(): void; } -export type { Desktop, DesktopExtension, NativeMenuBridge, Storage, StorageContent }; +export type { Desktop, DesktopExtension, DesktopLayout, NativeMenuBridge, Storage, StorageContent }; diff --git a/packages/studio-desktop/src/preload/index.ts b/packages/studio-desktop/src/preload/index.ts index 21a55a1e9a..71c3522e86 100644 --- a/packages/studio-desktop/src/preload/index.ts +++ b/packages/studio-desktop/src/preload/index.ts @@ -12,6 +12,7 @@ import { NetworkInterface, OsContext } from "@foxglove/studio-base/src/OsContext import LocalFileStorage from "./LocalFileStorage"; import { getExtensions, loadExtension, installExtension, uninstallExtension } from "./extensions"; +import { fetchLayouts } from "./layouts"; import { decodeRendererArg } from "../common/rendererArgs"; import { Desktop, @@ -136,6 +137,11 @@ export function main(): void { const userExtensionRoot = pathJoin(homePath, ".foxglove-studio", "extensions"); return await loadExtension(id, userExtensionRoot); }, + async fetchLayouts() { + const homePath = (await ipcRenderer.invoke("getHomePath")) as string; + const userExtensionRoot = pathJoin(homePath, ".lichtblick", "layouts"); + return await fetchLayouts(userExtensionRoot); + }, async installExtension(foxeFileData: Uint8Array) { const homePath = (await ipcRenderer.invoke("getHomePath")) as string; const userExtensionRoot = pathJoin(homePath, ".foxglove-studio", "extensions"); diff --git a/packages/studio-desktop/src/preload/layouts.test.ts b/packages/studio-desktop/src/preload/layouts.test.ts new file mode 100644 index 0000000000..413208c608 --- /dev/null +++ b/packages/studio-desktop/src/preload/layouts.test.ts @@ -0,0 +1,108 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/ + +import { existsSync, Dirent } from "fs"; +import { readFile, readdir } from "fs/promises"; + +import { fetchLayouts } from "./layouts"; + +// Mock fs methods +jest.mock("fs", () => ({ + existsSync: jest.fn(), +})); + +jest.mock("fs/promises", () => ({ + readdir: jest.fn(), + readFile: jest.fn(), +})); + +describe("fetchLayouts", () => { + const mockExistsSync = existsSync as jest.MockedFunction; + const mockReaddir = readdir as jest.MockedFunction; + const mockReadFile = readFile as jest.MockedFunction; + + beforeEach(() => { + jest.clearAllMocks(); + }); + + it("should return an empty array if root folder does not exist", async () => { + mockExistsSync.mockReturnValueOnce(false); + + const result = await fetchLayouts("/non/existent/path"); + + expect(result).toEqual([]); + }); + + it("should return layouts from valid JSON files in the root folder", async () => { + const mockFiles = [ + { name: "layout1.json", isFile: () => true }, + { name: "layout2.json", isFile: () => true }, + ]; + const mockLayout1 = { some: "data1" }; + const mockLayout2 = { some: "data2" }; + + mockExistsSync.mockReturnValueOnce(true); + mockReaddir.mockResolvedValueOnce(mockFiles as Dirent[]); + mockReadFile + .mockResolvedValueOnce(JSON.stringify(mockLayout1)!) + .mockResolvedValueOnce(JSON.stringify(mockLayout2)!); + + const result = await fetchLayouts("/valid/path"); + + expect(result).toEqual([ + { from: "layout1.json", layoutJson: mockLayout1 }, + { from: "layout2.json", layoutJson: mockLayout2 }, + ]); + }); + + it("should skip non-JSON files", async () => { + const mockFiles = [ + { name: "layout1.json", isFile: () => true }, + { name: "not_a_json.txt", isFile: () => true }, + ]; + const mockLayout1 = { some: "data1" }; + + mockExistsSync.mockReturnValueOnce(true); + mockReaddir.mockResolvedValueOnce(mockFiles as Dirent[]); + mockReadFile.mockResolvedValueOnce(JSON.stringify(mockLayout1)!); + + const result = await fetchLayouts("/valid/path"); + + expect(result).toEqual([{ from: "layout1.json", layoutJson: mockLayout1 }]); + }); + + it("should ignore a directory end with .json in the name", async () => { + const mockFiles = [ + { name: "layout1.json", isFile: () => true }, + { name: "folder.json", isFile: () => false }, + ]; + const mockLayout1 = { some: "data1" }; + + mockExistsSync.mockReturnValueOnce(true); + mockReaddir.mockResolvedValueOnce(mockFiles as Dirent[]); + mockReadFile.mockResolvedValueOnce(JSON.stringify(mockLayout1)!); + + const result = await fetchLayouts("/valid/path"); + + expect(result).toEqual([{ from: "layout1.json", layoutJson: mockLayout1 }]); + }); + + it("should handle errors reading a file gracefully", async () => { + const mockFiles = [ + { name: "layout1.json", isFile: () => true }, + { name: "layout2.json", isFile: () => true }, + ]; + const mockLayout1 = { some: "data1" }; + + mockExistsSync.mockReturnValueOnce(true); + mockReaddir.mockResolvedValueOnce(mockFiles as Dirent[]); + mockReadFile + .mockResolvedValueOnce(JSON.stringify(mockLayout1)!) + .mockRejectedValueOnce(new Error("read error")); + + const result = await fetchLayouts("/valid/path"); + + expect(result).toEqual([{ from: "layout1.json", layoutJson: mockLayout1 }]); + }); +}); diff --git a/packages/studio-desktop/src/preload/layouts.ts b/packages/studio-desktop/src/preload/layouts.ts new file mode 100644 index 0000000000..d55d79d1b1 --- /dev/null +++ b/packages/studio-desktop/src/preload/layouts.ts @@ -0,0 +1,39 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/ + +import { existsSync } from "fs"; +import { readdir, readFile } from "fs/promises"; +import { join as pathJoin } from "path"; + +import Logger from "@foxglove/log"; + +import { DesktopLayout } from "../common/types"; + +const log = Logger.getLogger(__filename); + +export async function fetchLayouts(rootFolder: string): Promise { + const layouts: DesktopLayout[] = []; + + if (!existsSync(rootFolder)) { + return layouts; + } + + const rootFolderContents = await readdir(rootFolder, { withFileTypes: true }); + + for (const entry of rootFolderContents) { + if (!entry.isFile() || !entry.name.endsWith(".json")) { + continue; + } + try { + const layoutPath = pathJoin(rootFolder, entry.name); + const layoutData = await readFile(layoutPath, { encoding: "utf8" }); + + layouts.push({ from: entry.name, layoutJson: JSON.parse(layoutData) }); + } catch (err) { + log.error(err); + } + } + + return layouts; +} diff --git a/packages/studio-desktop/src/renderer/Root.tsx b/packages/studio-desktop/src/renderer/Root.tsx index 0c744c11ab..9b03f3ed99 100644 --- a/packages/studio-desktop/src/renderer/Root.tsx +++ b/packages/studio-desktop/src/renderer/Root.tsx @@ -24,6 +24,7 @@ import { } from "@foxglove/studio-base"; import { DesktopExtensionLoader } from "./services/DesktopExtensionLoader"; +import { DesktopLayoutLoader } from "./services/DesktopLayoutLoader"; import { NativeAppMenu } from "./services/NativeAppMenu"; import { NativeWindow } from "./services/NativeWindow"; import { Desktop, NativeMenuBridge, Storage } from "../common/types"; @@ -68,6 +69,9 @@ export default function Root(props: { new IdbExtensionLoader("org"), new DesktopExtensionLoader(desktopBridge), ]); + + const [layoutLoaders] = useState(() => [new DesktopLayoutLoader(desktopBridge)]); + const nativeAppMenu = useMemo(() => new NativeAppMenu(menuBridge), []); const nativeWindow = useMemo(() => new NativeWindow(desktopBridge), []); @@ -147,6 +151,7 @@ export default function Root(props: { dataSources={dataSources} appConfiguration={appConfiguration} extensionLoaders={extensionLoaders} + layoutLoaders={layoutLoaders} nativeAppMenu={nativeAppMenu} nativeWindow={nativeWindow} enableGlobalCss diff --git a/packages/studio-desktop/src/renderer/services/DesktopLayoutLoader.test.ts b/packages/studio-desktop/src/renderer/services/DesktopLayoutLoader.test.ts new file mode 100644 index 0000000000..89f447b046 --- /dev/null +++ b/packages/studio-desktop/src/renderer/services/DesktopLayoutLoader.test.ts @@ -0,0 +1,48 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/ + +import { DesktopLayoutLoader } from "./DesktopLayoutLoader"; +import { Desktop } from "../../common/types"; + +describe("DesktopLayoutLoader", () => { + const mockBridge = { + fetchLayouts: jest.fn(), + } as unknown as jest.Mocked; + + beforeEach(() => { + jest.clearAllMocks(); + }); + + it("should return correct layouts", async () => { + mockBridge.fetchLayouts.mockResolvedValueOnce([ + { from: "layout1.json", layoutJson: { some: "data" } }, + { from: "layout2.json", layoutJson: { other: "data" } }, + ]); + + const loader = new DesktopLayoutLoader(mockBridge); + const result = await loader.fetchLayouts(); + + expect(result).toEqual([ + { + from: "layout1.json", + name: "layout1", + data: { some: "data" }, + }, + { + from: "layout2.json", + name: "layout2", + data: { other: "data" }, + }, + ]); + }); + + it("should return an empty array if no layouts are found", async () => { + mockBridge.fetchLayouts.mockResolvedValueOnce([]); + + const loader = new DesktopLayoutLoader(mockBridge); + const result = await loader.fetchLayouts(); + + expect(result).toEqual([]); + }); +}); diff --git a/packages/studio-desktop/src/renderer/services/DesktopLayoutLoader.ts b/packages/studio-desktop/src/renderer/services/DesktopLayoutLoader.ts new file mode 100644 index 0000000000..2da65eda35 --- /dev/null +++ b/packages/studio-desktop/src/renderer/services/DesktopLayoutLoader.ts @@ -0,0 +1,32 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/ + +import Logger from "@foxglove/log"; +import { LayoutLoader, LayoutInfo, LayoutData } from "@foxglove/studio-base"; + +import { Desktop } from "../../common/types"; + +const log = Logger.getLogger(__filename); + +export class DesktopLayoutLoader implements LayoutLoader { + #bridge?: Desktop; + public readonly namespace = "local"; + + public constructor(bridge: Desktop) { + this.#bridge = bridge; + } + + public fetchLayouts = async (): Promise => { + const desktopLayouts = (await this.#bridge?.fetchLayouts()) ?? []; + log.debug(`Loaded ${desktopLayouts.length} layout(s)`); + + const formattedLayouts = desktopLayouts.map((desktopLayout) => ({ + from: desktopLayout.from, + name: desktopLayout.from.replace(".json", ""), + data: desktopLayout.layoutJson as LayoutData, + })); + + return formattedLayouts; + }; +} diff --git a/packages/studio/package.json b/packages/studio/package.json index a091ad0630..b5ded88910 100644 --- a/packages/studio/package.json +++ b/packages/studio/package.json @@ -1,6 +1,6 @@ { "name": "@foxglove/studio", - "version": "1.2.1", + "version": "1.3.0", "license": "MPL-2.0", "repository": { "type": "git", diff --git a/yarn.lock b/yarn.lock index 12ac422ba0..928b13aa97 100644 --- a/yarn.lock +++ b/yarn.lock @@ -100,10 +100,10 @@ __metadata: languageName: node linkType: hard -"@babel/compat-data@npm:^7.22.6, @babel/compat-data@npm:^7.24.8": - version: 7.24.9 - resolution: "@babel/compat-data@npm:7.24.9" - checksum: 3590be0f7028bca0565a83f66752c0f0283b818e9e1bb7fc12912822768e379a6ff84c59d77dc64ba62c140b8500a3828d95c0ce013cd62d254a179bae38709b +"@babel/compat-data@npm:^7.22.6, @babel/compat-data@npm:^7.24.8, @babel/compat-data@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/compat-data@npm:7.25.0" + checksum: 2ddcf8517f15eb03a712707b5d4fb146e4db44f8ebd821c29ca19f2808ee2f013c7b2c1d5d686b255ffbfa417368d61ee563ccd5d3639ed4293ce308a5d5d481 languageName: node linkType: hard @@ -130,15 +130,15 @@ __metadata: languageName: node linkType: hard -"@babel/generator@npm:^7.23.0, @babel/generator@npm:^7.24.8, @babel/generator@npm:^7.24.9, @babel/generator@npm:^7.7.2": - version: 7.24.10 - resolution: "@babel/generator@npm:7.24.10" +"@babel/generator@npm:^7.23.0, @babel/generator@npm:^7.24.9, @babel/generator@npm:^7.25.0, @babel/generator@npm:^7.7.2": + version: 7.25.0 + resolution: "@babel/generator@npm:7.25.0" dependencies: - "@babel/types": ^7.24.9 + "@babel/types": ^7.25.0 "@jridgewell/gen-mapping": ^0.3.5 "@jridgewell/trace-mapping": ^0.3.25 jsesc: ^2.5.1 - checksum: eb13806e9eb76932ea5205502a85ea650a991c7a6f757fbe859176f6d9b34b3da5a2c1f52a2c24fdbe0045a90438fe6889077e338cdd6c727619dee925af1ba6 + checksum: bf25649dde4068bff8e387319bf820f2cb3b1af7b8c0cfba0bd90880656427c8bad96cd5cb6db7058d20cffe93149ee59da16567018ceaa21ecaefbf780a785c languageName: node linkType: hard @@ -174,35 +174,33 @@ __metadata: languageName: node linkType: hard -"@babel/helper-create-class-features-plugin@npm:^7.24.7, @babel/helper-create-class-features-plugin@npm:^7.24.8": - version: 7.24.8 - resolution: "@babel/helper-create-class-features-plugin@npm:7.24.8" +"@babel/helper-create-class-features-plugin@npm:^7.24.7, @babel/helper-create-class-features-plugin@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/helper-create-class-features-plugin@npm:7.25.0" dependencies: "@babel/helper-annotate-as-pure": ^7.24.7 - "@babel/helper-environment-visitor": ^7.24.7 - "@babel/helper-function-name": ^7.24.7 "@babel/helper-member-expression-to-functions": ^7.24.8 "@babel/helper-optimise-call-expression": ^7.24.7 - "@babel/helper-replace-supers": ^7.24.7 + "@babel/helper-replace-supers": ^7.25.0 "@babel/helper-skip-transparent-expression-wrappers": ^7.24.7 - "@babel/helper-split-export-declaration": ^7.24.7 + "@babel/traverse": ^7.25.0 semver: ^6.3.1 peerDependencies: "@babel/core": ^7.0.0 - checksum: b4707e2c4a2cb504d7656168d887bf653db6fbe8ece4502e28e5798f2ec624dc606f2d6bc4820d31b4dc1b80f7d83d98db83516dda321a76c075e5f531abed0b + checksum: e986c1187e16837b71f12920bd77e672b4bc19ac6dfe30b9d9d515a311c5cc5a085a8e337ac8597b1cb7bd0efdbfcc66f69bf652786c9a022070f9b782deec0d languageName: node linkType: hard -"@babel/helper-create-regexp-features-plugin@npm:^7.18.6, @babel/helper-create-regexp-features-plugin@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/helper-create-regexp-features-plugin@npm:7.24.7" +"@babel/helper-create-regexp-features-plugin@npm:^7.18.6, @babel/helper-create-regexp-features-plugin@npm:^7.24.7, @babel/helper-create-regexp-features-plugin@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/helper-create-regexp-features-plugin@npm:7.25.0" dependencies: "@babel/helper-annotate-as-pure": ^7.24.7 regexpu-core: ^5.3.1 semver: ^6.3.1 peerDependencies: "@babel/core": ^7.0.0 - checksum: 17c59fa222af50f643946eca940ce1d474ff2da1f4afed2312687ab9d708ebbb8c9372754ddbdf44b6e21ead88b8fc144644f3a7b63ccb886de002458cef3974 + checksum: eff1edbcffa53f361275bfb4449580fe307fafc76d6e7d30d53638198c92462d797f817ccd5624506d42704051a37b29cb6c2a8441c4ea1ee75a5898975f151e languageName: node linkType: hard @@ -221,35 +219,7 @@ __metadata: languageName: node linkType: hard -"@babel/helper-environment-visitor@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/helper-environment-visitor@npm:7.24.7" - dependencies: - "@babel/types": ^7.24.7 - checksum: 079d86e65701b29ebc10baf6ed548d17c19b808a07aa6885cc141b690a78581b180ee92b580d755361dc3b16adf975b2d2058b8ce6c86675fcaf43cf22f2f7c6 - languageName: node - linkType: hard - -"@babel/helper-function-name@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/helper-function-name@npm:7.24.7" - dependencies: - "@babel/template": ^7.24.7 - "@babel/types": ^7.24.7 - checksum: 142ee08922074dfdc0ff358e09ef9f07adf3671ab6eef4fca74dcf7a551f1a43717e7efa358c9e28d7eea84c28d7f177b7a58c70452fc312ae3b1893c5dab2a4 - languageName: node - linkType: hard - -"@babel/helper-hoist-variables@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/helper-hoist-variables@npm:7.24.7" - dependencies: - "@babel/types": ^7.24.7 - checksum: 6cfdcf2289cd12185dcdbdf2435fa8d3447b797ac75851166de9fc8503e2fd0021db6baf8dfbecad3753e582c08e6a3f805c8d00cbed756060a877d705bd8d8d - languageName: node - linkType: hard - -"@babel/helper-member-expression-to-functions@npm:^7.24.7, @babel/helper-member-expression-to-functions@npm:^7.24.8": +"@babel/helper-member-expression-to-functions@npm:^7.24.8": version: 7.24.8 resolution: "@babel/helper-member-expression-to-functions@npm:7.24.8" dependencies: @@ -269,18 +239,17 @@ __metadata: languageName: node linkType: hard -"@babel/helper-module-transforms@npm:^7.24.7, @babel/helper-module-transforms@npm:^7.24.8, @babel/helper-module-transforms@npm:^7.24.9": - version: 7.24.9 - resolution: "@babel/helper-module-transforms@npm:7.24.9" +"@babel/helper-module-transforms@npm:^7.24.7, @babel/helper-module-transforms@npm:^7.24.8, @babel/helper-module-transforms@npm:^7.24.9, @babel/helper-module-transforms@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/helper-module-transforms@npm:7.25.0" dependencies: - "@babel/helper-environment-visitor": ^7.24.7 "@babel/helper-module-imports": ^7.24.7 "@babel/helper-simple-access": ^7.24.7 - "@babel/helper-split-export-declaration": ^7.24.7 "@babel/helper-validator-identifier": ^7.24.7 + "@babel/traverse": ^7.25.0 peerDependencies: "@babel/core": ^7.0.0 - checksum: ffcf11b678a8d3e6a243285cb5262c37f4d47d507653420c1f7f0bd27076e88177f2b7158850d1a470fcfe923426a2e6571c554c455a90c9755ff488ac36ac40 + checksum: 12270fe101a03e46e68d8166aca423c829472f735cd40b674a50c3061954475c840b0baee57ba546d5a51796715e0db8f781f556fb93e71529e5343bd3b6bd57 languageName: node linkType: hard @@ -300,29 +269,29 @@ __metadata: languageName: node linkType: hard -"@babel/helper-remap-async-to-generator@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/helper-remap-async-to-generator@npm:7.24.7" +"@babel/helper-remap-async-to-generator@npm:^7.24.7, @babel/helper-remap-async-to-generator@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/helper-remap-async-to-generator@npm:7.25.0" dependencies: "@babel/helper-annotate-as-pure": ^7.24.7 - "@babel/helper-environment-visitor": ^7.24.7 - "@babel/helper-wrap-function": ^7.24.7 + "@babel/helper-wrap-function": ^7.25.0 + "@babel/traverse": ^7.25.0 peerDependencies: "@babel/core": ^7.0.0 - checksum: bab7be178f875350f22a2cb9248f67fe3a8a8128db77a25607096ca7599fd972bc7049fb11ed9e95b45a3f1dd1fac3846a3279f9cbac16f337ecb0e6ca76e1fc + checksum: 47f3065e43fe9d6128ddb4291ffb9cf031935379265fd13de972b5f241943121f7583efb69cd2e1ecf39e3d0f76f047547d56c3fcc2c853b326fad5465da0bd7 languageName: node linkType: hard -"@babel/helper-replace-supers@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/helper-replace-supers@npm:7.24.7" +"@babel/helper-replace-supers@npm:^7.24.7, @babel/helper-replace-supers@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/helper-replace-supers@npm:7.25.0" dependencies: - "@babel/helper-environment-visitor": ^7.24.7 - "@babel/helper-member-expression-to-functions": ^7.24.7 + "@babel/helper-member-expression-to-functions": ^7.24.8 "@babel/helper-optimise-call-expression": ^7.24.7 + "@babel/traverse": ^7.25.0 peerDependencies: "@babel/core": ^7.0.0 - checksum: 2bf0d113355c60d86a04e930812d36f5691f26c82d4ec1739e5ec0a4c982c9113dad3167f7c74f888a96328bd5e696372232406d8200e5979e6e0dc2af5e7c76 + checksum: f669fc2487c22d40b808f94b9c3ee41129484d5ef0ba689bdd70f216ff91e10b6b021d2f8cd37e7bdd700235a2a6ae6622526344f064528190383bf661ac65f8 languageName: node linkType: hard @@ -346,15 +315,6 @@ __metadata: languageName: node linkType: hard -"@babel/helper-split-export-declaration@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/helper-split-export-declaration@npm:7.24.7" - dependencies: - "@babel/types": ^7.24.7 - checksum: e3ddc91273e5da67c6953f4aa34154d005a00791dc7afa6f41894e768748540f6ebcac5d16e72541aea0c89bee4b89b4da6a3d65972a0ea8bfd2352eda5b7e22 - languageName: node - linkType: hard - "@babel/helper-string-parser@npm:^7.24.8": version: 7.24.8 resolution: "@babel/helper-string-parser@npm:7.24.8" @@ -376,25 +336,24 @@ __metadata: languageName: node linkType: hard -"@babel/helper-wrap-function@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/helper-wrap-function@npm:7.24.7" +"@babel/helper-wrap-function@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/helper-wrap-function@npm:7.25.0" dependencies: - "@babel/helper-function-name": ^7.24.7 - "@babel/template": ^7.24.7 - "@babel/traverse": ^7.24.7 - "@babel/types": ^7.24.7 - checksum: 085bf130ed08670336e3976f5841ae44e3e10001131632e22ef234659341978d2fd37e65785f59b6cb1745481347fc3bce84b33a685cacb0a297afbe1d2b03af + "@babel/template": ^7.25.0 + "@babel/traverse": ^7.25.0 + "@babel/types": ^7.25.0 + checksum: 0095b4741704066d1687f9bbd5370bb88c733919e4275e49615f70c180208148ff5f24ab58d186ce92f8f5d28eab034ec6617e9264590cc4744c75302857629c languageName: node linkType: hard "@babel/helpers@npm:^7.24.8": - version: 7.24.8 - resolution: "@babel/helpers@npm:7.24.8" + version: 7.25.0 + resolution: "@babel/helpers@npm:7.25.0" dependencies: - "@babel/template": ^7.24.7 - "@babel/types": ^7.24.8 - checksum: 2d7301b1b9c91e518c4766bae171230e243d98461c15eabbd44f8f9c83c297fad5c4a64ad80cfec9ca8e90412fc2b41ee86d7eb35dc8a7611c268bcf1317fe46 + "@babel/template": ^7.25.0 + "@babel/types": ^7.25.0 + checksum: 739e3704ff41a30f5eaac469b553f4d3ab02be6ced083f5925851532dfbd9efc5c347728e77b754ed0b262a4e5e384e60932a62c192d338db7e4b7f3adf9f4a7 languageName: node linkType: hard @@ -410,35 +369,46 @@ __metadata: languageName: node linkType: hard -"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.23.0, @babel/parser@npm:^7.23.9, @babel/parser@npm:^7.24.7, @babel/parser@npm:^7.24.8": - version: 7.24.8 - resolution: "@babel/parser@npm:7.24.8" +"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.23.0, @babel/parser@npm:^7.23.9, @babel/parser@npm:^7.24.7, @babel/parser@npm:^7.24.8, @babel/parser@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/parser@npm:7.25.0" bin: parser: ./bin/babel-parser.js - checksum: 76f866333bfbd53800ac027419ae523bb0137fc63daa968232eb780e4390136bb6e497cb4a2cf6051a2c318aa335c2e6d2adc17079d60691ae7bde89b28c5688 + checksum: e0f0f5a0d323c8ebaa7caa5a982ce82a87d1f7176939642020beed021024af523e69e30b8918be82d02666742dfe0aad562c65edfd1a696785d76a2882e7904c languageName: node linkType: hard -"@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:7.24.7" +"@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:^7.24.7, @babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:7.25.0" dependencies: - "@babel/helper-environment-visitor": ^7.24.7 - "@babel/helper-plugin-utils": ^7.24.7 + "@babel/helper-plugin-utils": ^7.24.8 + "@babel/traverse": ^7.25.0 peerDependencies: "@babel/core": ^7.0.0 - checksum: 68d315642b53af143aa17a71eb976cf431b51339aee584e29514a462b81c998636dd54219c2713b5f13e1df89eaf130dfab59683f9116825608708c81696b96c + checksum: d33738813ac3ed45322da80e8111b18303f6ea39e703c271eeb8cc23163f5fc7c16ed7dfdc9489b2e31bd6a620c806db2edfc719b7a91f340b64921a3d304024 languageName: node linkType: hard -"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:7.24.7" +"@babel/plugin-bugfix-safari-class-field-initializer-scope@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/plugin-bugfix-safari-class-field-initializer-scope@npm:7.25.0" dependencies: - "@babel/helper-plugin-utils": ^7.24.7 + "@babel/helper-plugin-utils": ^7.24.8 + peerDependencies: + "@babel/core": ^7.0.0 + checksum: fd56d1e6435f2c008ca9050ea906ff7eedcbec43f532f2bf2e7e905d8bf75bf5e4295ea9593f060394e2c8e45737266ccbf718050bad2dd7be4e7613c60d1b5b + languageName: node + linkType: hard + +"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:^7.24.7, @babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:7.25.0" + dependencies: + "@babel/helper-plugin-utils": ^7.24.8 peerDependencies: "@babel/core": ^7.0.0 - checksum: 7eb4e7ce5e3d6db4b0fdbdfaaa301c2e58f38a7ee39d5a4259a1fda61a612e83d3e4bc90fc36fb0345baf57e1e1a071e0caffeb80218623ad163f2fdc2e53a54 + checksum: 13ed301b108d85867d64226bbc4032b07dd1a23aab68e9e32452c4fe3930f2198bb65bdae9c262c4104bd5e45647bc1830d25d43d356ee9a137edd8d5fab8350 languageName: node linkType: hard @@ -455,15 +425,15 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:7.24.7" +"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:^7.24.7, @babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:7.25.0" dependencies: - "@babel/helper-environment-visitor": ^7.24.7 - "@babel/helper-plugin-utils": ^7.24.7 + "@babel/helper-plugin-utils": ^7.24.8 + "@babel/traverse": ^7.25.0 peerDependencies: "@babel/core": ^7.0.0 - checksum: 8324d458db57060590942c7c2e9603880d07718ccb6450ec935105b8bd3c4393c4b8ada88e178c232258d91f33ffdcf2b1043d54e07a86989e50667ee100a32e + checksum: c8d08b8d6cc71451ad2a50cf7db72ab5b41c1e5e2e4d56cf6837a25a61270abd682c6b8881ab025f11a552d2024b3780519bb051459ebb71c27aed13d9917663 languageName: node linkType: hard @@ -777,17 +747,17 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-async-generator-functions@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-async-generator-functions@npm:7.24.7" +"@babel/plugin-transform-async-generator-functions@npm:^7.24.7, @babel/plugin-transform-async-generator-functions@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/plugin-transform-async-generator-functions@npm:7.25.0" dependencies: - "@babel/helper-environment-visitor": ^7.24.7 - "@babel/helper-plugin-utils": ^7.24.7 - "@babel/helper-remap-async-to-generator": ^7.24.7 + "@babel/helper-plugin-utils": ^7.24.8 + "@babel/helper-remap-async-to-generator": ^7.25.0 "@babel/plugin-syntax-async-generators": ^7.8.4 + "@babel/traverse": ^7.25.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 112e3b18f9c496ebc01209fc27f0b41a3669c479c7bc44f7249383172b432ebaae1e523caa7c6ecbd2d0d7adcb7e5769fe2798f8cb01c08cd57232d1bb6d8ad4 + checksum: cce2bab70ad871ac11751bede006bd4861888f4c63bc9954be38620b14cc6890a4cbc633c1062b89c5fe288ce74b9d1974cc0d43c04baeeb2b13231a236fba85 languageName: node linkType: hard @@ -815,14 +785,14 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-block-scoping@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-block-scoping@npm:7.24.7" +"@babel/plugin-transform-block-scoping@npm:^7.24.7, @babel/plugin-transform-block-scoping@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/plugin-transform-block-scoping@npm:7.25.0" dependencies: - "@babel/helper-plugin-utils": ^7.24.7 + "@babel/helper-plugin-utils": ^7.24.8 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 039206155533600f079f3a455f85888dd7d4970ff7ffa85ef44760f4f5acb9f19c9d848cc1fec1b9bdbc0dfec9e8a080b90d0ab66ad2bdc7138b5ca4ba96e61c + checksum: b1a8f932f69ad2a47ae3e02b4cedd2a876bfc2ac9cf72a503fd706cdc87272646fe9eed81e068c0fc639647033de29f7fa0c21cddd1da0026f83dbaac97316a8 languageName: node linkType: hard @@ -851,21 +821,19 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-classes@npm:^7.24.8": - version: 7.24.8 - resolution: "@babel/plugin-transform-classes@npm:7.24.8" +"@babel/plugin-transform-classes@npm:^7.24.8, @babel/plugin-transform-classes@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/plugin-transform-classes@npm:7.25.0" dependencies: "@babel/helper-annotate-as-pure": ^7.24.7 "@babel/helper-compilation-targets": ^7.24.8 - "@babel/helper-environment-visitor": ^7.24.7 - "@babel/helper-function-name": ^7.24.7 "@babel/helper-plugin-utils": ^7.24.8 - "@babel/helper-replace-supers": ^7.24.7 - "@babel/helper-split-export-declaration": ^7.24.7 + "@babel/helper-replace-supers": ^7.25.0 + "@babel/traverse": ^7.25.0 globals: ^11.1.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 9c0f547d67e255b37055461df9c1a578c29bf59c7055bd5b40b07b92e5448af3ca8d853d50056125b7dae9bfe3a4cf1559d61b9ccbc3d2578dd43f15386f12fe + checksum: ff97f168e6a18fa4e7bb439f1a170dc83c470973091c22c74674769350ab572be5af017cdb64fbd261fe99d068a4ee88f1b7fa7f5ab524d84c2f2833b116e577 languageName: node linkType: hard @@ -915,6 +883,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-duplicate-named-capturing-groups-regex@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/plugin-transform-duplicate-named-capturing-groups-regex@npm:7.25.0" + dependencies: + "@babel/helper-create-regexp-features-plugin": ^7.25.0 + "@babel/helper-plugin-utils": ^7.24.8 + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 608d6b0e77341189508880fd1a9f605a38d0803dd6f678ea3920ab181b17b377f6d5221ae8cf0104c7a044d30d4ddb0366bd064447695671d78457a656bb264f + languageName: node + linkType: hard + "@babel/plugin-transform-dynamic-import@npm:^7.24.7": version: 7.24.7 resolution: "@babel/plugin-transform-dynamic-import@npm:7.24.7" @@ -975,16 +955,16 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-function-name@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-function-name@npm:7.24.7" +"@babel/plugin-transform-function-name@npm:^7.24.7, @babel/plugin-transform-function-name@npm:^7.25.0": + version: 7.25.1 + resolution: "@babel/plugin-transform-function-name@npm:7.25.1" dependencies: - "@babel/helper-compilation-targets": ^7.24.7 - "@babel/helper-function-name": ^7.24.7 - "@babel/helper-plugin-utils": ^7.24.7 + "@babel/helper-compilation-targets": ^7.24.8 + "@babel/helper-plugin-utils": ^7.24.8 + "@babel/traverse": ^7.25.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 8eb1a67894a124910b5a67630bed4307757504381f39f0fb5cf82afc7ae8647dbc03b256d13865b73a749b9071b68e9fb8a28cef2369917b4299ebb93fd66146 + checksum: 743f3ea03bbc5a90944849d5a880b6bd9243dddbde581a46952da76e53a0b74c1e2424133fe8129d7a152c1f8c872bcd27e0b6728d7caadabd1afa7bb892e1e0 languageName: node linkType: hard @@ -1059,17 +1039,17 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-modules-systemjs@npm:^7.24.7": - version: 7.24.7 - resolution: "@babel/plugin-transform-modules-systemjs@npm:7.24.7" +"@babel/plugin-transform-modules-systemjs@npm:^7.24.7, @babel/plugin-transform-modules-systemjs@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/plugin-transform-modules-systemjs@npm:7.25.0" dependencies: - "@babel/helper-hoist-variables": ^7.24.7 - "@babel/helper-module-transforms": ^7.24.7 - "@babel/helper-plugin-utils": ^7.24.7 + "@babel/helper-module-transforms": ^7.25.0 + "@babel/helper-plugin-utils": ^7.24.8 "@babel/helper-validator-identifier": ^7.24.7 + "@babel/traverse": ^7.25.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 8af7a9db2929991d82cfdf41fb175dee344274d39b39122f8c35f24b5d682f98368e3d8f5130401298bd21412df21d416a7d8b33b59c334fae3d3c762118b1d8 + checksum: fe673bec08564e491847324bb80a1e6edfb229f5c37e58a094d51e95306e7b098e1d130fc43e992d22debd93b9beac74441ffc3f6ea5d78f6b2535896efa0728 languageName: node linkType: hard @@ -1232,13 +1212,13 @@ __metadata: linkType: hard "@babel/plugin-transform-react-constant-elements@npm:^7.21.3": - version: 7.24.7 - resolution: "@babel/plugin-transform-react-constant-elements@npm:7.24.7" + version: 7.25.1 + resolution: "@babel/plugin-transform-react-constant-elements@npm:7.25.1" dependencies: - "@babel/helper-plugin-utils": ^7.24.7 + "@babel/helper-plugin-utils": ^7.24.8 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 15a50645d5bd5139a65a57cc1ca8d731921bf4b3d453ed14150760a16891bdd8c0d6e870a85e3a580a00686415732fd74ff2c669a823e641a6124ac9489d8ed4 + checksum: 6126abf8bc3980c1e27fd217f8b2f226b20cce9be300eaf9d30548556dd1e906b7daa4580d9ae1dae35eb5ed5c98e7222e0cb91efb0a232d05aae5875dcfe55c languageName: node linkType: hard @@ -1371,16 +1351,17 @@ __metadata: linkType: hard "@babel/plugin-transform-typescript@npm:^7.24.7": - version: 7.24.8 - resolution: "@babel/plugin-transform-typescript@npm:7.24.8" + version: 7.25.0 + resolution: "@babel/plugin-transform-typescript@npm:7.25.0" dependencies: "@babel/helper-annotate-as-pure": ^7.24.7 - "@babel/helper-create-class-features-plugin": ^7.24.8 + "@babel/helper-create-class-features-plugin": ^7.25.0 "@babel/helper-plugin-utils": ^7.24.8 + "@babel/helper-skip-transparent-expression-wrappers": ^7.24.7 "@babel/plugin-syntax-typescript": ^7.24.7 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 4dcdc0ca2b523ccfb216ad7e68d2954576e42d83956e0e65626ad1ece17da85cb1122b6c350c4746db927996060466c879945d40cde156a94019f30587fef41a + checksum: 68f755be1c561740cd4e74f07ccc4777672fa1c0b9aa2699efe73bc881aed4249add117d5492632adc7d80c9dea3a9d153fcce7ba29ff12b0e2ba6bb2d148fdd languageName: node linkType: hard @@ -1431,7 +1412,7 @@ __metadata: languageName: node linkType: hard -"@babel/preset-env@npm:7.24.8, @babel/preset-env@npm:^7.20.2, @babel/preset-env@npm:^7.23.2": +"@babel/preset-env@npm:7.24.8": version: 7.24.8 resolution: "@babel/preset-env@npm:7.24.8" dependencies: @@ -1522,6 +1503,99 @@ __metadata: languageName: node linkType: hard +"@babel/preset-env@npm:^7.20.2, @babel/preset-env@npm:^7.23.2": + version: 7.25.0 + resolution: "@babel/preset-env@npm:7.25.0" + dependencies: + "@babel/compat-data": ^7.25.0 + "@babel/helper-compilation-targets": ^7.24.8 + "@babel/helper-plugin-utils": ^7.24.8 + "@babel/helper-validator-option": ^7.24.8 + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": ^7.25.0 + "@babel/plugin-bugfix-safari-class-field-initializer-scope": ^7.25.0 + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": ^7.25.0 + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": ^7.24.7 + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": ^7.25.0 + "@babel/plugin-proposal-private-property-in-object": 7.21.0-placeholder-for-preset-env.2 + "@babel/plugin-syntax-async-generators": ^7.8.4 + "@babel/plugin-syntax-class-properties": ^7.12.13 + "@babel/plugin-syntax-class-static-block": ^7.14.5 + "@babel/plugin-syntax-dynamic-import": ^7.8.3 + "@babel/plugin-syntax-export-namespace-from": ^7.8.3 + "@babel/plugin-syntax-import-assertions": ^7.24.7 + "@babel/plugin-syntax-import-attributes": ^7.24.7 + "@babel/plugin-syntax-import-meta": ^7.10.4 + "@babel/plugin-syntax-json-strings": ^7.8.3 + "@babel/plugin-syntax-logical-assignment-operators": ^7.10.4 + "@babel/plugin-syntax-nullish-coalescing-operator": ^7.8.3 + "@babel/plugin-syntax-numeric-separator": ^7.10.4 + "@babel/plugin-syntax-object-rest-spread": ^7.8.3 + "@babel/plugin-syntax-optional-catch-binding": ^7.8.3 + "@babel/plugin-syntax-optional-chaining": ^7.8.3 + "@babel/plugin-syntax-private-property-in-object": ^7.14.5 + "@babel/plugin-syntax-top-level-await": ^7.14.5 + "@babel/plugin-syntax-unicode-sets-regex": ^7.18.6 + "@babel/plugin-transform-arrow-functions": ^7.24.7 + "@babel/plugin-transform-async-generator-functions": ^7.25.0 + "@babel/plugin-transform-async-to-generator": ^7.24.7 + "@babel/plugin-transform-block-scoped-functions": ^7.24.7 + "@babel/plugin-transform-block-scoping": ^7.25.0 + "@babel/plugin-transform-class-properties": ^7.24.7 + "@babel/plugin-transform-class-static-block": ^7.24.7 + "@babel/plugin-transform-classes": ^7.25.0 + "@babel/plugin-transform-computed-properties": ^7.24.7 + "@babel/plugin-transform-destructuring": ^7.24.8 + "@babel/plugin-transform-dotall-regex": ^7.24.7 + "@babel/plugin-transform-duplicate-keys": ^7.24.7 + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": ^7.25.0 + "@babel/plugin-transform-dynamic-import": ^7.24.7 + "@babel/plugin-transform-exponentiation-operator": ^7.24.7 + "@babel/plugin-transform-export-namespace-from": ^7.24.7 + "@babel/plugin-transform-for-of": ^7.24.7 + "@babel/plugin-transform-function-name": ^7.25.0 + "@babel/plugin-transform-json-strings": ^7.24.7 + "@babel/plugin-transform-literals": ^7.24.7 + "@babel/plugin-transform-logical-assignment-operators": ^7.24.7 + "@babel/plugin-transform-member-expression-literals": ^7.24.7 + "@babel/plugin-transform-modules-amd": ^7.24.7 + "@babel/plugin-transform-modules-commonjs": ^7.24.8 + "@babel/plugin-transform-modules-systemjs": ^7.25.0 + "@babel/plugin-transform-modules-umd": ^7.24.7 + "@babel/plugin-transform-named-capturing-groups-regex": ^7.24.7 + "@babel/plugin-transform-new-target": ^7.24.7 + "@babel/plugin-transform-nullish-coalescing-operator": ^7.24.7 + "@babel/plugin-transform-numeric-separator": ^7.24.7 + "@babel/plugin-transform-object-rest-spread": ^7.24.7 + "@babel/plugin-transform-object-super": ^7.24.7 + "@babel/plugin-transform-optional-catch-binding": ^7.24.7 + "@babel/plugin-transform-optional-chaining": ^7.24.8 + "@babel/plugin-transform-parameters": ^7.24.7 + "@babel/plugin-transform-private-methods": ^7.24.7 + "@babel/plugin-transform-private-property-in-object": ^7.24.7 + "@babel/plugin-transform-property-literals": ^7.24.7 + "@babel/plugin-transform-regenerator": ^7.24.7 + "@babel/plugin-transform-reserved-words": ^7.24.7 + "@babel/plugin-transform-shorthand-properties": ^7.24.7 + "@babel/plugin-transform-spread": ^7.24.7 + "@babel/plugin-transform-sticky-regex": ^7.24.7 + "@babel/plugin-transform-template-literals": ^7.24.7 + "@babel/plugin-transform-typeof-symbol": ^7.24.8 + "@babel/plugin-transform-unicode-escapes": ^7.24.7 + "@babel/plugin-transform-unicode-property-regex": ^7.24.7 + "@babel/plugin-transform-unicode-regex": ^7.24.7 + "@babel/plugin-transform-unicode-sets-regex": ^7.24.7 + "@babel/preset-modules": 0.1.6-no-external-plugins + babel-plugin-polyfill-corejs2: ^0.4.10 + babel-plugin-polyfill-corejs3: ^0.10.4 + babel-plugin-polyfill-regenerator: ^0.6.1 + core-js-compat: ^3.37.1 + semver: ^6.3.1 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10161771c6dd408e440ea634338eeb0bc9f3619c45513b04ccafb9d6a5ad12a6e01fc16506cbb3ea9e8be2123690be65524f6112662cf38c3fbdcda988f47585 + languageName: node + linkType: hard + "@babel/preset-flow@npm:^7.22.15": version: 7.24.7 resolution: "@babel/preset-flow@npm:7.24.7" @@ -1602,51 +1676,48 @@ __metadata: linkType: hard "@babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.13.10, @babel/runtime@npm:^7.17.8, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.18.6, @babel/runtime@npm:^7.19.4, @babel/runtime@npm:^7.21.0, @babel/runtime@npm:^7.22.15, @babel/runtime@npm:^7.22.5, @babel/runtime@npm:^7.23.2, @babel/runtime@npm:^7.23.8, @babel/runtime@npm:^7.23.9, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.7.2, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.8.7, @babel/runtime@npm:^7.9.2": - version: 7.24.8 - resolution: "@babel/runtime@npm:7.24.8" + version: 7.25.0 + resolution: "@babel/runtime@npm:7.25.0" dependencies: regenerator-runtime: ^0.14.0 - checksum: 6b1e4230580f67a807ad054720812bbefbb024cc2adc1159d050acbb764c4c81c7ac5f7a042c48f578987c5edc2453c71039268df059058e9501fa6023d764b0 + checksum: 4a2a374a58eb01aaa65c5762606e90b3a1f448e0c637d42278b6cc0b42a9f5399b5f381ba9f237ee087da2860d14dd2d1de7bddcbe18be6a3cafba97e44bed64 languageName: node linkType: hard -"@babel/template@npm:^7.24.7, @babel/template@npm:^7.3.3, @babel/template@npm:^7.4.4": - version: 7.24.7 - resolution: "@babel/template@npm:7.24.7" +"@babel/template@npm:^7.24.7, @babel/template@npm:^7.25.0, @babel/template@npm:^7.3.3, @babel/template@npm:^7.4.4": + version: 7.25.0 + resolution: "@babel/template@npm:7.25.0" dependencies: "@babel/code-frame": ^7.24.7 - "@babel/parser": ^7.24.7 - "@babel/types": ^7.24.7 - checksum: ea90792fae708ddf1632e54c25fe1a86643d8c0132311f81265d2bdbdd42f9f4fac65457056c1b6ca87f7aa0d6a795b549566774bba064bdcea2034ab3960ee9 + "@babel/parser": ^7.25.0 + "@babel/types": ^7.25.0 + checksum: 3f2db568718756d0daf2a16927b78f00c425046b654cd30b450006f2e84bdccaf0cbe6dc04994aa1f5f6a4398da2f11f3640a4d3ee31722e43539c4c919c817b languageName: node linkType: hard -"@babel/traverse@npm:^7.18.9, @babel/traverse@npm:^7.23.2, @babel/traverse@npm:^7.24.7, @babel/traverse@npm:^7.24.8": - version: 7.24.8 - resolution: "@babel/traverse@npm:7.24.8" +"@babel/traverse@npm:^7.18.9, @babel/traverse@npm:^7.23.2, @babel/traverse@npm:^7.24.7, @babel/traverse@npm:^7.24.8, @babel/traverse@npm:^7.25.0, @babel/traverse@npm:^7.25.1": + version: 7.25.1 + resolution: "@babel/traverse@npm:7.25.1" dependencies: "@babel/code-frame": ^7.24.7 - "@babel/generator": ^7.24.8 - "@babel/helper-environment-visitor": ^7.24.7 - "@babel/helper-function-name": ^7.24.7 - "@babel/helper-hoist-variables": ^7.24.7 - "@babel/helper-split-export-declaration": ^7.24.7 - "@babel/parser": ^7.24.8 - "@babel/types": ^7.24.8 + "@babel/generator": ^7.25.0 + "@babel/parser": ^7.25.0 + "@babel/template": ^7.25.0 + "@babel/types": ^7.25.0 debug: ^4.3.1 globals: ^11.1.0 - checksum: ee7955476ce031613249f2b0ce9e74a3b7787c9d52e84534fcf39ad61aeb0b811a4cd83edc157608be4886f04c6ecf210861e211ba2a3db4fda729cc2048b5ed + checksum: c22a5ced9aef2669fd18936e3d919481cc4c12055f2e3b91e0761b2f89e26e4c6b51bfc4577f1a52ddb8734199d9917ec09027a378a6eb25ffe844704741f50e languageName: node linkType: hard -"@babel/types@npm:^7.0.0, @babel/types@npm:^7.18.9, @babel/types@npm:^7.20.7, @babel/types@npm:^7.21.3, @babel/types@npm:^7.23.0, @babel/types@npm:^7.24.7, @babel/types@npm:^7.24.8, @babel/types@npm:^7.24.9, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4, @babel/types@npm:^7.8.3": - version: 7.24.9 - resolution: "@babel/types@npm:7.24.9" +"@babel/types@npm:^7.0.0, @babel/types@npm:^7.18.9, @babel/types@npm:^7.20.7, @babel/types@npm:^7.21.3, @babel/types@npm:^7.23.0, @babel/types@npm:^7.24.7, @babel/types@npm:^7.24.8, @babel/types@npm:^7.24.9, @babel/types@npm:^7.25.0, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4, @babel/types@npm:^7.8.3": + version: 7.25.0 + resolution: "@babel/types@npm:7.25.0" dependencies: "@babel/helper-string-parser": ^7.24.8 "@babel/helper-validator-identifier": ^7.24.7 to-fast-properties: ^2.0.0 - checksum: 15cb05c45be5d4c49a749575d3742bd005d0e2e850c13fb462754983a5bc1063fbc8f6566246fc064e3e8b21a5a75a37a948f1b3f27189cc90b236fee93f5e51 + checksum: 58645192c73ea1adf72b3311c46e6f656bb3f52adb285c3ae0566e62a3d9ea1998449e88c6590501cb7aa9fe3411bb66288c961b9ebb5c4e9c433bad8619efaa languageName: node linkType: hard @@ -1791,7 +1862,20 @@ __metadata: languageName: node linkType: hard -"@emotion/cache@npm:*, @emotion/cache@npm:11.13.0, @emotion/cache@npm:^11.11.0, @emotion/cache@npm:^11.13.0": +"@emotion/cache@npm:*, @emotion/cache@npm:^11.11.0, @emotion/cache@npm:^11.13.0": + version: 11.13.1 + resolution: "@emotion/cache@npm:11.13.1" + dependencies: + "@emotion/memoize": ^0.9.0 + "@emotion/sheet": ^1.4.0 + "@emotion/utils": ^1.4.0 + "@emotion/weak-memoize": ^0.4.0 + stylis: 4.2.0 + checksum: 94b161786a03a08a1e30257478fad9a9be1ac8585ddca0c6410d7411fd474fc8b0d6d1167d7d15bdb012d1fd8a1220ac2bbc79501ad9b292b83c17da0874d7de + languageName: node + linkType: hard + +"@emotion/cache@npm:11.13.0": version: 11.13.0 resolution: "@emotion/cache@npm:11.13.0" dependencies: @@ -2283,21 +2367,21 @@ __metadata: linkType: hard "@floating-ui/core@npm:^1.6.0": - version: 1.6.4 - resolution: "@floating-ui/core@npm:1.6.4" + version: 1.6.5 + resolution: "@floating-ui/core@npm:1.6.5" dependencies: - "@floating-ui/utils": ^0.2.4 - checksum: 6855472c00ceaa14e0f1cb4bd5de0de01d05cd46bdf12cb19bd6a89fa70bdfba0460a776dc50d28ab40e3bddc291e2211958497528fdd98653ea7260d61e0442 + "@floating-ui/utils": ^0.2.5 + checksum: 8e6c62a6e9223fba9afbcaca8afe408788a2bc8ab1b2f5734a26d5b02d4017a2baffc7176a938a610fd243e6a983ada605f259b35c88813e2230dd29906a78fd languageName: node linkType: hard "@floating-ui/dom@npm:^1.0.0": - version: 1.6.7 - resolution: "@floating-ui/dom@npm:1.6.7" + version: 1.6.8 + resolution: "@floating-ui/dom@npm:1.6.8" dependencies: "@floating-ui/core": ^1.6.0 - "@floating-ui/utils": ^0.2.4 - checksum: 66605a2948bfe7532408197b4c522fecf04cf11e7839623d0dca0d22362b42d64a5db2f3be865053e9b0d44c89faf1befa9a4ce1b7fa595d1b3dc82f635d079c + "@floating-ui/utils": ^0.2.5 + checksum: bab6954bdde69afeaf8dbbf335818fe710c6eae1c62856ae1e09fa6abdc056bf5995e053638b76fa6661b8384c363ca2af874ab0448c3f6943808f4f8f77f3ea languageName: node linkType: hard @@ -2313,10 +2397,10 @@ __metadata: languageName: node linkType: hard -"@floating-ui/utils@npm:^0.2.4": - version: 0.2.4 - resolution: "@floating-ui/utils@npm:0.2.4" - checksum: af44cdb3f394fbee6abc933fc3c25bf22f3f0bac58150eee8cc1dcc7e9be56a19b13e438820160614a90712e5a43f84b091afa6689318a10504042930ae9cf44 +"@floating-ui/utils@npm:^0.2.5": + version: 0.2.5 + resolution: "@floating-ui/utils@npm:0.2.5" + checksum: 32834fe0fec5ee89187f8defd0b10813d725dab7dc6ed1545ded6655630bac5d438f0c991d019d675585e118846f12391236fc2886a5c73a57576e7de3eca3f9 languageName: node linkType: hard @@ -2694,7 +2778,7 @@ __metadata: languageName: node linkType: hard -"@foxglove/schemas@npm:1.6.3, @foxglove/schemas@npm:^1.3.1": +"@foxglove/schemas@npm:1.6.3": version: 1.6.3 resolution: "@foxglove/schemas@npm:1.6.3" dependencies: @@ -2704,6 +2788,16 @@ __metadata: languageName: node linkType: hard +"@foxglove/schemas@npm:^1.3.1": + version: 1.6.4 + resolution: "@foxglove/schemas@npm:1.6.4" + dependencies: + "@foxglove/rosmsg-msgs-common": ^3.0.0 + tslib: ^2.5.0 + checksum: f564c4cd08440fd2776c95dabc54feaae15c7615d57876982237ecb1c7c9d0386b6a7a5046f42dcfa17a7c8556c75db987f3017efe0f32680423a6221dabaafe + languageName: node + linkType: hard + "@foxglove/sql.js@npm:^0.0.4": version: 0.0.4 resolution: "@foxglove/sql.js@npm:0.0.4" @@ -3080,9 +3174,9 @@ __metadata: languageName: node linkType: hard -"@griffel/core@npm:^1.17.1": - version: 1.17.1 - resolution: "@griffel/core@npm:1.17.1" +"@griffel/core@npm:^1.18.0": + version: 1.18.0 + resolution: "@griffel/core@npm:1.18.0" dependencies: "@emotion/hash": ^0.9.0 "@griffel/style-types": ^1.2.0 @@ -3090,19 +3184,19 @@ __metadata: rtl-css-js: ^1.16.1 stylis: ^4.2.0 tslib: ^2.1.0 - checksum: d9f2c57909c230dfe42a524dc755b67c0b0f70e1888fabbf5bdd5369e21d9741bc0934b2ccb6702ef6df811506c32e9b6cf1cf5b6408834b820fc45a5eb8a433 + checksum: 3405d0a949f5fb69475c6a38c01f627b7709d04ba3c7fa6822b6e827cf1e3b194486aab3e8754c894b7879b4209333263a0c70a3c3cf6131345cb3a8a96b6352 languageName: node linkType: hard "@griffel/react@npm:^1.0.0": - version: 1.5.24 - resolution: "@griffel/react@npm:1.5.24" + version: 1.5.25 + resolution: "@griffel/react@npm:1.5.25" dependencies: - "@griffel/core": ^1.17.1 + "@griffel/core": ^1.18.0 tslib: ^2.1.0 peerDependencies: react: ">=16.8.0 <19.0.0" - checksum: 4396ab51607e47d87c1fb5f4a30bf0aadfe580ccdc00e431fdcf26635d0b7c9bc4869ed3aa502d51bc1423d168ef9916ec0f0237b8f18a5557d915bff879a3a0 + checksum: 9b4dbfc095404747bcd26e4e4888a2e662846f7f4208ab182fe862b2618a82aab0b8a229ce2ac6acdb38ede22416eed33c96c7eb21ce2275b860cc37b2e6f385 languageName: node linkType: hard @@ -3511,12 +3605,12 @@ __metadata: languageName: node linkType: hard -"@jsonjoy.com/util@npm:^1.1.2": - version: 1.2.0 - resolution: "@jsonjoy.com/util@npm:1.2.0" +"@jsonjoy.com/util@npm:^1.1.2, @jsonjoy.com/util@npm:^1.3.0": + version: 1.3.0 + resolution: "@jsonjoy.com/util@npm:1.3.0" peerDependencies: tslib: 2 - checksum: 1af590ffc34a8b2112134bda821e9fddf616c66327f18df3f13dcdaad3b86678022427b4233c8c9ec1ddb5cdc4a26ce0571e105593d22eb98590e724be789373 + checksum: a805ca7cf5fc05c6244324a955d96a28797fb8efd60cf22a809a57059de78e4367c72ffb367c82a7ea6ce5622e56f9c696393c5561fbac0fd3c9dc1534d62968 languageName: node linkType: hard @@ -3649,9 +3743,9 @@ __metadata: linkType: hard "@mui/core-downloads-tracker@npm:^5.13.4": - version: 5.16.4 - resolution: "@mui/core-downloads-tracker@npm:5.16.4" - checksum: e1be17bfcfc5e50d42eff8ca8660469c0e20f70bd5148183e8a8d66da12c420f86e097b68d09561055c2d6e4f93f6650ba65a30522a997da9cd9a08d09a54bbc + version: 5.16.5 + resolution: "@mui/core-downloads-tracker@npm:5.16.5" + checksum: 2f0812bf38ffa99f96e0615bd8cb03557e661cc7908d490bee89479594c8143211bcd37cba7694171d9cd488abc8f186c84c68488d5f1e38749b9619ba960d50 languageName: node linkType: hard @@ -3733,12 +3827,12 @@ __metadata: languageName: node linkType: hard -"@mui/private-theming@npm:^5.16.4": - version: 5.16.4 - resolution: "@mui/private-theming@npm:5.16.4" +"@mui/private-theming@npm:^5.16.5": + version: 5.16.5 + resolution: "@mui/private-theming@npm:5.16.5" dependencies: "@babel/runtime": ^7.23.9 - "@mui/utils": ^5.16.4 + "@mui/utils": ^5.16.5 prop-types: ^15.8.1 peerDependencies: "@types/react": ^17.0.0 || ^18.0.0 @@ -3746,7 +3840,7 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: a3f56aa08a4fa8c221b0d8311c156bf8be097dda0ed9eb82b878e2b889dd314760773199b6eee805ba98d1e47402a2ca6667d5e1d84ff4872cb3d40694dd01f8 + checksum: 9849d40e33b442d0d294a82794be3d8da74b376d9906bb164e462d74f4ffa60a8f0f8c1c8263eab9973e3e579e0ca7e397b778c85af3b2c55fe5c95dca00309a languageName: node linkType: hard @@ -3772,14 +3866,14 @@ __metadata: linkType: hard "@mui/system@npm:^5.13.5, @mui/system@npm:^5.15.5": - version: 5.16.4 - resolution: "@mui/system@npm:5.16.4" + version: 5.16.5 + resolution: "@mui/system@npm:5.16.5" dependencies: "@babel/runtime": ^7.23.9 - "@mui/private-theming": ^5.16.4 + "@mui/private-theming": ^5.16.5 "@mui/styled-engine": ^5.16.4 "@mui/types": ^7.2.15 - "@mui/utils": ^5.16.4 + "@mui/utils": ^5.16.5 clsx: ^2.1.0 csstype: ^3.1.3 prop-types: ^15.8.1 @@ -3795,7 +3889,7 @@ __metadata: optional: true "@types/react": optional: true - checksum: c7b8caad1d7f99661eeead943f934ce55a8f7ded0f8d9b6fbf12c5a9e3eb539ccd991272f493b4a36d96ae5efe2e77d330f75240f36b7d6dfdbd376f5616f2ee + checksum: dee096d6a58e5ff411ea68bdfcc33dacf824e177ac5931c14e593ddeddee3b32e527f44aa0135190b07283fa354046af355e4eb4f916a2505afb8c41f9496320 languageName: node linkType: hard @@ -3811,11 +3905,12 @@ __metadata: languageName: node linkType: hard -"@mui/utils@npm:^5.13.1, @mui/utils@npm:^5.14.16, @mui/utils@npm:^5.15.5, @mui/utils@npm:^5.16.4": - version: 5.16.4 - resolution: "@mui/utils@npm:5.16.4" +"@mui/utils@npm:^5.13.1, @mui/utils@npm:^5.14.16, @mui/utils@npm:^5.15.5, @mui/utils@npm:^5.16.5": + version: 5.16.5 + resolution: "@mui/utils@npm:5.16.5" dependencies: "@babel/runtime": ^7.23.9 + "@mui/types": ^7.2.15 "@types/prop-types": ^15.7.12 clsx: ^2.1.1 prop-types: ^15.8.1 @@ -3826,7 +3921,7 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 8185d74a7c10c32347d29296cc6433d3f6894196dc3645ff4543c2f76a97c8c40ba35aff1443abd8af7f0123a97834f2809281c28c924c99693ceaeab9d6640d + checksum: f105f85cf8bdcfea31d689a23b50713810ec5aea62b244362edd5427d52e8b282b349fdc7876eeba02438da6047e0cb38df36d7d93a0d2aabb844d7e73bf5155 languageName: node linkType: hard @@ -6164,92 +6259,92 @@ __metadata: languageName: node linkType: hard -"@swc/core-darwin-arm64@npm:1.7.0": - version: 1.7.0 - resolution: "@swc/core-darwin-arm64@npm:1.7.0" +"@swc/core-darwin-arm64@npm:1.7.3": + version: 1.7.3 + resolution: "@swc/core-darwin-arm64@npm:1.7.3" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@swc/core-darwin-x64@npm:1.7.0": - version: 1.7.0 - resolution: "@swc/core-darwin-x64@npm:1.7.0" +"@swc/core-darwin-x64@npm:1.7.3": + version: 1.7.3 + resolution: "@swc/core-darwin-x64@npm:1.7.3" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@swc/core-linux-arm-gnueabihf@npm:1.7.0": - version: 1.7.0 - resolution: "@swc/core-linux-arm-gnueabihf@npm:1.7.0" +"@swc/core-linux-arm-gnueabihf@npm:1.7.3": + version: 1.7.3 + resolution: "@swc/core-linux-arm-gnueabihf@npm:1.7.3" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@swc/core-linux-arm64-gnu@npm:1.7.0": - version: 1.7.0 - resolution: "@swc/core-linux-arm64-gnu@npm:1.7.0" +"@swc/core-linux-arm64-gnu@npm:1.7.3": + version: 1.7.3 + resolution: "@swc/core-linux-arm64-gnu@npm:1.7.3" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-arm64-musl@npm:1.7.0": - version: 1.7.0 - resolution: "@swc/core-linux-arm64-musl@npm:1.7.0" +"@swc/core-linux-arm64-musl@npm:1.7.3": + version: 1.7.3 + resolution: "@swc/core-linux-arm64-musl@npm:1.7.3" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@swc/core-linux-x64-gnu@npm:1.7.0": - version: 1.7.0 - resolution: "@swc/core-linux-x64-gnu@npm:1.7.0" +"@swc/core-linux-x64-gnu@npm:1.7.3": + version: 1.7.3 + resolution: "@swc/core-linux-x64-gnu@npm:1.7.3" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@swc/core-linux-x64-musl@npm:1.7.0": - version: 1.7.0 - resolution: "@swc/core-linux-x64-musl@npm:1.7.0" +"@swc/core-linux-x64-musl@npm:1.7.3": + version: 1.7.3 + resolution: "@swc/core-linux-x64-musl@npm:1.7.3" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@swc/core-win32-arm64-msvc@npm:1.7.0": - version: 1.7.0 - resolution: "@swc/core-win32-arm64-msvc@npm:1.7.0" +"@swc/core-win32-arm64-msvc@npm:1.7.3": + version: 1.7.3 + resolution: "@swc/core-win32-arm64-msvc@npm:1.7.3" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@swc/core-win32-ia32-msvc@npm:1.7.0": - version: 1.7.0 - resolution: "@swc/core-win32-ia32-msvc@npm:1.7.0" +"@swc/core-win32-ia32-msvc@npm:1.7.3": + version: 1.7.3 + resolution: "@swc/core-win32-ia32-msvc@npm:1.7.3" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@swc/core-win32-x64-msvc@npm:1.7.0": - version: 1.7.0 - resolution: "@swc/core-win32-x64-msvc@npm:1.7.0" +"@swc/core-win32-x64-msvc@npm:1.7.3": + version: 1.7.3 + resolution: "@swc/core-win32-x64-msvc@npm:1.7.3" conditions: os=win32 & cpu=x64 languageName: node linkType: hard "@swc/core@npm:^1.3.82": - version: 1.7.0 - resolution: "@swc/core@npm:1.7.0" - dependencies: - "@swc/core-darwin-arm64": 1.7.0 - "@swc/core-darwin-x64": 1.7.0 - "@swc/core-linux-arm-gnueabihf": 1.7.0 - "@swc/core-linux-arm64-gnu": 1.7.0 - "@swc/core-linux-arm64-musl": 1.7.0 - "@swc/core-linux-x64-gnu": 1.7.0 - "@swc/core-linux-x64-musl": 1.7.0 - "@swc/core-win32-arm64-msvc": 1.7.0 - "@swc/core-win32-ia32-msvc": 1.7.0 - "@swc/core-win32-x64-msvc": 1.7.0 + version: 1.7.3 + resolution: "@swc/core@npm:1.7.3" + dependencies: + "@swc/core-darwin-arm64": 1.7.3 + "@swc/core-darwin-x64": 1.7.3 + "@swc/core-linux-arm-gnueabihf": 1.7.3 + "@swc/core-linux-arm64-gnu": 1.7.3 + "@swc/core-linux-arm64-musl": 1.7.3 + "@swc/core-linux-x64-gnu": 1.7.3 + "@swc/core-linux-x64-musl": 1.7.3 + "@swc/core-win32-arm64-msvc": 1.7.3 + "@swc/core-win32-ia32-msvc": 1.7.3 + "@swc/core-win32-x64-msvc": 1.7.3 "@swc/counter": ^0.1.3 - "@swc/types": ^0.1.9 + "@swc/types": ^0.1.12 peerDependencies: "@swc/helpers": "*" dependenciesMeta: @@ -6276,7 +6371,7 @@ __metadata: peerDependenciesMeta: "@swc/helpers": optional: true - checksum: 5ede35e27f1f51a0133722ecf3943c8a3922087b1a53eefc7b9d11ae2a97fcb69821dc2793e57e01d0f5d7d01ce72150a333e5b944c37210b4e3118df6215984 + checksum: af7850035057ea1f7412cf7bf7b27d13e0d55e79a5c6e37319cbdca6a962134718d8a8355cfd4926b4fc8d25d67afca567ca63bb3f8d2c8cab869b37bb7cd0ed languageName: node linkType: hard @@ -6287,12 +6382,12 @@ __metadata: languageName: node linkType: hard -"@swc/types@npm:^0.1.9": - version: 0.1.9 - resolution: "@swc/types@npm:0.1.9" +"@swc/types@npm:^0.1.12": + version: 0.1.12 + resolution: "@swc/types@npm:0.1.12" dependencies: "@swc/counter": ^0.1.3 - checksum: 16fcdf331c94c52f6dbf234bd9c294a5479e4b107eb8bce364b46cd5cf86ff7073e371a3a02573e6843b0ec979e6d8912b6f60212ad297aa170a9025e7ebb716 + checksum: cf7f89e46f859864075d7965582baea9c5f98830f45b1046251568c9bdf1ca484b1bf37f6d3c32b7c82ecf8cd5df89d22f05268c391819c44e49911bb1a8e71a languageName: node linkType: hard @@ -6341,8 +6436,8 @@ __metadata: linkType: hard "@testing-library/jest-dom@npm:^6.1.2": - version: 6.4.6 - resolution: "@testing-library/jest-dom@npm:6.4.6" + version: 6.4.8 + resolution: "@testing-library/jest-dom@npm:6.4.8" dependencies: "@adobe/css-tools": ^4.4.0 "@babel/runtime": ^7.9.2 @@ -6352,24 +6447,7 @@ __metadata: dom-accessibility-api: ^0.6.3 lodash: ^4.17.21 redent: ^3.0.0 - peerDependencies: - "@jest/globals": ">= 28" - "@types/bun": "*" - "@types/jest": ">= 28" - jest: ">= 28" - vitest: ">= 0.32" - peerDependenciesMeta: - "@jest/globals": - optional: true - "@types/bun": - optional: true - "@types/jest": - optional: true - jest: - optional: true - vitest: - optional: true - checksum: d70acbfc5d842065292dc1b4113ac2b4c2a2b83f9868e454d7f24d97ee92fddf7852e0e079b6eecaf21154bfe6e9ad03eb32e72f16854f64d7ce1ff42288828b + checksum: b601688950e522557c2c6bbc0f026ae31a10583577c8a557814b0eb33648fe82afc06299f3cdb79ff0c5076fd1a6106f3d76e2ca0dde6f7ee0555e63008fbd72 languageName: node linkType: hard @@ -6665,12 +6743,12 @@ __metadata: linkType: hard "@types/eslint@npm:*": - version: 8.56.10 - resolution: "@types/eslint@npm:8.56.10" + version: 9.6.0 + resolution: "@types/eslint@npm:9.6.0" dependencies: "@types/estree": "*" "@types/json-schema": "*" - checksum: fb7137dd263ce1130b42d14452bdd0266ef81f52cb55ba1a5e9750e65da1f0596dc598c88bffc7e415458b6cb611a876dcc132bcf40ea48701c6d05b40c57be5 + checksum: 7be4b1d24f3df30b28e9cbaac6a5fa14ec1ceca7c173d9605c0ec6e0d1dcdba0452d326dd695dd980f5c14b42aa09fe41675c4f09ffc82db4f466588d3f837cb languageName: node linkType: hard @@ -7487,11 +7565,11 @@ __metadata: linkType: hard "@types/ws@npm:^8.5.10": - version: 8.5.11 - resolution: "@types/ws@npm:8.5.11" + version: 8.5.12 + resolution: "@types/ws@npm:8.5.12" dependencies: "@types/node": "*" - checksum: 91d3ad6cc802f52b01c8cc7b0de149617785e8166e631291201d5f50937db2a578cbe70b61d96f43140d57170ad2f904782d3ec9ed86c34c5e9cec9a847a94dc + checksum: ddefb6ad1671f70ce73b38a5f47f471d4d493864fca7c51f002a86e5993d031294201c5dced6d5018fb8905ad46888d65c7f20dd54fc165910b69f42fba9a6d0 languageName: node linkType: hard @@ -7815,60 +7893,60 @@ __metadata: languageName: node linkType: hard -"@vue/compiler-core@npm:3.4.32": - version: 3.4.32 - resolution: "@vue/compiler-core@npm:3.4.32" +"@vue/compiler-core@npm:3.4.34": + version: 3.4.34 + resolution: "@vue/compiler-core@npm:3.4.34" dependencies: "@babel/parser": ^7.24.7 - "@vue/shared": 3.4.32 + "@vue/shared": 3.4.34 entities: ^4.5.0 estree-walker: ^2.0.2 source-map-js: ^1.2.0 - checksum: 1743205465c322ddf62f8d2dd1557528626dd36f7528c9ca7e7cb7dbb0969f903dbc46e470220f5a8e30ff2bc6fd7ba9e5b5ef973f7bfd125ece51a77dcd9b29 + checksum: 397e76fec66bb5481b32823aa9530e9810bb39c33b5ac78b4488e8814f5779bbc4d1d85cac98fe96c3036e83105ccad0fb813e15cb8b5d201343dfef99750041 languageName: node linkType: hard -"@vue/compiler-dom@npm:3.4.32": - version: 3.4.32 - resolution: "@vue/compiler-dom@npm:3.4.32" +"@vue/compiler-dom@npm:3.4.34": + version: 3.4.34 + resolution: "@vue/compiler-dom@npm:3.4.34" dependencies: - "@vue/compiler-core": 3.4.32 - "@vue/shared": 3.4.32 - checksum: c4e762e372c2ea374b9cac7f1d94f553f2e9f892713b9441838de4993d99f6eb1a184d2f268c550878f876ed40869677f92852a91db42f11c6e0591a7ee943aa + "@vue/compiler-core": 3.4.34 + "@vue/shared": 3.4.34 + checksum: 6ba068d0274048eb25e3ef9665bbe6e4f9a65841ab4fd22336a6c5b760e9474c8260b31f514fbce3f3bf23e55e452c4be58cf35efafdb42c6a2d524e27cec1ca languageName: node linkType: hard "@vue/compiler-sfc@npm:^3.3.4": - version: 3.4.32 - resolution: "@vue/compiler-sfc@npm:3.4.32" + version: 3.4.34 + resolution: "@vue/compiler-sfc@npm:3.4.34" dependencies: "@babel/parser": ^7.24.7 - "@vue/compiler-core": 3.4.32 - "@vue/compiler-dom": 3.4.32 - "@vue/compiler-ssr": 3.4.32 - "@vue/shared": 3.4.32 + "@vue/compiler-core": 3.4.34 + "@vue/compiler-dom": 3.4.34 + "@vue/compiler-ssr": 3.4.34 + "@vue/shared": 3.4.34 estree-walker: ^2.0.2 magic-string: ^0.30.10 postcss: ^8.4.39 source-map-js: ^1.2.0 - checksum: 376eb5326be7e69028e2d089a84778607b0ab28d2ca545fb65b635c550cb727a0095bb821c7e71d662f410d110a4be7bf45169a8bb3bfeb0779b838a29a90281 + checksum: e9fc4ee40372d7b5e18eb8921aa469bf224a6e6fbc33fe1a73dd16ee89c914f5ceb912e4e61453841de00e2a1dbc52e92b556e62436342637efbc19129d97eb2 languageName: node linkType: hard -"@vue/compiler-ssr@npm:3.4.32": - version: 3.4.32 - resolution: "@vue/compiler-ssr@npm:3.4.32" +"@vue/compiler-ssr@npm:3.4.34": + version: 3.4.34 + resolution: "@vue/compiler-ssr@npm:3.4.34" dependencies: - "@vue/compiler-dom": 3.4.32 - "@vue/shared": 3.4.32 - checksum: aeb2f7af9eff9a73ece21ca7b038b2537542cafb367e2d9c7d55522d475bdb7892e9d7333de3de26ac0bedf9c4caced73b28f64ed2f9417aa40fdc343a48edd8 + "@vue/compiler-dom": 3.4.34 + "@vue/shared": 3.4.34 + checksum: f066036859f6de1882a941e1fce7904d3bb091f858ab1ad40926e9d5bbb92ece883835e267a93b07d938c048480d51109cb776047d02b8bbe47fe4282d1bb78e languageName: node linkType: hard -"@vue/shared@npm:3.4.32": - version: 3.4.32 - resolution: "@vue/shared@npm:3.4.32" - checksum: 3d4a5667ff11c3c532e774a7e9cfbead1dd41e7d9517e470caff0705bbf70c90a4ad320d39e417fbafe6c4663630e29381856a281e1f61b80f9844a91d326c87 +"@vue/shared@npm:3.4.34": + version: 3.4.34 + resolution: "@vue/shared@npm:3.4.34" + checksum: 6383d05a23137b66a9f2b4e18ca7da874eab4b059db1ce62c0f1220c99670a8349987ef9f376e832b208afa521041323c0b6860f7e1dd55974b78c128df74fc7 languageName: node linkType: hard @@ -8208,7 +8286,7 @@ __metadata: languageName: node linkType: hard -"acorn@npm:^8.1.0, acorn@npm:^8.11.0, acorn@npm:^8.11.3, acorn@npm:^8.4.1, acorn@npm:^8.7.1, acorn@npm:^8.8.1, acorn@npm:^8.8.2, acorn@npm:^8.9.0": +"acorn@npm:^8.1.0, acorn@npm:^8.11.0, acorn@npm:^8.11.3, acorn@npm:^8.12.1, acorn@npm:^8.4.1, acorn@npm:^8.7.1, acorn@npm:^8.8.1, acorn@npm:^8.8.2, acorn@npm:^8.9.0": version: 8.12.1 resolution: "acorn@npm:8.12.1" bin: @@ -8407,10 +8485,10 @@ __metadata: languageName: node linkType: hard -"app-builder-bin@npm:v5.0.0-alpha.4": - version: 5.0.0-alpha.4 - resolution: "app-builder-bin@npm:5.0.0-alpha.4" - checksum: f45145a699deadffde149c09d7ed266c4a7db29d35e5a65ef55b395eb19675faef1490903a5bea3f541a819834206b498345bfc9b49218fa5773e5f184cd1141 +"app-builder-bin@npm:5.0.0-alpha.6": + version: 5.0.0-alpha.6 + resolution: "app-builder-bin@npm:5.0.0-alpha.6" + checksum: c8b38c2e162166eeb9fd34572c09e29cc9970a5b34022d2f9957551f086d67b7d7b030544115637b14a2cd2373dc745c2ec5da96e3e53b9c144327dad8d04ad5 languageName: node linkType: hard @@ -9368,12 +9446,12 @@ __metadata: linkType: hard "builder-util@npm:*": - version: 25.0.0 - resolution: "builder-util@npm:25.0.0" + version: 25.0.2 + resolution: "builder-util@npm:25.0.2" dependencies: 7zip-bin: ~5.2.0 "@types/debug": ^4.1.6 - app-builder-bin: v5.0.0-alpha.4 + app-builder-bin: 5.0.0-alpha.6 bluebird-lst: ^1.0.9 builder-util-runtime: 9.2.5 chalk: ^4.1.2 @@ -9387,7 +9465,7 @@ __metadata: source-map-support: ^0.5.19 stat-mode: ^1.0.0 temp-file: ^3.4.0 - checksum: 9b09e2765e28d42d1fe692242022c74e9227a1ac7ea89f87d15efd69573ecd4c4589f9724b5795a4dd123f262f1fc39190c7888e9b63beb1c41b3f9802ba0a65 + checksum: 6bbcabf250336d217c596417234f57f44fbcee6421486b7a6f3a4cbba2f3799c8ff695e00b775b2f9ecf69852005734e193c932c5afde3d5d617462669d8c7fe languageName: node linkType: hard @@ -9539,9 +9617,9 @@ __metadata: linkType: hard "caniuse-lite@npm:^1.0.30001640": - version: 1.0.30001642 - resolution: "caniuse-lite@npm:1.0.30001642" - checksum: 23f823ec115306eaf9299521328bb6ad0c4ce65254c375b14fd497ceda759ee8ee5b8763b7b622cb36b6b5fb53c6cb8569785fba842fe289be7dc3fcf008eb4f + version: 1.0.30001643 + resolution: "caniuse-lite@npm:1.0.30001643" + checksum: e39991c13a0fd8f5c2aa99c9128188e4c4e9d6a203c3da6270c36285460ef152c5e9410ee4db560aa723904668946afe50541dce9636ab5e61434ba71dc22955 languageName: node linkType: hard @@ -10664,14 +10742,14 @@ __metadata: linkType: hard "debug@npm:4, debug@npm:^4, debug@npm:^4.0.0, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4": - version: 4.3.5 - resolution: "debug@npm:4.3.5" + version: 4.3.6 + resolution: "debug@npm:4.3.6" dependencies: ms: 2.1.2 peerDependenciesMeta: supports-color: optional: true - checksum: 7c002b51e256257f936dda09eb37167df952758c57badf6bf44bdc40b89a4bcb8e5a0a2e4c7b53f97c69e2970dd5272d33a757378a12c8f8e64ea7bf99e8e86e + checksum: 1630b748dea3c581295e02137a9f5cbe2c1d85fea35c1e6597a65ca2b16a6fce68cec61b299d480787ef310ba927dc8c92d3061faba0ad06c6a724672f66be7f languageName: node linkType: hard @@ -11486,9 +11564,9 @@ __metadata: linkType: hard "electron-to-chromium@npm:^1.4.820": - version: 1.4.829 - resolution: "electron-to-chromium@npm:1.4.829" - checksum: e35b34f5ea631dcd92609d1b7277db3f640eb3912e95edc3e238a9cc9c79ff930d353d95c4760b7d64739c607c6a136b05988b6d05a1367e9387b4d002988a3a + version: 1.5.2 + resolution: "electron-to-chromium@npm:1.5.2" + checksum: 530a9a4dc4aa0220abf564be49b7090470eac6e9a03acb667deadaf139c7f65466b4540ff5699677f9370f2a05619e89fc089f81603d36d33dc5acc75f12171e languageName: node linkType: hard @@ -11612,12 +11690,12 @@ __metadata: linkType: hard "enhanced-resolve@npm:^5.0.0, enhanced-resolve@npm:^5.17.0": - version: 5.17.0 - resolution: "enhanced-resolve@npm:5.17.0" + version: 5.17.1 + resolution: "enhanced-resolve@npm:5.17.1" dependencies: graceful-fs: ^4.2.4 tapable: ^2.2.0 - checksum: 1066000454da6a7aeabdbe1f433d912d1e39e6892142a78a37b6577aab27e0436091fa1399d857ad87085b1c3b73a0f811c8874da3dbdc40fbd5ebe89a5568e6 + checksum: 4bc38cf1cea96456f97503db7280394177d1bc46f8f87c267297d04f795ac5efa81e48115a2f5b6273c781027b5b6bfc5f62b54df629e4d25fa7001a86624f59 languageName: node linkType: hard @@ -11863,13 +11941,13 @@ __metadata: linkType: hard "esbuild-register@npm:^3.5.0": - version: 3.5.0 - resolution: "esbuild-register@npm:3.5.0" + version: 3.6.0 + resolution: "esbuild-register@npm:3.6.0" dependencies: debug: ^4.3.4 peerDependencies: esbuild: ">=0.12 <1" - checksum: f4307753c9672a2c901d04a1165031594a854f0a4c6f4c1db08aa393b68a193d38f2df483dc8ca0513e89f7b8998415e7e26fb9830989fb8cdccc5fb5f181c6b + checksum: 9221e26dde3366398a43183b600d8e9252b8003516cd766983a06c321eb07cf1b6b236948a21e4d1728c17a341c0fa52b49409c951d89fc7bf65d07d43c31a05 languageName: node linkType: hard @@ -14511,14 +14589,14 @@ __metadata: linkType: hard "import-local@npm:^3.0.2": - version: 3.1.0 - resolution: "import-local@npm:3.1.0" + version: 3.2.0 + resolution: "import-local@npm:3.2.0" dependencies: pkg-dir: ^4.2.0 resolve-cwd: ^3.0.0 bin: import-local-fixture: fixtures/cli.js - checksum: bfcdb63b5e3c0e245e347f3107564035b128a414c4da1172a20dc67db2504e05ede4ac2eee1252359f78b0bfd7b19ef180aec427c2fce6493ae782d73a04cddd + checksum: 0b0b0b412b2521739fbb85eeed834a3c34de9bc67e670b3d0b86248fc460d990a7b116ad056c084b87a693ef73d1f17268d6a5be626bb43c998a8b1c8a230004 languageName: node linkType: hard @@ -14574,7 +14652,7 @@ __metadata: languageName: node linkType: hard -"inline-style-prefixer@npm:^7.0.0": +"inline-style-prefixer@npm:^7.0.1": version: 7.0.1 resolution: "inline-style-prefixer@npm:7.0.1" dependencies: @@ -15307,8 +15385,8 @@ __metadata: linkType: hard "jake@npm:^10.8.5": - version: 10.9.1 - resolution: "jake@npm:10.9.1" + version: 10.9.2 + resolution: "jake@npm:10.9.2" dependencies: async: ^3.2.3 chalk: ^4.0.2 @@ -15316,7 +15394,7 @@ __metadata: minimatch: ^3.1.2 bin: jake: bin/cli.js - checksum: 49659c156b8ad921af377fb782505ae3cc7e7dd8793695b782070d99b4b66d2688b4e3efb32e09252400bfe6e49a7fb393a3a0959e8e1a51dbda95bcacbb9c36 + checksum: f2dc4a086b4f58446d02cb9be913c39710d9ea570218d7681bb861f7eeaecab7b458256c946aeaa7e548c5e0686cc293e6435501e4047174a3b6a504dcbfcaae languageName: node linkType: hard @@ -16791,14 +16869,14 @@ __metadata: linkType: hard "memfs@npm:^4.6.0": - version: 4.9.3 - resolution: "memfs@npm:4.9.3" + version: 4.11.0 + resolution: "memfs@npm:4.11.0" dependencies: "@jsonjoy.com/json-pack": ^1.0.3 - "@jsonjoy.com/util": ^1.1.2 + "@jsonjoy.com/util": ^1.3.0 tree-dump: ^1.0.1 tslib: ^2.0.0 - checksum: 65af465dd07d7859c2dd5a50d7d2cb3177d3e5b1d3be3c85361ef561a13728ae8404902ef14f0d5c8330c5b9730ce6b1723c375753b4cb2b9729762d8abb5550 + checksum: 87992fe38566df241bc8c4b7a231f6e59724fd8c350857e434677e14c695a24fed3e52f5cd103a5e4f99908487864ff1e41dcfc11b457f10a6934deb3c0257f8 languageName: node linkType: hard @@ -17591,21 +17669,21 @@ __metadata: linkType: hard "nano-css@npm:^5.3.1": - version: 5.6.1 - resolution: "nano-css@npm:5.6.1" + version: 5.6.2 + resolution: "nano-css@npm:5.6.2" dependencies: "@jridgewell/sourcemap-codec": ^1.4.15 css-tree: ^1.1.2 csstype: ^3.1.2 fastest-stable-stringify: ^2.0.2 - inline-style-prefixer: ^7.0.0 + inline-style-prefixer: ^7.0.1 rtl-css-js: ^1.16.1 stacktrace-js: ^2.0.2 stylis: ^4.3.0 peerDependencies: react: "*" react-dom: "*" - checksum: 735f02c030a9416bb6060503d24f18f2b2c9f43e4893c2d8714508d00f9d114b8a134df3623e94e376b0b1d794b0cacac6a48f8e5fb2b7fa8996071bcad590b8 + checksum: 85d5e730798387bee3090e9943801489ec4269bd376a848b75515cf0f44dc7ce53d4a9fec575081a7dff53a8a5d4b00eebdc1bbf217d75fae7195819f917aba1 languageName: node linkType: hard @@ -17781,9 +17859,9 @@ __metadata: linkType: hard "node-releases@npm:^2.0.14": - version: 2.0.17 - resolution: "node-releases@npm:2.0.17" - checksum: 2fd2969aa75ef6813efaabcec1a3199ef2552e3bba9245d2fc255fefedf819fb1dd3c12767047c1e132c561ad6cc39d954d0da3f6319bb966720bbc1f595058d + version: 2.0.18 + resolution: "node-releases@npm:2.0.18" + checksum: ef55a3d853e1269a6d6279b7692cd6ff3e40bc74947945101138745bfdc9a5edabfe72cb19a31a8e45752e1910c4c65c77d931866af6357f242b172b7283f5b3 languageName: node linkType: hard @@ -18758,13 +18836,13 @@ __metadata: linkType: hard "postcss@npm:^8.3.11, postcss@npm:^8.4.21, postcss@npm:^8.4.33, postcss@npm:^8.4.39": - version: 8.4.39 - resolution: "postcss@npm:8.4.39" + version: 8.4.40 + resolution: "postcss@npm:8.4.40" dependencies: nanoid: ^3.3.7 picocolors: ^1.0.1 source-map-js: ^1.2.0 - checksum: 14b130c90f165961772bdaf99c67f907f3d16494adf0868e57ef68baa67e0d1f6762db9d41ab0f4d09bab6fb7888588dba3596afd1a235fd5c2d43fba7006ac6 + checksum: afd0cc49d2169dcd96c0f17e155c5d75de048956306a3017f1cfa6a7d66b941592245bed20f7796ceeccb2d8967749b623be2c7b010a74f67ea10fb5bdb8ba28 languageName: node linkType: hard @@ -19085,7 +19163,7 @@ __metadata: languageName: node linkType: hard -"qs@npm:^6.10.0, qs@npm:^6.11.2": +"qs@npm:^6.10.0, qs@npm:^6.12.3": version: 6.12.3 resolution: "qs@npm:6.12.3" dependencies: @@ -22405,12 +22483,12 @@ __metadata: linkType: hard "typescript@npm:^4 || ^5, typescript@npm:^5.3.3": - version: 5.5.3 - resolution: "typescript@npm:5.5.3" + version: 5.5.4 + resolution: "typescript@npm:5.5.4" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 4b4f14313484d5c86064d04ba892544801fa551f5cf72719b540b498056fec7fc192d0bbdb2ba1448e759b1548769956da9e43e7c16781e8d8856787b0575004 + checksum: b309040f3a1cd91c68a5a58af6b9fdd4e849b8c42d837b2c2e73f9a4f96a98c4f1ed398a9aab576ee0a4748f5690cf594e6b99dbe61de7839da748c41e6d6ca8 languageName: node linkType: hard @@ -22425,12 +22503,12 @@ __metadata: linkType: hard "typescript@patch:typescript@^4 || ^5#~builtin, typescript@patch:typescript@^5.3.3#~builtin": - version: 5.5.3 - resolution: "typescript@patch:typescript@npm%3A5.5.3#~builtin::version=5.5.3&hash=f3b441" + version: 5.5.4 + resolution: "typescript@patch:typescript@npm%3A5.5.4#~builtin::version=5.5.4&hash=f3b441" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 6853be4607706cc1ad2f16047cf1cd72d39f79acd5f9716e1d23bc0e462c7f59be7458fe58a21665e7657a05433d7ab8419d093a5a4bd5f3a33f879b35d2769b + checksum: fc52962f31a5bcb716d4213bef516885e4f01f30cea797a831205fc9ef12b405a40561c40eae3127ab85ba1548e7df49df2bcdee6b84a94bfbe3a0d7eff16b14 languageName: node linkType: hard @@ -22460,11 +22538,11 @@ __metadata: linkType: hard "uglify-js@npm:^3.1.4": - version: 3.19.0 - resolution: "uglify-js@npm:3.19.0" + version: 3.19.1 + resolution: "uglify-js@npm:3.19.1" bin: uglifyjs: bin/uglifyjs - checksum: 23dc4778a9c5b5252888f3871e34b4a5e69ccc92e0febd9598c82cb559a7d550244ebc3f10eb0af0586c7cc34afe8be99d1581d9fcd36e3bed219d28d0fd3452 + checksum: c71e455b0adcc75631effbcc8fa868e3e906c97b73be034ccdb1373babfa30c3378356febec6bd9abe756dad80ba156af9654b9540244ab9950b56d2543cd54b languageName: node linkType: hard @@ -22769,14 +22847,14 @@ __metadata: linkType: hard "unplugin@npm:^1.3.1": - version: 1.11.0 - resolution: "unplugin@npm:1.11.0" + version: 1.12.0 + resolution: "unplugin@npm:1.12.0" dependencies: - acorn: ^8.11.3 + acorn: ^8.12.1 chokidar: ^3.6.0 webpack-sources: ^3.2.3 - webpack-virtual-modules: ^0.6.1 - checksum: b99ed2d0078fa49e81f5280e9cce58ce6ab2bd36700b4b5e02cafced96ef213ca1c6ed86cf95ef47ae3eda93cb4f79903927ec4f2068da302bd815f7c579aebc + webpack-virtual-modules: ^0.6.2 + checksum: 37de3409f1ee59f6a50bac832e1b42235beb4351b3a84fbd41e72bd13540c0bc99b7001b74cb0dca8781db7a15ca80b4623c375b153144c75f0b5224778c12cd languageName: node linkType: hard @@ -22832,12 +22910,12 @@ __metadata: linkType: hard "url@npm:^0.11.0": - version: 0.11.3 - resolution: "url@npm:0.11.3" + version: 0.11.4 + resolution: "url@npm:0.11.4" dependencies: punycode: ^1.4.1 - qs: ^6.11.2 - checksum: f9e7886f46a16f96d2e42fbcc5d682c231c55ef5442c1ff66150c0f6556f6e3a97d094a84f51be15ec2432711d212eb60426659ce418f5fcadeaa3f601532c4e + qs: ^6.12.3 + checksum: c25e587723d343d5d4248892393bfa5039ded9c2c07095a9d005bc64b7cb8956d623c0d8da8d1a28f71986a7a8d80fc2e9f9cf84235e48fa435a5cb4451062c6 languageName: node linkType: hard @@ -23409,7 +23487,7 @@ __metadata: languageName: node linkType: hard -"webpack-virtual-modules@npm:^0.6.1": +"webpack-virtual-modules@npm:^0.6.2": version: 0.6.2 resolution: "webpack-virtual-modules@npm:0.6.2" checksum: 7e8e1d63f35864c815420cc2f27da8561a1e028255040698a352717de0ba46d3b3faf16f06c1a1965217054c4c2894eb9af53a85451870e919b5707ce9c5822d @@ -23798,11 +23876,11 @@ __metadata: linkType: hard "yaml@npm:^2.1.3": - version: 2.4.5 - resolution: "yaml@npm:2.4.5" + version: 2.5.0 + resolution: "yaml@npm:2.5.0" bin: yaml: bin.mjs - checksum: f8efd407c07e095f00f3031108c9960b2b12971d10162b1ec19007200f6c987d2e28f73283f4731119aa610f177a3ea03d4a8fcf640600a25de1b74d00c69b3d + checksum: a116dca5c61641d9bf1f1016c6e71daeb1ed4915f5930ed237d45ab7a605aa5d92c332ff64879a6cd088cabede008c778774e3060ffeb4cd617d28088e4b2d83 languageName: node linkType: hard