diff --git a/README.md b/README.md index 7c75d33..5a1de8a 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,60 @@ React wrapper for working with [`@comapeo/core`](https://github.com/digidem/coma npm install react @tanstack/react-query@5 @comapeo/core-react @comapeo/schema @comapeo/core @comapeo/ipc ``` +## Setup + +### Basic Setup + +Wrap your application with `ClientApiProvider` and a React Query `QueryClientProvider`: + +```tsx +import { ClientApiProvider } from '@comapeo/core-react' +import { QueryClient, QueryClientProvider } from '@tanstack/react-query' + +const queryClient = new QueryClient() + +function App() { + return ( + + + + + + ) +} +``` + +### Map Sharing Setup + +To use the map sharing hooks, you also need to wrap your application with `MapServerProvider`. Provide a `getBaseUrl` function that returns a Promise resolving to the base URL of your map server: + +```tsx +import { MapServerProvider } from '@comapeo/core-react' +import { createServer } from '@comapeo/map-server' + +const server = createServer() +const listenPromise = server.listen() + +const getBaseUrl = async () => { + const { localPort } = await listenPromise + return new URL(`http://localhost:${localPort}/`) +} + +function App() { + return ( + + + + + + + + ) +} +``` + +Hooks that communicate with the map server will wait for `getBaseUrl()` to resolve before making requests, so the provider can be mounted before the server is ready. You can also provide an optional `fetch` prop to use a custom fetch implementation. + ## API Documentation Still a work in progress. Currently lives in [`docs/API.md`](./docs/API.md). diff --git a/docs/API.md b/docs/API.md index 24d1706..649c137 100644 --- a/docs/API.md +++ b/docs/API.md @@ -6,6 +6,17 @@ - [useIsArchiveDevice](#useisarchivedevice) - [useSetOwnDeviceInfo](#usesetowndeviceinfo) - [useSetIsArchiveDevice](#usesetisarchivedevice) +- [ReceivedMapSharesProvider](#receivedmapsharesprovider) +- [SentMapSharesProvider](#sentmapsharesprovider) +- [useReceivedMapSharesActions](#usereceivedmapsharesactions) +- [useReceivedMapSharesState](#usereceivedmapsharesstate) +- [useReceivedMapSharesState](#usereceivedmapsharesstate) +- [useReceivedMapSharesState](#usereceivedmapsharesstate) +- [useSentMapSharesActions](#usesentmapsharesactions) +- [useSentMapSharesState](#usesentmapsharesstate) +- [createMapServerApi](#createmapserverapi) +- [MapServerProvider](#mapserverprovider) +- [useMapServerApi](#usemapserverapi) - [useProjectSettings](#useprojectsettings) - [useSingleProject](#usesingleproject) - [useManyProjects](#usemanyprojects) @@ -19,8 +30,12 @@ - [useRemoveServerPeer](#useremoveserverpeer) - [useCreateProject](#usecreateproject) - [useLeaveProject](#useleaveproject) +- [useImportProjectCategories](#useimportprojectcategories) - [useImportProjectConfig](#useimportprojectconfig) - [useUpdateProjectSettings](#useupdateprojectsettings) +- [useChangeMemberRole](#usechangememberrole) +- [useRemoveMember](#useremovemember) +- [useProjectOwnRoleChangeListener](#useprojectownrolechangelistener) - [useCreateBlob](#usecreateblob) - [useSyncState](#usesyncstate) - [useDataSyncProgress](#usedatasyncprogress) @@ -37,7 +52,7 @@ - [useCreateDocument](#usecreatedocument) - [useUpdateDocument](#useupdatedocument) - [useDeleteDocument](#usedeletedocument) -- [useSetUpInvitesListeners](#usesetupinviteslisteners) +- [usePresetsSelection](#usepresetsselection) - [useManyInvites](#usemanyinvites) - [useSingleInvite](#usesingleinvite) - [useAcceptInvite](#useacceptinvite) @@ -45,6 +60,14 @@ - [useSendInvite](#usesendinvite) - [useRequestCancelInvite](#userequestcancelinvite) - [useMapStyleUrl](#usemapstyleurl) +- [useManyReceivedMapShares](#usemanyreceivedmapshares) +- [useSingleReceivedMapShare](#usesinglereceivedmapshare) +- [useDownloadReceivedMapShare](#usedownloadreceivedmapshare) +- [useDeclineReceivedMapShare](#usedeclinereceivedmapshare) +- [useAbortReceivedMapShareDownload](#useabortreceivedmapsharedownload) +- [useSendMapShare](#usesendmapshare) +- [useCancelSentMapShare](#usecancelsentmapshare) +- [useSingleSentMapShare](#usesinglesentmapshare) ### ClientApiProvider @@ -52,7 +75,7 @@ Create a context provider that holds a CoMapeo API client instance. | Function | Type | | ---------- | ---------- | -| `ClientApiProvider` | `({ children, clientApi, }: { children: ReactNode; clientApi: MapeoClientApi; }) => Element` | +| `ClientApiProvider` | `({ children, clientApi, }: PropsWithChildren<{ clientApi: any; }>) => Element` | Parameters: @@ -67,7 +90,11 @@ set up, it will throw an error. | Function | Type | | ---------- | ---------- | -| `useClientApi` | `() => MapeoClientApi` | +| `useClientApi` | `() => any` | + +Returns: + +Client API instance Examples: @@ -95,7 +122,7 @@ Retrieve info about the current device. | Function | Type | | ---------- | ---------- | -| `useOwnDeviceInfo` | `() => { data: { deviceId: string; deviceType: "UNRECOGNIZED" or "device_type_unspecified" or "mobile" or "tablet" or "desktop" or "selfHostedServer"; } and Partial; error: Error or null; isRefetching: boolean; }` | +| `useOwnDeviceInfo` | `() => { data: any; error: Error or null; isRefetching: boolean; }` | Examples: @@ -112,7 +139,7 @@ Retrieve whether the current device is an archive device or not. | Function | Type | | ---------- | ---------- | -| `useIsArchiveDevice` | `() => { data: boolean; error: Error or null; isRefetching: boolean; }` | +| `useIsArchiveDevice` | `() => { data: any; error: Error or null; isRefetching: boolean; }` | Examples: @@ -129,7 +156,7 @@ Update the device info for the current device. | Function | Type | | ---------- | ---------- | -| `useSetOwnDeviceInfo` | `() => { error: Error; mutate: UseMutateFunction; mutateAsync: UseMutateAsyncFunction<...>; reset: () => void; status: "error"; } or { ...; }` | +| `useSetOwnDeviceInfo` | `() => { error: Error; mutate: UseMutateFunction; mutateAsync: UseMutateAsyncFunction<...>; reset: () => void; status: "error"; } or { ...; }` | ### useSetIsArchiveDevice @@ -137,7 +164,120 @@ Set or unset the current device as an archive device. | Function | Type | | ---------- | ---------- | -| `useSetIsArchiveDevice` | `() => { error: Error; mutate: UseMutateFunction; mutateAsync: UseMutateAsyncFunction; reset: () => void; status: "error"; } or { ...; }` | +| `useSetIsArchiveDevice` | `() => { error: Error; mutate: UseMutateFunction; mutateAsync: UseMutateAsyncFunction; reset: () => void; status: "error"; } or { ...; }` | + +### ReceivedMapSharesProvider + +| Function | Type | +| ---------- | ---------- | +| `ReceivedMapSharesProvider` | `({ children, clientApi, mapServerApi, }: MapSharesProviderProps) => Element` | + +### SentMapSharesProvider + +| Function | Type | +| ---------- | ---------- | +| `SentMapSharesProvider` | `({ children, clientApi, mapServerApi, }: MapSharesProviderProps) => Element` | + +### useReceivedMapSharesActions + +| Function | Type | +| ---------- | ---------- | +| `useReceivedMapSharesActions` | `() => { download({ shareId }: DownloadMapShareOptions): Promise; decline({ shareId, reason }: DeclineMapShareOptions): Promise; abort({ shareId }: AbortMapShareOptions): Promise<...>; }` | + +### useReceivedMapSharesState + +| Function | Type | +| ---------- | ---------- | +| `useReceivedMapSharesState` | `{ (): any[]; (selector: (state: any[]) => T): T; }` | + +### useReceivedMapSharesState + +| Function | Type | +| ---------- | ---------- | +| `useReceivedMapSharesState` | `{ (): any[]; (selector: (state: any[]) => T): T; }` | + +### useReceivedMapSharesState + +| Function | Type | +| ---------- | ---------- | +| `useReceivedMapSharesState` | `{ (): any[]; (selector: (state: any[]) => T): T; }` | + +### useSentMapSharesActions + +| Function | Type | +| ---------- | ---------- | +| `useSentMapSharesActions` | `() => { createAndSend({ projectId, receiverDeviceId, mapId, }: CreateAndSendMapShareOptions): Promise; cancel({ shareId }: CancelMapShareOptions): Promise<...>; }` | + +### useSentMapSharesState + +| Function | Type | +| ---------- | ---------- | +| `useSentMapSharesState` | `(selector?: ((state: ServerMapShareState[]) => T) or undefined) => T` | + +### createMapServerApi + +Utility function to create a MapServerApi instance. +Only exported for unit testing purposes. + +| Function | Type | +| ---------- | ---------- | +| `createMapServerApi` | `({ getBaseUrl, fetch, }: MapServerApiOptions) => MapServerApi` | + +Parameters: + +* `opts.getBaseUrl`: A function that returns a promise that resolves to the base URL of the map server. +* `opts.fetch`: An optional custom fetch function to use for making requests to the map server. If not provided, the global `fetch` will be used. + + +### MapServerProvider + +Create a context provider that holds a `MapServerFetch` function, which waits +for the map server to be ready before making requests. + +| Function | Type | +| ---------- | ---------- | +| `MapServerProvider` | `({ children, getBaseUrl, fetch, }: MapServerProviderProps) => Element` | + +Parameters: + +* `opts.children`: React children node +* `opts.getBaseUrl`: A function that returns a promise that resolves to the base URL of the map server. +* `opts.fetch`: An optional custom fetch function to use for making requests to the map server. If not provided, the global `fetch` will be used. + + +Examples: + +```tsx +import { createServer } from '@comapeo/map-server' + +const server = createServer() +const listenPromise = server.listen() + +const getBaseUrl = async () => { + const { localPort } = await listenPromise + return new URL(`http://localhost:${localPort}/`) +} + +const mapServerApi = createMapServerApi({ getBaseUrl }) + +function App() { + return ( + + + + ) +} +``` + + +### useMapServerApi + +Internal hook to get the MapServerApi (instance of ky) from context. +Throws if used outside of MapServerProvider. + +| Function | Type | +| ---------- | ---------- | +| `useMapServerApi` | `() => MapServerApi` | ### useProjectSettings @@ -145,7 +285,7 @@ Retrieve the project settings for a project. | Function | Type | | ---------- | ---------- | -| `useProjectSettings` | `({ projectId }: { projectId: string; }) => { data: EditableProjectSettings; error: Error or null; isRefetching: boolean; }` | +| `useProjectSettings` | `({ projectId }: { projectId: string; }) => { data: any; error: Error or null; isRefetching: boolean; }` | Parameters: @@ -171,7 +311,7 @@ This is mostly used internally by the other hooks and should only be used if cer | Function | Type | | ---------- | ---------- | -| `useSingleProject` | `({ projectId }: { projectId: string; }) => { data: ClientApi; error: Error or null; isRefetching: boolean; }` | +| `useSingleProject` | `({ projectId }: { projectId: string; }) => { data: any; error: Error or null; isRefetching: boolean; }` | Parameters: @@ -193,7 +333,7 @@ Retrieve project information for each project that exists. | Function | Type | | ---------- | ---------- | -| `useManyProjects` | `() => { data: (Pick<{ schemaName: "projectSettings"; name?: string or undefined; defaultPresets?: { point: string[]; area: string[]; vertex: string[]; line: string[]; relation: string[]; } or undefined; configMetadata?: { ...; } or undefined; }, "name"> and { ...; })[]; error: Error or null; isRefetching: boolean; }` | +| `useManyProjects` | `() => { data: any; error: Error or null; isRefetching: boolean; }` | Examples: @@ -212,7 +352,7 @@ Retrieve a single member of a project. | Function | Type | | ---------- | ---------- | -| `useSingleMember` | `({ projectId, deviceId, }: { projectId: string; deviceId: string; }) => { data: MemberInfo; error: Error or null; isRefetching: boolean; }` | +| `useSingleMember` | `({ projectId, deviceId, }: { projectId: string; deviceId: string; }) => { data: any; error: Error or null; isRefetching: boolean; }` | Parameters: @@ -237,7 +377,7 @@ Retrieve all members of a project. | Function | Type | | ---------- | ---------- | -| `useManyMembers` | `({ projectId }: { projectId: string; }) => { data: MemberInfo[]; error: Error or null; isRefetching: boolean; }` | +| `useManyMembers` | `({ projectId }: { projectId: string; }) => { data: any; error: Error or null; isRefetching: boolean; }` | Parameters: @@ -367,7 +507,7 @@ Retrieve the device ID that created a document. | Function | Type | | ---------- | ---------- | -| `useDocumentCreatedBy` | `({ projectId, originalVersionId, }: { projectId: string; originalVersionId: string; }) => { data: string; error: Error or null; isRefetching: boolean; }` | +| `useDocumentCreatedBy` | `({ projectId, originalVersionId, }: { projectId: string; originalVersionId: string; }) => { data: any; error: Error or null; isRefetching: boolean; }` | Parameters: @@ -394,7 +534,7 @@ This is a more convenient alternative to using the `useOwnDeviceInfo` and `useMa | Function | Type | | ---------- | ---------- | -| `useOwnRoleInProject` | `({ projectId }: { projectId: string; }) => { data: Role<"a12a6702b93bd7ff" or "f7c150f5a3a9a855" or "012fd2d431c0bf60" or "9e6d29263cba36c9" or "8ced989b1904606b" or "a24eaca65ab5d5d0" or "08e4251e36f6e7ed">; error: Error or null; isRefetching: boolean; }` | +| `useOwnRoleInProject` | `({ projectId }: { projectId: string; }) => { data: any; error: Error or null; isRefetching: boolean; }` | Parameters: @@ -416,13 +556,13 @@ function BasicExample() { | Function | Type | | ---------- | ---------- | -| `useAddServerPeer` | `({ projectId }: { projectId: string; }) => { error: Error; mutate: UseMutateFunction; mutateAsync: UseMutateAsyncFunction<...>; reset: () => void; status: "error"; } or { ...; }` | +| `useAddServerPeer` | `({ projectId }: { projectId: string; }) => { error: Error; mutate: UseMutateFunction; mutateAsync: UseMutateAsyncFunction<...>; reset: () => void; status: "error"; } or { ...; }` | ### useRemoveServerPeer | Function | Type | | ---------- | ---------- | -| `useRemoveServerPeer` | `({ projectId }: { projectId: string; }) => { error: Error; mutate: UseMutateFunction; mutateAsync: UseMutateAsyncFunction<...>; reset: () => void; status: "error"; } or { ...; }` | +| `useRemoveServerPeer` | `({ projectId }: { projectId: string; }) => { error: Error; mutate: UseMutateFunction; mutateAsync: UseMutateAsyncFunction<...>; reset: () => void; status: "error"; } or { ...; }` | ### useCreateProject @@ -430,7 +570,7 @@ Create a new project. | Function | Type | | ---------- | ---------- | -| `useCreateProject` | `() => { error: Error; mutate: UseMutateFunction; mutateAsync: UseMutateAsyncFunction<...>; reset: () => void; status: "error"; } or { ...; }` | +| `useCreateProject` | `() => { error: Error; mutate: UseMutateFunction; mutateAsync: UseMutateAsyncFunction<...>; reset: () => void; status: "error"; } or { ...; }` | ### useLeaveProject @@ -438,7 +578,20 @@ Leave an existing project. | Function | Type | | ---------- | ---------- | -| `useLeaveProject` | `() => { error: Error; mutate: UseMutateFunction; mutateAsync: UseMutateAsyncFunction; reset: () => void; status: "error"; } or { ...; }` | +| `useLeaveProject` | `() => { error: Error; mutate: UseMutateFunction; mutateAsync: UseMutateAsyncFunction; reset: () => void; status: "error"; } or { ...; }` | + +### useImportProjectCategories + +Update the categories of a project using an external file. + +| Function | Type | +| ---------- | ---------- | +| `useImportProjectCategories` | `({ projectId, }: { projectId: string; }) => { error: Error; mutate: UseMutateFunction; mutateAsync: UseMutateAsyncFunction; reset: () => void; status: "error"; } or { ...; }` | + +Parameters: + +* `opts.projectId`: Public ID of the project to apply changes to. + ### useImportProjectConfig @@ -446,7 +599,7 @@ Update the configuration of a project using an external file. | Function | Type | | ---------- | ---------- | -| `useImportProjectConfig` | `({ projectId }: { projectId: string; }) => { error: Error; mutate: UseMutateFunction; mutateAsync: UseMutateAsyncFunction; reset: () => void; status: "error"; } or { ...; }` | +| `useImportProjectConfig` | `({ projectId }: { projectId: string; }) => { error: Error; mutate: UseMutateFunction; mutateAsync: UseMutateAsyncFunction; reset: () => void; status: "error"; } or { ...; }` | Parameters: @@ -459,20 +612,108 @@ Update the settings of a project. | Function | Type | | ---------- | ---------- | -| `useUpdateProjectSettings` | `({ projectId }: { projectId: string; }) => { error: Error; mutate: UseMutateFunction; muta...` | +| `useUpdateProjectSettings` | `({ projectId }: { projectId: string; }) => { error: Error; mutate: UseMutateFunction, unknown>; mutateAsync: UseMutateAsyncFunction<...>; reset: () => void; status: "error"; } or { ...; }` | Parameters: * `opts.projectId`: Public ID of the project to apply changes to. +### useChangeMemberRole + +Change a project member's role. + +| Function | Type | +| ---------- | ---------- | +| `useChangeMemberRole` | `({ projectId }: { projectId: string; }) => { error: Error; mutate: UseMutateFunction; mutateAsync: UseMutateAsyncFunction<...>; reset: () => void; status: "error"; } or { ...; }` | + +Parameters: + +* `opts.projectId`: Project public ID + + +Examples: + +```tsx +function BasicExample() { + const { mutate } = useChangeMemberRole({ projectId: '...' }) + // Use one of: COORDINATOR_ROLE_ID, MEMBER_ROLE_ID, BLOCKED_ROLE_ID + mutate({ deviceId: '...', roleId: COORDINATOR_ROLE_ID }) +} +``` + + +### useRemoveMember + +Remove a member from a project, providing an optional reason for removal. + +Do NOT use this for removing your own device from a project. Use `useLeaveProject` instead. + +| Function | Type | +| ---------- | ---------- | +| `useRemoveMember` | `({ projectId }: { projectId: string; }) => { error: Error; mutate: UseMutateFunction; mutateAsync: UseMutateAsyncFunction<...>; reset: () => void; status: "error"; } or { ...; }` | + +Parameters: + +* `opts.projectId`: Project public ID + + +Examples: + +```tsx +function BasicExample() { + const { mutate } = useRemoveMember({ projectId: '...' }) + mutate({ + deviceId: '...', + // Optional + reason: '...', + }) +} +``` + + +### useProjectOwnRoleChangeListener + +Set up listener for changes to your own role in a project. +It is necessary to use this if you want the project role-related read hooks to update +based on role change events that are received in the background. + +| Function | Type | +| ---------- | ---------- | +| `useProjectOwnRoleChangeListener` | `({ projectId, listener, }: { projectId: string; listener?: ((event: RoleChangeEvent) => void) or undefined; }) => void` | + +Parameters: + +* `opts.listener`: Optional listener to invoke when role changes + + +Examples: + +```tsx +function SomeComponent({ projectId }: { projectId: string }) { + useProjectOwnRoleChangeListener({ projectId }) +} +``` +```tsx +function ComponentWithListener({ projectId }: { projectId: string }) { + useProjectOwnRoleChangeListener({ + projectId, + listener: (event) => { + // Handle role change, e.g., navigate to default project + console.log('New role:', event.role) + } + }) +} +``` + + ### useCreateBlob Create a blob for a project. | Function | Type | | ---------- | ---------- | -| `useCreateBlob` | `({ projectId }: { projectId: string; }) => { error: Error; mutate: UseMutateFunction<{ driveId: string; name: string; type: "photo" or "audio" or "video"; hash: string; }, Error, { original: string; preview?: string or undefined; thumbnail?: string or undefined; metadata: Metadata; }, unknown>; mutateAsync: UseMutateAsy...` | +| `useCreateBlob` | `({ projectId }: { projectId: string; }) => { error: Error; mutate: UseMutateFunction; mutateAsync: UseMutateAsyncFunction<...>; reset: () => void; status: "error"; } or { ...; }` | Parameters: @@ -489,7 +730,7 @@ additional listeners across the IPC channel. | Function | Type | | ---------- | ---------- | -| `useSyncState` | `({ projectId, }: { projectId: string; }) => State or null` | +| `useSyncState` | `({ projectId, }: { projectId: string; }) => any` | Parameters: @@ -519,35 +760,39 @@ Provides the progress of data sync for sync-enabled connected peers | ---------- | ---------- | | `useDataSyncProgress` | `({ projectId, }: { projectId: string; }) => number or null` | +Returns: + +`null` if no sync state events have been received. Otherwise returns a value between 0 and 1 (inclusive) + ### useStartSync | Function | Type | | ---------- | ---------- | -| `useStartSync` | `({ projectId }: { projectId: string; }) => { error: Error; mutate: UseMutateFunction; mutateAsync: UseMutateAsyncFunction<...>; reset: () => void; status: "error"; } or { ...; }` | +| `useStartSync` | `({ projectId }: { projectId: string; }) => { error: Error; mutate: UseMutateFunction; mutateAsync: UseMutateAsyncFunction<...>; reset: () => void; status: "error"; } or { ...; }` | ### useStopSync | Function | Type | | ---------- | ---------- | -| `useStopSync` | `({ projectId }: { projectId: string; }) => { error: Error; mutate: UseMutateFunction; mutateAsync: UseMutateAsyncFunction; reset: () => void; status: "error"; } or { ...; }` | +| `useStopSync` | `({ projectId }: { projectId: string; }) => { error: Error; mutate: UseMutateFunction; mutateAsync: UseMutateAsyncFunction; reset: () => void; status: "error"; } or { ...; }` | ### useConnectSyncServers | Function | Type | | ---------- | ---------- | -| `useConnectSyncServers` | `({ projectId }: { projectId: string; }) => { error: Error; mutate: UseMutateFunction; mutateAsync: UseMutateAsyncFunction; reset: () => void; status: "error"; } or { ...; }` | +| `useConnectSyncServers` | `({ projectId }: { projectId: string; }) => { error: Error; mutate: UseMutateFunction; mutateAsync: UseMutateAsyncFunction; reset: () => void; status: "error"; } or { ...; }` | ### useDisconnectSyncServers | Function | Type | | ---------- | ---------- | -| `useDisconnectSyncServers` | `({ projectId }: { projectId: string; }) => { error: Error; mutate: UseMutateFunction; mutateAsync: UseMutateAsyncFunction; reset: () => void; status: "error"; } or { ...; }` | +| `useDisconnectSyncServers` | `({ projectId }: { projectId: string; }) => { error: Error; mutate: UseMutateFunction; mutateAsync: UseMutateAsyncFunction; reset: () => void; status: "error"; } or { ...; }` | ### useSetAutostopDataSyncTimeout | Function | Type | | ---------- | ---------- | -| `useSetAutostopDataSyncTimeout` | `({ projectId, }: { projectId: string; }) => { error: Error; mutate: UseMutateFunction; mutateAsync: UseMutateAsyncFunction; reset: () => void; status: "error"; } or { ...; }` | +| `useSetAutostopDataSyncTimeout` | `({ projectId, }: { projectId: string; }) => { error: Error; mutate: UseMutateFunction; mutateAsync: UseMutateAsyncFunction; reset: () => void; status: "error"; } or { ...; }` | ### useExportGeoJSON @@ -555,7 +800,7 @@ Creates a GeoJson file with all the observations and/or tracks in the project. | Function | Type | | ---------- | ---------- | -| `useExportGeoJSON` | `({ projectId }: { projectId: string; }) => { error: Error; mutate: UseMutateFunction; mutateAsync: UseMutateAsyncFunction<...>; reset: () => void; status: "error...` | +| `useExportGeoJSON` | `({ projectId }: { projectId: string; }) => { error: Error; mutate: UseMutateFunction; mutateAsync: UseMutateAsyncFunction<...>; reset: () => void; status: "error"; ...` | Parameters: @@ -568,7 +813,7 @@ Creates a zip file containing a GeoJson file with all the observations and/or tr | Function | Type | | ---------- | ---------- | -| `useExportZipFile` | `({ projectId }: { projectId: string; }) => { error: Error; mutate: UseMutateFunction; mutateAsync: UseMutateAsyncFunction<...>...` | +| `useExportZipFile` | `({ projectId }: { projectId: string; }) => { error: Error; mutate: UseMutateFunction; mutateAsync: UseMutateAsyncFunction<...>; r...` | Parameters: @@ -583,7 +828,7 @@ Triggers the closest error boundary if the document cannot be found | Function | Type | | ---------- | ---------- | -| `useSingleDocByDocId` | `({ projectId, docType, docId, lang, }: { projectId: string; docType: D; docId: string; lang?: string or undefined; }) => ReadHookResult({ projectId, docType, docId, lang, }: { projectId: string; docType: D; docId: string; lang?: string or undefined; }) => { data: any; error: Error or null; isRefetching: boolean; }` | Parameters: @@ -616,7 +861,7 @@ Triggers the closest error boundary if the document cannot be found. | Function | Type | | ---------- | ---------- | -| `useSingleDocByVersionId` | `({ projectId, docType, versionId, lang, }: { projectId: string; docType: D; versionId: string; lang?: string or undefined; }) => ReadHookResult({ projectId, docType, versionId, lang, }: { projectId: string; docType: D; versionId: string; lang?: string or undefined; }) => { data: any; error: Error or null; isRefetching: boolean; }` | Parameters: @@ -649,7 +894,7 @@ Retrieve all documents of a specific `docType`. | Function | Type | | ---------- | ---------- | -| `useManyDocs` | `({ projectId, docType, includeDeleted, lang, }: { projectId: string; docType: D; includeDeleted?: boolean or undefined; lang?: string or undefined; }) => ReadHookResult<(Extract<{ schemaName: "deviceInfo"; name: string; deviceType: "UNRECOGNIZED" or ... 4 more ... or "selfHostedServer"; ...` | +| `useManyDocs` | `({ projectId, docType, includeDeleted, lang, }: { projectId: string; docType: D; includeDeleted?: boolean or undefined; lang?: string or undefined; }) => { data: any; error: Error or null; isRefetching: boolean; }` | Parameters: @@ -693,7 +938,7 @@ Create a document for a project. | Function | Type | | ---------- | ---------- | -| `useCreateDocument` | `({ docType, projectId, }: { docType: D; projectId: string; }) => { error: Error; mutate: UseMutateFunction and { forks: string[]; }, Error, { ...; }, unknown>; mutateAsync: UseMutateAsyncFunction<...>; reset: () => void; status: "error"; } or { ...; }` | +| `useCreateDocument` | `({ docType, projectId, }: { docType: D; projectId: string; }) => { error: Error; mutate: UseMutateFunction and DerivedDocFields, Error, { ...; }, unknown>; mutateAsync: UseMutateAsyncFunction<...>; reset: () => void; status: "error"; } or { ...; }` | Parameters: @@ -707,7 +952,7 @@ Update a document within a project. | Function | Type | | ---------- | ---------- | -| `useUpdateDocument` | `({ docType, projectId, }: { docType: D; projectId: string; }) => { error: Error; mutate: UseMutateFunction and { forks: string[]; }, Error, { ...; }, unknown>; mutateAsync: UseMutateAsyncFunction<...>; reset: () => void; status: "error"; } or { ...; }` | +| `useUpdateDocument` | `({ docType, projectId, }: { docType: D; projectId: string; }) => { error: Error; mutate: UseMutateFunction and DerivedDocFields, Error, { ...; }, unknown>; mutateAsync: UseMutateAsyncFunction<...>; reset: () => void; status: "error"; } or { ...; }` | Parameters: @@ -721,7 +966,7 @@ Delete a document within a project. | Function | Type | | ---------- | ---------- | -| `useDeleteDocument` | `({ docType, projectId, }: { docType: D; projectId: string; }) => { error: Error; mutate: UseMutateFunction and { forks: string[]; }, Error, { ...; }, unknown>; mutateAsync: UseMutateAsyncFunction<...>; reset: () => void; status: "error"; } or { ...; }` | +| `useDeleteDocument` | `({ docType, projectId, }: { docType: D; projectId: string; }) => { error: Error; mutate: UseMutateFunction and DerivedDocFields, Error, { ...; }, unknown>; mutateAsync: UseMutateAsyncFunction<...>; reset: () => void; status: "error"; } or { ...; }` | Parameters: @@ -729,24 +974,41 @@ Parameters: * `opts.projectId`: Public ID of project document belongs to. -### useSetUpInvitesListeners +### usePresetsSelection -Set up listeners for received and updated invites. -It is necessary to use this if you want the invites-related read hooks to update -based on invites that are received or changed in the background. +Retrieve presets for category selection, ordered by project settings. + +Returns presets in the order defined by `projectSettings.defaultPresets` for the +specified data type. Falls back to alphabetical order (by preset name) if no defaults are configured. | Function | Type | | ---------- | ---------- | -| `useSetUpInvitesListeners` | `() => void` | +| `usePresetsSelection` | `({ projectId, dataType, lang, }: { projectId: string; dataType: "track" or "observation"; lang?: string or undefined; }) => { schemaName: "preset"; name: string; geometry: ("point" or "vertex" or "line" or "area" or "relation")[]; ... 13 more ...; deleted: boolean; }[]` | + +Parameters: + +* `opts.projectId`: Project public ID +* `opts.dataType`: Type of data being created ('observation' or 'track') +* `opts.lang`: Language to translate presets into + Examples: ```tsx -function App() { - // Use this somewhere near the root of the application - useSetUpInvitesListeners() +function ObservationCategoryChooser() { + const presets = usePresetsSelection({ + projectId: '...', + dataType: 'observation', + }) +} +``` - return +```tsx +function TrackCategoryChooser() { + const presets = usePresetsSelection({ + projectId: '...', + dataType: 'track', + }) } ``` @@ -757,7 +1019,7 @@ Get all invites that the device has received. | Function | Type | | ---------- | ---------- | -| `useManyInvites` | `() => { data: Invite[]; error: Error or null; isRefetching: boolean; }` | +| `useManyInvites` | `() => { data: any; error: Error or null; isRefetching: boolean; }` | Examples: @@ -774,7 +1036,7 @@ Get a single invite based on its ID. | Function | Type | | ---------- | ---------- | -| `useSingleInvite` | `({ inviteId }: { inviteId: string; }) => { data: Invite; error: Error or null; isRefetching: boolean; }` | +| `useSingleInvite` | `({ inviteId }: { inviteId: string; }) => { data: any; error: Error or null; isRefetching: boolean; }` | Parameters: @@ -796,7 +1058,7 @@ Accept an invite that has been received. | Function | Type | | ---------- | ---------- | -| `useAcceptInvite` | `() => { error: Error; mutate: UseMutateFunction; mutateAsync: UseMutateAsyncFunction; reset: () => void; status: "error"; } or { ...; }` | +| `useAcceptInvite` | `() => { error: Error; mutate: UseMutateFunction; mutateAsync: UseMutateAsyncFunction; reset: () => void; status: "error"; } or { ...; }` | ### useRejectInvite @@ -804,7 +1066,7 @@ Reject an invite that has been received. | Function | Type | | ---------- | ---------- | -| `useRejectInvite` | `() => { error: Error; mutate: UseMutateFunction; mutateAsync: UseMutateAsyncFunction; reset: () => void; status: "error"; } or { ...; }` | +| `useRejectInvite` | `() => { error: Error; mutate: UseMutateFunction; mutateAsync: UseMutateAsyncFunction; reset: () => void; status: "error"; } or { ...; }` | ### useSendInvite @@ -812,7 +1074,7 @@ Send an invite for a project. | Function | Type | | ---------- | ---------- | -| `useSendInvite` | `({ projectId }: { projectId: string; }) => { error: Error; mutate: UseMutateFunction<"ACCEPT" or "REJECT" or "ALREADY", Error, { deviceId: string; roleDescription?: string or undefined; roleId: "f7c150f5a3a9a855" or "012fd2d431c0bf60" or "9e6d29263cba36c9"; roleName?: string or undefined; }, unknown>; mutateAsync: UseMuta...` | +| `useSendInvite` | `({ projectId }: { projectId: string; }) => { error: Error; mutate: UseMutateFunction; mutateAsync: UseMutateAsyncFunction<...>; reset:...` | Parameters: @@ -825,7 +1087,7 @@ Request a cancellation of an invite sent to another device. | Function | Type | | ---------- | ---------- | -| `useRequestCancelInvite` | `({ projectId }: { projectId: string; }) => { error: Error; mutate: UseMutateFunction; mutateAsync: UseMutateAsyncFunction; reset: () => void; status: "error"; } or { ...; }` | +| `useRequestCancelInvite` | `({ projectId }: { projectId: string; }) => { error: Error; mutate: UseMutateFunction; mutateAsync: UseMutateAsyncFunction; reset: () => void; status: "error"; } or { ...; }` | Parameters: @@ -868,40 +1130,285 @@ function ExampleWithRefreshToken() { ``` +### useManyReceivedMapShares + +Get all map shares that the device has received. Automatically updates when +new shares arrive or share states change. + +IMPORTANT: This hook will not trigger a re-render when download progress +updates, only when the status changes. This is to avoid excessive re-renders +during downloads. Use `useSingleReceivedMapShare` to get real-time updates on +a specific share, including download progress. + +| Function | Type | +| ---------- | ---------- | +| `useManyReceivedMapShares` | `() => any[]` | + +Examples: + +```tsx +function MapSharesList() { + const shares = useManyReceivedMapShares() + + return shares.map(share => ( +
+ {share.mapName} from {share.senderDeviceName} - {share.state} +
+ )) +} +``` + + +### useSingleReceivedMapShare + +Get a single received map share based on its shareId. + +| Function | Type | +| ---------- | ---------- | +| `useSingleReceivedMapShare` | `({ shareId }: { shareId: string; }) => any` | + +Parameters: + +* `opts.shareId`: ID of the map share + + +Examples: + +```tsx +function MapShareDetail({ shareId }: { shareId: string }) { + const share = useSingleReceivedMapShare({ shareId }) + + return
{share.mapName} - {share.state}
+} +``` + + +### useDownloadReceivedMapShare + +Accept and download a map share that has been received. The mutate promise +resolves once the map _starts_ downloading, before it finishes downloading. +Use `useManyMapShares` or `useSingleMapShare` to track download progress. + +Throws if the share is not in `status="pending"` or if the download fails to +start (e.g. if the shareId if invalid). + +| Function | Type | +| ---------- | ---------- | +| `useDownloadReceivedMapShare` | `() => Pick, Error, Omit, unknown>, { ...; }> and { ...; }, "error" or ... 3 more ... or "mutateAsync"> or Pick<...> or Pick<...> or Pick<...>` | + +Examples: + +```tsx +function AcceptButton({ shareId }: { shareId: string }) { + const { mutate: accept } = useAcceptMapShare() + + return +} +``` + + +### useDeclineReceivedMapShare + +Decline a map share that has been received. Notifies the sender that the +share was declined. + +Throws if the share is not with `status="pending"` +Throws if shareId is invalid +Throws if decline request fails (e.g. network error) + +| Function | Type | +| ---------- | ---------- | +| `useDeclineReceivedMapShare` | `() => Pick, Error, Omit, unknown>, { ...; }> and { ...; }, "error" or ... 3 more ... or "mutateAsync"> or Pick<...> or Pick<...> or Pick<...>` | + +Examples: + +```tsx +function DeclineButton({ shareId }: { shareId: string }) { + const { mutate: decline } = useDeclineMapShare() + + return ( + + ) +} +``` + + +### useAbortReceivedMapShareDownload + +Abort an in-progress map share download. + +Throws if the share is not in `status="downloading"` +Throws if shareId is invalid + +| Function | Type | +| ---------- | ---------- | +| `useAbortReceivedMapShareDownload` | `() => Pick, Error, Omit, unknown>, { ...; }> and { ...; }, "error" or ... 3 more ... or "mutateAsync"> or Pick<...> or Pick<...> or Pick<...>` | + +Examples: + +```tsx +function AbortButton({ shareId }: { shareId: string }) { + const { mutate: abort } = useAbortMapShareDownload() + + return +} +``` + + +### useSendMapShare + +Share a map with a device. The mutation resolves immediately after sending +the share offer, without waiting for the recipient to accept or reject. The +mutation resolves with the created map share object, including its ID, which +can be used to track the share status with `useSingleSentMapShare`. + +| Function | Type | +| ---------- | ---------- | +| `useSendMapShare` | `({ projectId }: { projectId: string; }) => Pick, Error, CreateAndSendMapShareOptions, unknown>, { ...; }> and { ...; }, "error" or ... 3 more ... or "mutateAsync"> or Pick<...> or Pick<...> or Pick<...>` | + +Parameters: + +* `opts.projectId`: Public ID of project for sending the map share: you can only send map shares to users on the same project + + +Examples: + +```tsx +function SendMapButton({ projectId, deviceId }: { projectId: string; deviceId: string }) { + const { mutate: send } = useSendMapShare({ projectId }, { + onSuccess: (mapShare) => { + console.log('Share sent with id', mapShare.shareId) + } + }) + + return ( + + ) +} +``` + + +### useCancelSentMapShare + +Cancel a map share that was previously sent. If the recipient has not yet +started downloading the share, they will not be notified until they attempt +to accept the share and begin downloading it. If they are already downloading +the share, the download will be canceled before completion. If the download +is already complete, this action will throw an error. + +| Function | Type | +| ---------- | ---------- | +| `useCancelSentMapShare` | `() => Pick, Error, Omit, unknown>, { ...; }> and { ...; }, "error" or ... 3 more ... or "mutateAsync"> or Pick<...> or Pick<...> or Pick<...>` | + +Parameters: + +* `opts.projectId`: Public ID of project to request the map share cancellation for. + + +Examples: + +```tsx +function CancelShareButton({ projectId, shareId }: { projectId: string; shareId: string }) { + const { mutate: cancel } = useRequestCancelMapShare({ projectId }) + + return +} +``` + + +### useSingleSentMapShare + +Track the status and progress of a sent map share. Returns the current state +of the share, updated in real-time. When the recipient starts downloading, or +if they decline the share, then the returned share will update. + +Throws if no share with the specified ID is found. + +| Function | Type | +| ---------- | ---------- | +| `useSingleSentMapShare` | `({ shareId, }: { shareId: string; }) => ServerMapShareState` | + +Parameters: + +* `opts.shareId`: ID of the sent map share + + +Examples: + +```tsx +function SentShareStatus({ shareId }: { shareId: string }) { + const mapShare = useSingleSentMapShare({ shareId }) + + return (
+
Share status: {mapShare.status}
+ {mapShare.status === 'pending' &&
Waiting for recipient to accept...
} + {mapShare.status === 'downloading' && (
Download in progress: {mapShare.downloadProgress}%
)} + {mapShare.status === 'declined' &&
Share was declined by recipient
} + {mapShare.status === 'canceled' &&
Share was canceled
} +
) +} +``` + + ## Constants - [ClientApiContext](#clientapicontext) +- [ReceivedMapSharesContext](#receivedmapsharescontext) +- [SentMapSharesContext](#sentmapsharescontext) +- [MapServerContext](#mapservercontext) ### ClientApiContext | Constant | Type | | ---------- | ---------- | -| `ClientApiContext` | `Context` | +| `ClientApiContext` | `Context` | + +### ReceivedMapSharesContext + +| Constant | Type | +| ---------- | ---------- | +| `ReceivedMapSharesContext` | `Context<{ subscribe: (listener: () => void) => () => boolean; getSnapshot: () => any[]; actions: { download({ shareId }: DownloadMapShareOptions): Promise; decline({ shareId, reason }: DeclineMapShareOptions): Promise<...>; abort({ shareId }: AbortMapShareOptions): Promise<...>; }; } or null>` | + +### SentMapSharesContext + +| Constant | Type | +| ---------- | ---------- | +| `SentMapSharesContext` | `Context<{ subscribe: (listener: () => void) => () => boolean; getSnapshot: () => ServerMapShareState[]; actions: { createAndSend({ projectId, receiverDeviceId, mapId, }: CreateAndSendMapShareOptions): Promise; cancel({ shareId }: CancelMapShareOptions): Promise<...>; }; } or null>` | + +### MapServerContext + +| Constant | Type | +| ---------- | ---------- | +| `MapServerContext` | `Context` | ## Types -- [WriteableDocumentType](#writeabledocumenttype) -- [WriteableValue](#writeablevalue) -- [WriteableDocument](#writeabledocument) +- [MapServerApiOptions](#mapserverapioptions) +- [MapServerApi](#mapserverapi) +- [MapServerProviderProps](#mapserverproviderprops) -### WriteableDocumentType +### MapServerApiOptions | Type | Type | | ---------- | ---------- | -| `WriteableDocumentType` | `Extract< MapeoDoc['schemaName'], 'field' or 'observation' or 'preset' or 'track' or 'remoteDetectionAlert' >` | +| `MapServerApiOptions` | `{ getBaseUrl(): Promise fetch?( input: string or URL or Request, options?: RequestInit, ): Promise }` | -### WriteableValue +### MapServerApi | Type | Type | | ---------- | ---------- | -| `WriteableValue` | `Extract< MapeoValue, { schemaName: D } >` | +| `MapServerApi` | `KyInstance and { createEventSource(options: EventSourceOptions): EventSourceClient getMapStyleJsonUrl(mapId: string): Promise }` | -### WriteableDocument +### MapServerProviderProps | Type | Type | | ---------- | ---------- | -| `WriteableDocument` | `Extract< MapeoDoc, { schemaName: D } >` | +| `MapServerProviderProps` | `PropsWithChildren` | diff --git a/package-lock.json b/package-lock.json index 042cdfc..b6e1f30 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,8 +8,13 @@ "name": "@comapeo/core-react", "version": "7.2.0", "license": "MIT", + "dependencies": { + "@comapeo/map-server": "^1.0.0-pre.7", + "ensure-error": "5.0.0", + "eventsource-client": "1.2.0" + }, "devDependencies": { - "@comapeo/core": "5.2.1", + "@comapeo/core": "5.4.0", "@comapeo/ipc": "6.0.2", "@comapeo/schema": "2.2.0", "@eslint/compat": "2.0.0", @@ -22,6 +27,7 @@ "@tanstack/react-query": "5.90.12", "@testing-library/dom": "10.4.1", "@testing-library/react": "16.3.1", + "@types/jsdom": "^27.0.0", "@types/node": "22.19.3", "@types/react": "19.2.7", "@types/react-dom": "19.2.3", @@ -33,6 +39,8 @@ "globals": "16.5.0", "happy-dom": "20.0.11", "husky": "9.1.7", + "jsdom": "28.0.0", + "ky": "^1.14.3", "lint-staged": "16.2.7", "npm-run-all2": "8.0.4", "prettier": "3.7.4", @@ -41,8 +49,10 @@ "react-dom": "19.2.3", "tsdoc-markdown": "1.4.1", "tshy": "3.1.0", + "type-fest": "5.4.3", "typescript": "5.9.3", "typescript-eslint": "8.49.0", + "uint8array-extras": "1.5.0", "vitest": "4.0.15" }, "peerDependencies": { @@ -53,14 +63,83 @@ "react": "^18 || ^19" } }, + "node_modules/@acemir/cssom": { + "version": "0.9.31", + "dev": true, + "license": "MIT" + }, + "node_modules/@asamuzakjp/css-color": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@csstools/css-calc": "^3.0.0", + "@csstools/css-color-parser": "^4.0.1", + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0", + "lru-cache": "^11.2.5" + } + }, + "node_modules/@asamuzakjp/css-color/node_modules/lru-cache": { + "version": "11.2.6", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@asamuzakjp/dom-selector": { + "version": "6.7.8", + "dev": true, + "license": "MIT", + "dependencies": { + "@asamuzakjp/nwsapi": "^2.3.9", + "bidi-js": "^1.0.3", + "css-tree": "^3.1.0", + "is-potential-custom-element-name": "^1.0.1", + "lru-cache": "^11.2.5" + } + }, + "node_modules/@asamuzakjp/dom-selector/node_modules/lru-cache": { + "version": "11.2.6", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@asamuzakjp/nwsapi": { + "version": "2.3.9", + "dev": true, + "license": "MIT" + }, + "node_modules/@augment-vir/common": { + "version": "26.4.0", + "license": "MIT", + "dependencies": { + "browser-or-node": "^2.1.1", + "run-time-assertions": "^1.0.0", + "type-fest": "^4.12.0" + } + }, + "node_modules/@augment-vir/common/node_modules/type-fest": { + "version": "4.41.0", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@babel/code-frame": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", - "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", + "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" }, @@ -69,9 +148,9 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.5.tgz", - "integrity": "sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.0.tgz", + "integrity": "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==", "dev": true, "license": "MIT", "engines": { @@ -79,21 +158,22 @@ } }, "node_modules/@babel/core": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.5.tgz", - "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.28.5", - "@babel/helper-compilation-targets": "^7.27.2", - "@babel/helper-module-transforms": "^7.28.3", - "@babel/helpers": "^7.28.4", - "@babel/parser": "^7.28.5", - "@babel/template": "^7.27.2", - "@babel/traverse": "^7.28.5", - "@babel/types": "^7.28.5", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz", + "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-module-transforms": "^7.28.6", + "@babel/helpers": "^7.28.6", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/traverse": "^7.29.0", + "@babel/types": "^7.29.0", "@jridgewell/remapping": "^2.3.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", @@ -120,14 +200,14 @@ } }, "node_modules/@babel/generator": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.5.tgz", - "integrity": "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==", + "version": "7.29.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz", + "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/parser": "^7.28.5", - "@babel/types": "^7.28.5", + "@babel/parser": "^7.29.0", + "@babel/types": "^7.29.0", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" @@ -137,13 +217,13 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", - "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz", + "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.27.2", + "@babel/compat-data": "^7.28.6", "@babel/helper-validator-option": "^7.27.1", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", @@ -175,8 +255,6 @@ }, "node_modules/@babel/helper-globals": { "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", - "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", "dev": true, "license": "MIT", "engines": { @@ -184,29 +262,29 @@ } }, "node_modules/@babel/helper-module-imports": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", - "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz", + "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/traverse": "^7.27.1", - "@babel/types": "^7.27.1" + "@babel/traverse": "^7.28.6", + "@babel/types": "^7.28.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz", - "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz", + "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1", - "@babel/traverse": "^7.28.3" + "@babel/helper-module-imports": "^7.28.6", + "@babel/helper-validator-identifier": "^7.28.5", + "@babel/traverse": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -217,8 +295,6 @@ }, "node_modules/@babel/helper-string-parser": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", - "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", "dev": true, "license": "MIT", "engines": { @@ -246,27 +322,27 @@ } }, "node_modules/@babel/helpers": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz", - "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.6.tgz", + "integrity": "sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/template": "^7.27.2", - "@babel/types": "^7.28.4" + "@babel/template": "^7.28.6", + "@babel/types": "^7.28.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/parser": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz", - "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.0.tgz", + "integrity": "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.28.5" + "@babel/types": "^7.29.0" }, "bin": { "parser": "bin/babel-parser.js" @@ -277,8 +353,6 @@ }, "node_modules/@babel/runtime": { "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz", - "integrity": "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==", "dev": true, "license": "MIT", "engines": { @@ -286,33 +360,33 @@ } }, "node_modules/@babel/template": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", - "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", + "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/parser": "^7.27.2", - "@babel/types": "^7.27.1" + "@babel/code-frame": "^7.28.6", + "@babel/parser": "^7.28.6", + "@babel/types": "^7.28.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.5.tgz", - "integrity": "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz", + "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.28.5", + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", "@babel/helper-globals": "^7.28.0", - "@babel/parser": "^7.28.5", - "@babel/template": "^7.27.2", - "@babel/types": "^7.28.5", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0", "debug": "^4.3.1" }, "engines": { @@ -320,9 +394,9 @@ } }, "node_modules/@babel/types": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", - "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", "dev": true, "license": "MIT", "dependencies": { @@ -334,9 +408,9 @@ } }, "node_modules/@comapeo/core": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/@comapeo/core/-/core-5.2.1.tgz", - "integrity": "sha512-W+THNXlKjutzlmtNxQR203YVUd9roHlna4Z3n8E64qxleBaaMSFKPpRPMHPhlYgALCP6J61B9J3rqnJEFnZLtg==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@comapeo/core/-/core-5.4.0.tgz", + "integrity": "sha512-2pu/oDzpxGItvlYKwXpJHdHvltXNMZGHrL5n5v/i5ce3uMciAa9XPhCgJHOGUhjgldl+oB/xTGGw1p+/AbEAGg==", "dev": true, "license": "MIT", "dependencies": { @@ -362,7 +436,7 @@ "debug": "^4.3.4", "dot-prop": "^9.0.0", "dot-prop-extra": "^10.2.0", - "drizzle-orm": "^1.0.0-beta.1-ac4ce44", + "drizzle-orm": "1.0.0-beta.1-fd8bfcc", "ensure-error": "^4.0.0", "fastify": "^4.0.0", "fastify-plugin": "^4.5.1", @@ -402,17 +476,35 @@ "zip-stream-promise": "^1.0.2" } }, + "node_modules/@comapeo/core/node_modules/ensure-error": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@comapeo/core/node_modules/type-fest": { + "version": "4.41.0", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@comapeo/fallback-smp": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@comapeo/fallback-smp/-/fallback-smp-1.0.0.tgz", - "integrity": "sha512-6wLTtBOdlwtYMyrynBq6ZQ7S1aVABXQSwR/1QENkFkc7WyLLs4wLd9ny7WfSUQdHn6E2zfvA7WfKH7R06Zy3gQ==", "dev": true, "license": "MIT" }, "node_modules/@comapeo/geometry": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@comapeo/geometry/-/geometry-1.1.1.tgz", - "integrity": "sha512-MKnyzqhmpUUV5qCjUUDwUjuBx/ym9aizfOZ0h9+6SjQwCQa2kBRTN+Y9qDqteFSlJd0QMQRKpBmu+2OXJPypCQ==", "dev": true, "license": "MIT", "dependencies": { @@ -437,205 +529,736 @@ "@comapeo/core": "^5.0.0" } }, - "node_modules/@comapeo/schema": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@comapeo/schema/-/schema-2.2.0.tgz", - "integrity": "sha512-SbD/Q0BsirAFSj2LETqwgyx/Om62lUVT3R05k9vK5Ld+u+VNn1Xsg2nRblf6Xh9mP1U3rBYJvjjuYQ1lPUYmLA==", - "dev": true, + "node_modules/@comapeo/map-server": { + "version": "1.0.0-pre.7", + "resolved": "https://registry.npmjs.org/@comapeo/map-server/-/map-server-1.0.0-pre.7.tgz", + "integrity": "sha512-aLNbQ66es/m7OiQS8ou0R3pb7dW5J4pf7T2OK280nfjRp2Mvre1oqBfkk/Vj/I2U+oubiKinikGjAil3SDpbGA==", + "bundleDependencies": [ + "@whatwg-node/server" + ], "license": "MIT", "dependencies": { - "@comapeo/geometry": "^1.1.1", - "compact-encoding": "^2.12.0", - "protobufjs": "^7.2.5", - "type-fest": "^4.26.0" - } - }, - "node_modules/@digidem/types": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@digidem/types/-/types-2.3.0.tgz", - "integrity": "sha512-05dj9Z/xEmKQ5s9bl5doBHmmefgYoOQPn2BNu4eAbf6qgm6kylT1N94Ynr1zpdww+sB4sT9vjzAbc3BXtxQAKw==", - "dev": true, - "license": "ISC", - "dependencies": { - "@types/node": "^18.16.19", - "@types/streamx": "^2.9.1", - "tiny-typed-emitter": "^2.1.0" + "@whatwg-node/server": "^0.10.17", + "itty-router": "^5.0.22", + "p-defer": "^4.0.1", + "p-mutex": "^0.1.0", + "secret-stream-http": "^1.0.1", + "styled-map-package": "^4.1.0", + "typebox": "^1.0.61", + "typed-event-target": "^3.4.0" } }, - "node_modules/@digidem/types/node_modules/@types/node": { - "version": "18.19.127", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.127.tgz", - "integrity": "sha512-gSjxjrnKXML/yo0BO099uPixMqfpJU0TKYjpfLU7TrtA2WWDki412Np/RSTPRil1saKBhvVVKzVx/p/6p94nVA==", + "node_modules/@comapeo/map-server/node_modules/@envelop/instrumentation": { + "version": "1.0.0", "dev": true, + "inBundle": true, "license": "MIT", "dependencies": { - "undici-types": "~5.26.4" + "@whatwg-node/promise-helpers": "^1.2.1", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=18.0.0" } }, - "node_modules/@digidem/types/node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "node_modules/@comapeo/map-server/node_modules/@fastify/busboy": { + "version": "3.2.0", "dev": true, + "inBundle": true, "license": "MIT" }, - "node_modules/@emnapi/core": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.5.0.tgz", - "integrity": "sha512-sbP8GzB1WDzacS8fgNPpHlp6C9VZe+SJP3F90W9rLemaQj2PzIuTEl1qDOYQf58YIpyjViI24y9aPWCjEzY2cg==", + "node_modules/@comapeo/map-server/node_modules/@whatwg-node/disposablestack": { + "version": "0.0.6", "dev": true, + "inBundle": true, "license": "MIT", - "optional": true, "dependencies": { - "@emnapi/wasi-threads": "1.1.0", - "tslib": "^2.4.0" + "@whatwg-node/promise-helpers": "^1.0.0", + "tslib": "^2.6.3" + }, + "engines": { + "node": ">=18.0.0" } }, - "node_modules/@emnapi/runtime": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.5.0.tgz", - "integrity": "sha512-97/BJ3iXHww3djw6hYIfErCZFee7qCtrneuLa20UXFCOTCfBM2cvQHjWJ2EG0s0MtdNwInarqCTz35i4wWXHsQ==", + "node_modules/@comapeo/map-server/node_modules/@whatwg-node/fetch": { + "version": "0.10.13", "dev": true, + "inBundle": true, "license": "MIT", - "optional": true, "dependencies": { - "tslib": "^2.4.0" + "@whatwg-node/node-fetch": "^0.8.3", + "urlpattern-polyfill": "^10.0.0" + }, + "engines": { + "node": ">=18.0.0" } }, - "node_modules/@emnapi/wasi-threads": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.1.0.tgz", - "integrity": "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==", + "node_modules/@comapeo/map-server/node_modules/@whatwg-node/node-fetch": { + "version": "0.8.4", "dev": true, + "inBundle": true, "license": "MIT", - "optional": true, "dependencies": { - "tslib": "^2.4.0" + "@fastify/busboy": "^3.1.1", + "@whatwg-node/disposablestack": "^0.0.6", + "@whatwg-node/promise-helpers": "^1.3.2", + "tslib": "^2.6.3" + }, + "engines": { + "node": ">=18.0.0" } }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", - "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", - "cpu": [ - "ppc64" - ], + "node_modules/@comapeo/map-server/node_modules/@whatwg-node/promise-helpers": { + "version": "1.3.2", "dev": true, + "inBundle": true, "license": "MIT", - "optional": true, - "os": [ - "aix" - ], + "dependencies": { + "tslib": "^2.6.3" + }, "engines": { - "node": ">=18" + "node": ">=16.0.0" } }, - "node_modules/@esbuild/android-arm": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", - "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", - "cpu": [ - "arm" - ], + "node_modules/@comapeo/map-server/node_modules/@whatwg-node/server": { + "version": "0.10.17", "dev": true, + "inBundle": true, "license": "MIT", - "optional": true, - "os": [ - "android" - ], + "dependencies": { + "@envelop/instrumentation": "^1.0.0", + "@whatwg-node/disposablestack": "^0.0.6", + "@whatwg-node/fetch": "^0.10.13", + "@whatwg-node/promise-helpers": "^1.3.2", + "tslib": "^2.6.3" + }, "engines": { - "node": ">=18" + "node": ">=18.0.0" } }, - "node_modules/@esbuild/android-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", - "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", - "cpu": [ - "arm64" - ], - "dev": true, + "node_modules/@comapeo/map-server/node_modules/chalk": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", "license": "MIT", - "optional": true, - "os": [ - "android" - ], "engines": { - "node": ">=18" + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/@esbuild/android-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", - "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", - "cpu": [ - "x64" - ], - "dev": true, + "node_modules/@comapeo/map-server/node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", "license": "MIT", - "optional": true, - "os": [ - "android" - ], "engines": { "node": ">=18" } }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", - "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", - "cpu": [ - "arm64" - ], - "dev": true, + "node_modules/@comapeo/map-server/node_modules/p-limit": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-6.2.0.tgz", + "integrity": "sha512-kuUqqHNUqoIWp/c467RI4X6mmyuojY5jGutNU0wVTmEOOfcuwLqyMVoAi9MKi2Ak+5i9+nhmrK4ufZE8069kHA==", "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], + "dependencies": { + "yocto-queue": "^1.1.1" + }, "engines": { "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", - "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", - "cpu": [ - "x64" + "node_modules/@comapeo/map-server/node_modules/styled-map-package": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/styled-map-package/-/styled-map-package-4.1.0.tgz", + "integrity": "sha512-CJCYKb1RRgi64P2zZT4gsmAo2Tu6/eoxA4zJ/cmLMf9T7amjyGnWomRdPA22p0nrTvYwmPJlDkKw1tAPd3AOfw==", + "bundleDependencies": [ + "yauzl-promise" ], - "dev": true, "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" + "dependencies": { + "@inquirer/prompts": "^6.0.1", + "@mapbox/sphericalmercator": "^1.2.0", + "@maplibre/maplibre-gl-style-spec": "^20.3.1", + "@placemarkio/check-geojson": "^0.1.12", + "@turf/bbox": "^7.2.0", + "@turf/helpers": "^7.2.0", + "@whatwg-node/server": "^0.10.17", + "ansi-diff": "^1.2.0", + "archiver": "^7.0.1", + "buffer-peek-stream": "^1.1.0", + "chalk": "^5.4.1", + "commander": "^12.1.0", + "filter-obj": "^6.1.0", + "into-stream": "^8.0.1", + "is-stream": "^4.0.1", + "itty-router": "^5.0.22", + "ky": "^1.7.5", + "log-symbols": "^7.0.0", + "map-obj": "^5.0.2", + "mbtiles-reader": "^1.0.0", + "open": "^10.1.0", + "ora": "^8.2.0", + "p-event": "^6.0.1", + "p-limit": "^6.2.0", + "pretty-bytes": "^6.1.1", + "pretty-ms": "^9.2.0", + "readable-stream": "^4.7.0", + "temp-dir": "^3.0.0", + "yauzl-promise": "^4.0.0", + "yocto-queue": "^1.1.1" + }, + "bin": { + "smp": "bin/smp.js", + "styled-map-package": "bin/smp.js" } }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", - "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", - "cpu": [ - "arm64" - ], + "node_modules/@comapeo/map-server/node_modules/styled-map-package/node_modules/@node-rs/crc32": { + "version": "1.10.6", "dev": true, + "inBundle": true, "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], "engines": { - "node": ">=18" + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "optionalDependencies": { + "@node-rs/crc32-android-arm-eabi": "1.10.6", + "@node-rs/crc32-android-arm64": "1.10.6", + "@node-rs/crc32-darwin-arm64": "1.10.6", + "@node-rs/crc32-darwin-x64": "1.10.6", + "@node-rs/crc32-freebsd-x64": "1.10.6", + "@node-rs/crc32-linux-arm-gnueabihf": "1.10.6", + "@node-rs/crc32-linux-arm64-gnu": "1.10.6", + "@node-rs/crc32-linux-arm64-musl": "1.10.6", + "@node-rs/crc32-linux-x64-gnu": "1.10.6", + "@node-rs/crc32-linux-x64-musl": "1.10.6", + "@node-rs/crc32-wasm32-wasi": "1.10.6", + "@node-rs/crc32-win32-arm64-msvc": "1.10.6", + "@node-rs/crc32-win32-ia32-msvc": "1.10.6", + "@node-rs/crc32-win32-x64-msvc": "1.10.6" + } + }, + "node_modules/@comapeo/map-server/node_modules/styled-map-package/node_modules/@node-rs/crc32-linux-x64-gnu": { + "version": "1.10.6", + "cpu": [ + "x64" + ], + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@comapeo/map-server/node_modules/styled-map-package/node_modules/@node-rs/crc32-linux-x64-musl": { + "version": "1.10.6", + "cpu": [ + "x64" + ], + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@comapeo/map-server/node_modules/styled-map-package/node_modules/define-data-property": { + "version": "1.1.4", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@comapeo/map-server/node_modules/styled-map-package/node_modules/define-properties": { + "version": "1.2.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@comapeo/map-server/node_modules/styled-map-package/node_modules/es-define-property": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/@comapeo/map-server/node_modules/styled-map-package/node_modules/es-errors": { + "version": "1.3.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/@comapeo/map-server/node_modules/styled-map-package/node_modules/globalthis": { + "version": "1.0.4", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@comapeo/map-server/node_modules/styled-map-package/node_modules/gopd": { + "version": "1.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@comapeo/map-server/node_modules/styled-map-package/node_modules/has-property-descriptors": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@comapeo/map-server/node_modules/styled-map-package/node_modules/is-it-type": { + "version": "5.1.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "globalthis": "^1.0.2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@comapeo/map-server/node_modules/styled-map-package/node_modules/object-keys": { + "version": "1.1.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/@comapeo/map-server/node_modules/styled-map-package/node_modules/simple-invariant": { + "version": "2.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/@comapeo/map-server/node_modules/styled-map-package/node_modules/yauzl-promise": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "@node-rs/crc32": "^1.7.0", + "is-it-type": "^5.1.2", + "simple-invariant": "^2.0.1" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@comapeo/map-server/node_modules/tslib": { + "version": "2.8.1", + "dev": true, + "inBundle": true, + "license": "0BSD" + }, + "node_modules/@comapeo/map-server/node_modules/urlpattern-polyfill": { + "version": "10.1.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/@comapeo/map-server/node_modules/yocto-queue": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.2.tgz", + "integrity": "sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==", + "license": "MIT", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@comapeo/schema": { + "version": "2.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@comapeo/geometry": "^1.1.1", + "compact-encoding": "^2.12.0", + "protobufjs": "^7.2.5", + "type-fest": "^4.26.0" + } + }, + "node_modules/@comapeo/schema/node_modules/type-fest": { + "version": "4.41.0", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@csstools/color-helpers": { + "version": "6.0.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=20.19.0" + } + }, + "node_modules/@csstools/css-calc": { + "version": "3.0.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=20.19.0" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0" + } + }, + "node_modules/@csstools/css-color-parser": { + "version": "4.0.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/color-helpers": "^6.0.1", + "@csstools/css-calc": "^3.0.0" + }, + "engines": { + "node": ">=20.19.0" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0" + } + }, + "node_modules/@csstools/css-parser-algorithms": { + "version": "4.0.0", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "peer": true, + "engines": { + "node": ">=20.19.0" + }, + "peerDependencies": { + "@csstools/css-tokenizer": "^4.0.0" + } + }, + "node_modules/@csstools/css-syntax-patches-for-csstree": { + "version": "1.0.27", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0" + }, + "node_modules/@csstools/css-tokenizer": { + "version": "4.0.0", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "peer": true, + "engines": { + "node": ">=20.19.0" + } + }, + "node_modules/@digidem/types": { + "version": "2.3.0", + "dev": true, + "license": "ISC", + "dependencies": { + "@types/node": "^18.16.19", + "@types/streamx": "^2.9.1", + "tiny-typed-emitter": "^2.1.0" + } + }, + "node_modules/@digidem/types/node_modules/@types/node": { + "version": "18.19.127", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@digidem/types/node_modules/undici-types": { + "version": "5.26.5", + "dev": true, + "license": "MIT" + }, + "node_modules/@emnapi/core": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.8.1.tgz", + "integrity": "sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg==", + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.1.0", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.8.1.tgz", + "integrity": "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.1.0.tgz", + "integrity": "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.3.tgz", + "integrity": "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.3.tgz", + "integrity": "sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.3.tgz", + "integrity": "sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.3.tgz", + "integrity": "sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.3.tgz", + "integrity": "sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.3.tgz", + "integrity": "sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.3.tgz", + "integrity": "sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", - "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.3.tgz", + "integrity": "sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==", "cpu": [ "x64" ], @@ -650,9 +1273,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", - "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.3.tgz", + "integrity": "sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==", "cpu": [ "arm" ], @@ -667,9 +1290,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", - "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.3.tgz", + "integrity": "sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==", "cpu": [ "arm64" ], @@ -684,9 +1307,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", - "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.3.tgz", + "integrity": "sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==", "cpu": [ "ia32" ], @@ -701,9 +1324,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", - "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.3.tgz", + "integrity": "sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==", "cpu": [ "loong64" ], @@ -718,9 +1341,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", - "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.3.tgz", + "integrity": "sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==", "cpu": [ "mips64el" ], @@ -735,9 +1358,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", - "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.3.tgz", + "integrity": "sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==", "cpu": [ "ppc64" ], @@ -752,9 +1375,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", - "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.3.tgz", + "integrity": "sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==", "cpu": [ "riscv64" ], @@ -769,9 +1392,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", - "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.3.tgz", + "integrity": "sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==", "cpu": [ "s390x" ], @@ -786,9 +1409,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", - "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.3.tgz", + "integrity": "sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==", "cpu": [ "x64" ], @@ -803,9 +1426,9 @@ } }, "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", - "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.3.tgz", + "integrity": "sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==", "cpu": [ "arm64" ], @@ -820,9 +1443,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", - "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.3.tgz", + "integrity": "sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==", "cpu": [ "x64" ], @@ -837,9 +1460,9 @@ } }, "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", - "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.3.tgz", + "integrity": "sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==", "cpu": [ "arm64" ], @@ -854,9 +1477,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", - "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.3.tgz", + "integrity": "sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==", "cpu": [ "x64" ], @@ -871,9 +1494,9 @@ } }, "node_modules/@esbuild/openharmony-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", - "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.3.tgz", + "integrity": "sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==", "cpu": [ "arm64" ], @@ -888,9 +1511,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", - "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.3.tgz", + "integrity": "sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==", "cpu": [ "x64" ], @@ -905,9 +1528,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", - "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.3.tgz", + "integrity": "sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==", "cpu": [ "arm64" ], @@ -922,9 +1545,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", - "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.3.tgz", + "integrity": "sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==", "cpu": [ "ia32" ], @@ -939,9 +1562,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", - "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.3.tgz", + "integrity": "sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==", "cpu": [ "x64" ], @@ -956,9 +1579,9 @@ } }, "node_modules/@eslint-community/eslint-utils": { - "version": "4.9.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz", - "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==", + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", "dev": true, "license": "MIT", "dependencies": { @@ -976,8 +1599,6 @@ }, "node_modules/@eslint-community/regexpp": { "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", - "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", "dev": true, "license": "MIT", "engines": { @@ -1071,9 +1692,9 @@ } }, "node_modules/@eslint/core": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-1.0.0.tgz", - "integrity": "sha512-PRfWP+8FOldvbApr6xL7mNCw4cJcSTq4GA7tYbgq15mRb0kWKO/wEB2jr+uwjFH3sZvEZneZyCUGTxsv4Sahyw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-1.1.0.tgz", + "integrity": "sha512-/nr9K9wkr3P1EzFTdFdMoLuo1PmIxjmwvPozwoSodjNBdefGujXQUF93u1DDZpEaTuDvMsIQddsd35BwtrW9Xw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -1085,8 +1706,6 @@ }, "node_modules/@eslint/eslintrc": { "version": "3.3.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", - "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", "dev": true, "license": "MIT", "dependencies": { @@ -1109,8 +1728,6 @@ }, "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, "license": "MIT", "dependencies": { @@ -1120,8 +1737,6 @@ }, "node_modules/@eslint/eslintrc/node_modules/globals": { "version": "14.0.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", - "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", "dev": true, "license": "MIT", "engines": { @@ -1133,8 +1748,6 @@ }, "node_modules/@eslint/eslintrc/node_modules/minimatch": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "license": "ISC", "dependencies": { @@ -1194,10 +1807,24 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, + "node_modules/@exodus/bytes": { + "version": "1.13.0", + "dev": true, + "license": "MIT", + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "@noble/hashes": "^1.8.0 || ^2.0.0" + }, + "peerDependenciesMeta": { + "@noble/hashes": { + "optional": true + } + } + }, "node_modules/@faker-js/faker": { "version": "9.9.0", - "resolved": "https://registry.npmjs.org/@faker-js/faker/-/faker-9.9.0.tgz", - "integrity": "sha512-OEl393iCOoo/z8bMezRlJu+GlRGlsKbUAN7jKB6LhnKoqKve5DXRpalbItIIcwnCjs1k/FOPjFzcA6Qn+H+YbA==", "dev": true, "funding": [ { @@ -1213,8 +1840,6 @@ }, "node_modules/@fastify/accept-negotiator": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@fastify/accept-negotiator/-/accept-negotiator-1.1.0.tgz", - "integrity": "sha512-OIHZrb2ImZ7XG85HXOONLcJWGosv7sIvM2ifAPQVhg9Lv7qdmMBNVaai4QTdyuaqbKM5eO6sLSQOYI7wEQeCJQ==", "dev": true, "license": "MIT", "engines": { @@ -1223,8 +1848,6 @@ }, "node_modules/@fastify/ajv-compiler": { "version": "3.6.0", - "resolved": "https://registry.npmjs.org/@fastify/ajv-compiler/-/ajv-compiler-3.6.0.tgz", - "integrity": "sha512-LwdXQJjmMD+GwLOkP7TVC68qa+pSSogeWWmznRJ/coyTcfe9qA05AHFSe1eZFwK6q+xVRpChnvFUkf1iYaSZsQ==", "dev": true, "license": "MIT", "dependencies": { @@ -1235,8 +1858,6 @@ }, "node_modules/@fastify/ajv-compiler/node_modules/ajv": { "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, "license": "MIT", "dependencies": { @@ -1252,8 +1873,6 @@ }, "node_modules/@fastify/ajv-compiler/node_modules/ajv/node_modules/fast-uri": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", - "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", "dev": true, "funding": [ { @@ -1269,22 +1888,16 @@ }, "node_modules/@fastify/ajv-compiler/node_modules/json-schema-traverse": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true, "license": "MIT" }, "node_modules/@fastify/error": { "version": "3.4.1", - "resolved": "https://registry.npmjs.org/@fastify/error/-/error-3.4.1.tgz", - "integrity": "sha512-wWSvph+29GR783IhmvdwWnN4bUxTD01Vm5Xad4i7i1VuAOItLvbPAb69sb0IQ2N57yprvhNIwAP5B6xfKTmjmQ==", "dev": true, "license": "MIT" }, "node_modules/@fastify/fast-json-stringify-compiler": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@fastify/fast-json-stringify-compiler/-/fast-json-stringify-compiler-4.3.0.tgz", - "integrity": "sha512-aZAXGYo6m22Fk1zZzEUKBvut/CIIQe/BapEORnxiD5Qr0kPHqqI69NtEMCme74h+at72sPhbkb4ZrLd1W3KRLA==", "dev": true, "license": "MIT", "dependencies": { @@ -1293,8 +1906,6 @@ }, "node_modules/@fastify/merge-json-schemas": { "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@fastify/merge-json-schemas/-/merge-json-schemas-0.1.1.tgz", - "integrity": "sha512-fERDVz7topgNjtXsJTTW1JKLy0rhuLRcquYqNR9rF7OcVpCa2OVW49ZPDIhaRRCaUuvVxI+N416xUoF76HNSXA==", "dev": true, "license": "MIT", "dependencies": { @@ -1303,8 +1914,6 @@ }, "node_modules/@fastify/send": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@fastify/send/-/send-2.1.0.tgz", - "integrity": "sha512-yNYiY6sDkexoJR0D8IDy3aRP3+L4wdqCpvx5WP+VtEU58sn7USmKynBzDQex5X42Zzvw2gNzzYgP90UfWShLFA==", "dev": true, "license": "MIT", "dependencies": { @@ -1317,8 +1926,6 @@ }, "node_modules/@fastify/send/node_modules/mime": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", - "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", "dev": true, "license": "MIT", "bin": { @@ -1330,8 +1937,6 @@ }, "node_modules/@fastify/static": { "version": "7.0.4", - "resolved": "https://registry.npmjs.org/@fastify/static/-/static-7.0.4.tgz", - "integrity": "sha512-p2uKtaf8BMOZWLs6wu+Ihg7bWNBdjNgCwDza4MJtTqg+5ovKmcbgbR9Xs5/smZ1YISfzKOCNYmZV8LaCj+eJ1Q==", "dev": true, "license": "MIT", "dependencies": { @@ -1345,8 +1950,6 @@ }, "node_modules/@fastify/type-provider-typebox": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@fastify/type-provider-typebox/-/type-provider-typebox-4.1.0.tgz", - "integrity": "sha512-mXNBaBEoS6Yf4/O2ujNhu9yEZwvBC7niqRESsiftE9NP1hV6ZdV3ZsFbPf1S520BK3rTZ0F28zr+sMdIXNJlfw==", "dev": true, "license": "MIT", "peerDependencies": { @@ -1355,8 +1958,6 @@ }, "node_modules/@humanfs/core": { "version": "0.19.1", - "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", - "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -1365,8 +1966,6 @@ }, "node_modules/@humanfs/node": { "version": "0.16.7", - "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", - "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -1379,8 +1978,6 @@ }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -1393,8 +1990,6 @@ }, "node_modules/@humanwhocodes/retry": { "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", - "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", "dev": true, "license": "Apache-2.0", "engines": { @@ -1407,9 +2002,6 @@ }, "node_modules/@hyperswarm/secret-stream": { "version": "6.8.1", - "resolved": "https://registry.npmjs.org/@hyperswarm/secret-stream/-/secret-stream-6.8.1.tgz", - "integrity": "sha512-F3fr8CKB6za9Ac7ifjgAe07qnnesl5kS0MtLsyKxA1Og8E+FZykdwLpgoLjnEa7G6E1L56lASLr42E4kd20sog==", - "dev": true, "license": "Apache-2.0", "dependencies": { "b4a": "^1.1.0", @@ -1425,9 +2017,6 @@ }, "node_modules/@hyperswarm/secret-stream/node_modules/sodium-native": { "version": "5.0.8", - "resolved": "https://registry.npmjs.org/sodium-native/-/sodium-native-5.0.8.tgz", - "integrity": "sha512-2ZxmF9Llvo/3X3NAc8VV6JFoswObg9u27Q8Be4BtCLDiejXuTt6Nm7+iIWUv+WMcs1eJ7YV5U2f4e8LidfIlRQ==", - "dev": true, "license": "MIT", "dependencies": { "require-addon": "^1.1.0", @@ -1439,9 +2028,6 @@ }, "node_modules/@hyperswarm/secret-stream/node_modules/sodium-universal": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/sodium-universal/-/sodium-universal-5.0.1.tgz", - "integrity": "sha512-rv+aH+tnKB5H0MAc2UadHShLMslpJsc4wjdnHRtiSIEYpOetCgu8MS4ExQRia+GL/MK3uuCyZPeEsi+J3h+Q+Q==", - "dev": true, "license": "MIT", "dependencies": { "sodium-native": "^5.0.1" @@ -1457,8 +2043,6 @@ }, "node_modules/@ianvs/prettier-plugin-sort-imports": { "version": "4.7.0", - "resolved": "https://registry.npmjs.org/@ianvs/prettier-plugin-sort-imports/-/prettier-plugin-sort-imports-4.7.0.tgz", - "integrity": "sha512-soa2bPUJAFruLL4z/CnMfSEKGznm5ebz29fIa9PxYtu8HHyLKNE1NXAs6dylfw1jn/ilEIfO2oLLN6uAafb7DA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -1492,9 +2076,6 @@ }, "node_modules/@inquirer/checkbox": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-3.0.1.tgz", - "integrity": "sha512-0hm2nrToWUdD6/UHnel/UKGdk1//ke5zGUpHIvk5ZWmaKezlGxZkOJXNSWsdxO/rEqTkbB3lNC2J6nBElV2aAQ==", - "dev": true, "license": "MIT", "dependencies": { "@inquirer/core": "^9.2.1", @@ -1509,9 +2090,6 @@ }, "node_modules/@inquirer/checkbox/node_modules/ansi-escapes": { "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, "license": "MIT", "dependencies": { "type-fest": "^0.21.3" @@ -1525,9 +2103,6 @@ }, "node_modules/@inquirer/checkbox/node_modules/type-fest": { "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true, "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" @@ -1538,9 +2113,6 @@ }, "node_modules/@inquirer/confirm": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-4.0.1.tgz", - "integrity": "sha512-46yL28o2NJ9doViqOy0VDcoTzng7rAb6yPQKU7VDLqkmbCaH4JqK4yk4XqlzNWy9PVC5pG1ZUXPBQv+VqnYs2w==", - "dev": true, "license": "MIT", "dependencies": { "@inquirer/core": "^9.2.1", @@ -1552,9 +2124,6 @@ }, "node_modules/@inquirer/core": { "version": "9.2.1", - "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-9.2.1.tgz", - "integrity": "sha512-F2VBt7W/mwqEU4bL0RnHNZmC/OxzNx9cOYxHqnXX3MP6ruYvZUZAW9imgN9+h/uBT/oP8Gh888J2OZSbjSeWcg==", - "dev": true, "license": "MIT", "dependencies": { "@inquirer/figures": "^1.0.6", @@ -1576,9 +2145,6 @@ }, "node_modules/@inquirer/core/node_modules/ansi-escapes": { "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, "license": "MIT", "dependencies": { "type-fest": "^0.21.3" @@ -1592,16 +2158,10 @@ }, "node_modules/@inquirer/core/node_modules/emoji-regex": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, "license": "MIT" }, "node_modules/@inquirer/core/node_modules/is-fullwidth-code-point": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -1609,9 +2169,6 @@ }, "node_modules/@inquirer/core/node_modules/string-width": { "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", @@ -1624,9 +2181,6 @@ }, "node_modules/@inquirer/core/node_modules/strip-ansi": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" @@ -1637,9 +2191,6 @@ }, "node_modules/@inquirer/core/node_modules/type-fest": { "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true, "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" @@ -1650,9 +2201,6 @@ }, "node_modules/@inquirer/core/node_modules/wrap-ansi": { "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", @@ -1665,9 +2213,6 @@ }, "node_modules/@inquirer/editor": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-3.0.1.tgz", - "integrity": "sha512-VA96GPFaSOVudjKFraokEEmUQg/Lub6OXvbIEZU1SDCmBzRkHGhxoFAVaF30nyiB4m5cEbDgiI2QRacXZ2hw9Q==", - "dev": true, "license": "MIT", "dependencies": { "@inquirer/core": "^9.2.1", @@ -1680,9 +2225,6 @@ }, "node_modules/@inquirer/expand": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-3.0.1.tgz", - "integrity": "sha512-ToG8d6RIbnVpbdPdiN7BCxZGiHOTomOX94C2FaT5KOHupV40tKEDozp12res6cMIfRKrXLJyexAZhWVHgbALSQ==", - "dev": true, "license": "MIT", "dependencies": { "@inquirer/core": "^9.2.1", @@ -1695,9 +2237,6 @@ }, "node_modules/@inquirer/figures": { "version": "1.0.13", - "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.13.tgz", - "integrity": "sha512-lGPVU3yO9ZNqA7vTYz26jny41lE7yoQansmqdMLBEfqaGsmdg7V3W9mK9Pvb5IL4EVZ9GnSDGMO/cJXud5dMaw==", - "dev": true, "license": "MIT", "engines": { "node": ">=18" @@ -1705,9 +2244,6 @@ }, "node_modules/@inquirer/input": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-3.0.1.tgz", - "integrity": "sha512-BDuPBmpvi8eMCxqC5iacloWqv+5tQSJlUafYWUe31ow1BVXjW2a5qe3dh4X/Z25Wp22RwvcaLCc2siHobEOfzg==", - "dev": true, "license": "MIT", "dependencies": { "@inquirer/core": "^9.2.1", @@ -1719,9 +2255,6 @@ }, "node_modules/@inquirer/number": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-2.0.1.tgz", - "integrity": "sha512-QpR8jPhRjSmlr/mD2cw3IR8HRO7lSVOnqUvQa8scv1Lsr3xoAMMworcYW3J13z3ppjBFBD2ef1Ci6AE5Qn8goQ==", - "dev": true, "license": "MIT", "dependencies": { "@inquirer/core": "^9.2.1", @@ -1733,9 +2266,6 @@ }, "node_modules/@inquirer/password": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-3.0.1.tgz", - "integrity": "sha512-haoeEPUisD1NeE2IanLOiFr4wcTXGWrBOyAyPZi1FfLJuXOzNmxCJPgUrGYKVh+Y8hfGJenIfz5Wb/DkE9KkMQ==", - "dev": true, "license": "MIT", "dependencies": { "@inquirer/core": "^9.2.1", @@ -1748,9 +2278,6 @@ }, "node_modules/@inquirer/password/node_modules/ansi-escapes": { "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, "license": "MIT", "dependencies": { "type-fest": "^0.21.3" @@ -1764,9 +2291,6 @@ }, "node_modules/@inquirer/password/node_modules/type-fest": { "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true, "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" @@ -1777,9 +2301,6 @@ }, "node_modules/@inquirer/prompts": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-6.0.1.tgz", - "integrity": "sha512-yl43JD/86CIj3Mz5mvvLJqAOfIup7ncxfJ0Btnl0/v5TouVUyeEdcpknfgc+yMevS/48oH9WAkkw93m7otLb/A==", - "dev": true, "license": "MIT", "dependencies": { "@inquirer/checkbox": "^3.0.1", @@ -1799,9 +2320,6 @@ }, "node_modules/@inquirer/rawlist": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-3.0.1.tgz", - "integrity": "sha512-VgRtFIwZInUzTiPLSfDXK5jLrnpkuSOh1ctfaoygKAdPqjcjKYmGh6sCY1pb0aGnCGsmhUxoqLDUAU0ud+lGXQ==", - "dev": true, "license": "MIT", "dependencies": { "@inquirer/core": "^9.2.1", @@ -1814,9 +2332,6 @@ }, "node_modules/@inquirer/search": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-2.0.1.tgz", - "integrity": "sha512-r5hBKZk3g5MkIzLVoSgE4evypGqtOannnB3PKTG9NRZxyFRKcfzrdxXXPcoJQsxJPzvdSU2Rn7pB7lw0GCmGAg==", - "dev": true, "license": "MIT", "dependencies": { "@inquirer/core": "^9.2.1", @@ -1830,9 +2345,6 @@ }, "node_modules/@inquirer/select": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-3.0.1.tgz", - "integrity": "sha512-lUDGUxPhdWMkN/fHy1Lk7pF3nK1fh/gqeyWXmctefhxLYxlDsc7vsPBEpxrfVGDsVdyYJsiJoD4bJ1b623cV1Q==", - "dev": true, "license": "MIT", "dependencies": { "@inquirer/core": "^9.2.1", @@ -1847,9 +2359,6 @@ }, "node_modules/@inquirer/select/node_modules/ansi-escapes": { "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, "license": "MIT", "dependencies": { "type-fest": "^0.21.3" @@ -1863,9 +2372,6 @@ }, "node_modules/@inquirer/select/node_modules/type-fest": { "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true, "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" @@ -1876,9 +2382,6 @@ }, "node_modules/@inquirer/type": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-2.0.0.tgz", - "integrity": "sha512-XvJRx+2KR3YXyYtPUUy+qd9i7p+GO9Ko6VIIpWlBrpWwXDv8WLFeHTxz35CfQFUiBMLXlGHhGzys7lqit9gWag==", - "dev": true, "license": "MIT", "dependencies": { "mute-stream": "^1.0.0" @@ -1889,8 +2392,6 @@ }, "node_modules/@isaacs/balanced-match": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", - "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==", "dev": true, "license": "MIT", "engines": { @@ -1899,8 +2400,6 @@ }, "node_modules/@isaacs/brace-expansion": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz", - "integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==", "dev": true, "license": "MIT", "dependencies": { @@ -1912,9 +2411,6 @@ }, "node_modules/@isaacs/cliui": { "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dev": true, "license": "ISC", "dependencies": { "string-width": "^5.1.2", @@ -1930,9 +2426,6 @@ }, "node_modules/@isaacs/cliui/node_modules/ansi-styles": { "version": "6.2.3", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", - "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", - "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -1943,16 +2436,10 @@ }, "node_modules/@isaacs/cliui/node_modules/emoji-regex": { "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true, "license": "MIT" }, "node_modules/@isaacs/cliui/node_modules/string-width": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, "license": "MIT", "dependencies": { "eastasianwidth": "^0.2.0", @@ -1968,9 +2455,6 @@ }, "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^6.1.0", @@ -1986,8 +2470,6 @@ }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.13", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", - "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", "dev": true, "license": "MIT", "dependencies": { @@ -2008,25 +2490,31 @@ }, "node_modules/@jridgewell/resolve-uri": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "dev": true, "license": "MIT", "engines": { "node": ">=6.0.0" } }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", + "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", - "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", "dev": true, "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.31", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", - "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", "dev": true, "license": "MIT", "dependencies": { @@ -2036,8 +2524,6 @@ }, "node_modules/@jsep-plugin/assignment": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@jsep-plugin/assignment/-/assignment-1.3.0.tgz", - "integrity": "sha512-VVgV+CXrhbMI3aSusQyclHkenWSAm95WaiKrMxRFam3JSUiIaQjoMIw2sEs/OX4XifnqeQUN4DYbJjlA8EfktQ==", "dev": true, "license": "MIT", "engines": { @@ -2049,8 +2535,6 @@ }, "node_modules/@jsep-plugin/regex": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@jsep-plugin/regex/-/regex-1.0.4.tgz", - "integrity": "sha512-q7qL4Mgjs1vByCaTnDFcBnV9HS7GVPJX5vyVoCgZHNSC9rjwIlmbXG5sUuorR5ndfHAIlJ8pVStxvjXHbNvtUg==", "dev": true, "license": "MIT", "engines": { @@ -2062,8 +2546,6 @@ }, "node_modules/@lukeed/ms": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@lukeed/ms/-/ms-2.0.2.tgz", - "integrity": "sha512-9I2Zn6+NJLfaGoz9jN3lpwDgAYvfGeNYdbAIjJOqzs4Tpc+VU3Jqq4IofSUBKajiDS8k9fZIg18/z13mpk1bsA==", "dev": true, "license": "MIT", "engines": { @@ -2072,18 +2554,12 @@ }, "node_modules/@mapbox/jsonlint-lines-primitives": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@mapbox/jsonlint-lines-primitives/-/jsonlint-lines-primitives-2.0.2.tgz", - "integrity": "sha512-rY0o9A5ECsTQRVhv7tL/OyDpGAoUB4tTvLiW1DSzQGq4bvTPhNw1VpSNjDJc5GFZ2XuyOtSWSVN05qOtcD71qQ==", - "dev": true, "engines": { "node": ">= 0.6" } }, "node_modules/@mapbox/sphericalmercator": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@mapbox/sphericalmercator/-/sphericalmercator-1.2.0.tgz", - "integrity": "sha512-ZTOuuwGuMOJN+HEmG/68bSEw15HHaMWmQ5gdTsWdWsjDe56K1kGvLOK6bOSC8gWgIvEO0w6un/2Gvv1q5hJSkQ==", - "dev": true, "bin": { "bbox": "bin/bbox.js", "to4326": "bin/to4326.js", @@ -2093,24 +2569,16 @@ }, "node_modules/@mapbox/tiletype": { "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@mapbox/tiletype/-/tiletype-0.3.1.tgz", - "integrity": "sha512-jIMABS+S9wpqmCulD1whea3YJXaLEPJq7f7Dae3TrB4cFImNXsTEvKt91DOdcJWpgsV1mVxorxUiqvcVVWKxTg==", - "dev": true, "bin": { "tiletype": "bin/tiletype.js" } }, "node_modules/@mapbox/unitbezier": { "version": "0.0.1", - "resolved": "https://registry.npmjs.org/@mapbox/unitbezier/-/unitbezier-0.0.1.tgz", - "integrity": "sha512-nMkuDXFv60aBr9soUG5q+GvZYL+2KZHVvsqFCzqnkGEf46U2fvmytHaEVc1/YZbiLn8X+eR3QzX1+dwDO1lxlw==", - "dev": true, "license": "BSD-2-Clause" }, "node_modules/@mapeo/crypto": { "version": "1.0.0-alpha.10", - "resolved": "https://registry.npmjs.org/@mapeo/crypto/-/crypto-1.0.0-alpha.10.tgz", - "integrity": "sha512-TEK8HN1W0XZOOADIMxa4saXtqAZKyBDeVVn3RBCcPaCiOGHeYy43/0rMnBVTbXZCLsLVPnOXwv6vg+vUkasrWQ==", "dev": true, "license": "ISC", "dependencies": { @@ -2129,15 +2597,11 @@ }, "node_modules/@mapeo/default-config": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@mapeo/default-config/-/default-config-6.0.0.tgz", - "integrity": "sha512-nAnTbcKQRntsExuQAsAHal+EOd2OkDWrsl0ewcic/yVo+WpJ25ZTryKSPMVyFyHLihElX1cUH2r8C3YkZMoClA==", "dev": true, "license": "CC-BY-NC-4.0" }, "node_modules/@mapeo/mock-data": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@mapeo/mock-data/-/mock-data-5.0.0.tgz", - "integrity": "sha512-N8+T+SOD8GlLIYmP26ntjtCDmbaXr/XB4PwywrVVD+kva3emnUWaFdA8PPSGp0hKzSkR2cN1jakItHdKRrNYww==", "dev": true, "license": "MIT", "dependencies": { @@ -2155,8 +2619,6 @@ }, "node_modules/@mapeo/sqlite-indexer": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@mapeo/sqlite-indexer/-/sqlite-indexer-1.0.2.tgz", - "integrity": "sha512-PvQx1SfatNT+PNECtQ3MOOTVVQfZpbFlOT3JOHJDw2I3yQarncFAsYq2d9ahD1RBzTAutiPOTsHHqYW3Y1EdKQ==", "dev": true, "license": "MIT", "engines": { @@ -2169,9 +2631,6 @@ }, "node_modules/@maplibre/maplibre-gl-style-spec": { "version": "20.4.0", - "resolved": "https://registry.npmjs.org/@maplibre/maplibre-gl-style-spec/-/maplibre-gl-style-spec-20.4.0.tgz", - "integrity": "sha512-AzBy3095fTFPjDjmWpR2w6HVRAZJ6hQZUCwk5Plz6EyfnfuQW1odeW5i2Ai47Y6TBA2hQnC+azscjBSALpaWgw==", - "dev": true, "license": "ISC", "dependencies": { "@mapbox/jsonlint-lines-primitives": "~2.0.2", @@ -2192,7 +2651,6 @@ "version": "0.2.12", "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz", "integrity": "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==", - "dev": true, "license": "MIT", "optional": true, "dependencies": { @@ -2203,8 +2661,6 @@ }, "node_modules/@node-rs/crc32": { "version": "1.10.6", - "resolved": "https://registry.npmjs.org/@node-rs/crc32/-/crc32-1.10.6.tgz", - "integrity": "sha512-+llXfqt+UzgoDzT9of5vPQPGqTAVCohU74I9zIBkNo5TH6s2P31DFJOGsJQKN207f0GHnYv5pV3wh3BCY/un/A==", "dev": true, "license": "MIT", "engines": { @@ -2238,7 +2694,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -2255,7 +2710,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -2267,12 +2721,9 @@ }, "node_modules/@node-rs/crc32-darwin-arm64": { "version": "1.10.6", - "resolved": "https://registry.npmjs.org/@node-rs/crc32-darwin-arm64/-/crc32-darwin-arm64-1.10.6.tgz", - "integrity": "sha512-kARYANp5GnmsQiViA5Qu74weYQ3phOHSYQf0G+U5wB3NB5JmBHnZcOc46Ig21tTypWtdv7u63TaltJQE41noyg==", "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -2289,7 +2740,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -2306,7 +2756,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -2323,7 +2772,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -2340,7 +2788,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -2357,7 +2804,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -2408,7 +2854,6 @@ "cpu": [ "wasm32" ], - "dev": true, "license": "MIT", "optional": true, "dependencies": { @@ -2425,7 +2870,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -2442,7 +2886,6 @@ "cpu": [ "ia32" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -2459,7 +2902,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -2471,9 +2913,6 @@ }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "dev": true, "license": "MIT", "optional": true, "engines": { @@ -2482,9 +2921,6 @@ }, "node_modules/@placemarkio/check-geojson": { "version": "0.1.14", - "resolved": "https://registry.npmjs.org/@placemarkio/check-geojson/-/check-geojson-0.1.14.tgz", - "integrity": "sha512-PZvNKzt6STytUw21TUkqU+TG6dbwTWb1ACosvInBYTBm37zsr8C74J6crBTQ3BWkyd6YeitYd4HibJzBEyk6Aw==", - "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -2492,36 +2928,26 @@ }, "node_modules/@protobufjs/aspromise": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", "dev": true, "license": "BSD-3-Clause" }, "node_modules/@protobufjs/base64": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", "dev": true, "license": "BSD-3-Clause" }, "node_modules/@protobufjs/codegen": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", "dev": true, "license": "BSD-3-Clause" }, "node_modules/@protobufjs/eventemitter": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", "dev": true, "license": "BSD-3-Clause" }, "node_modules/@protobufjs/fetch": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -2531,43 +2957,33 @@ }, "node_modules/@protobufjs/float": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", "dev": true, "license": "BSD-3-Clause" }, "node_modules/@protobufjs/inquire": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", "dev": true, "license": "BSD-3-Clause" }, "node_modules/@protobufjs/path": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", "dev": true, "license": "BSD-3-Clause" }, "node_modules/@protobufjs/pool": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", "dev": true, "license": "BSD-3-Clause" }, "node_modules/@protobufjs/utf8": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", "dev": true, "license": "BSD-3-Clause" }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.53.3.tgz", - "integrity": "sha512-mRSi+4cBjrRLoaal2PnqH82Wqyb+d3HsPUN/W+WslCXsZsyHa9ZeQQX/pQsZaVIWDkPcpV6jJ+3KLbTbgnwv8w==", + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.57.1.tgz", + "integrity": "sha512-A6ehUVSiSaaliTxai040ZpZ2zTevHYbvu/lDoeAteHI8QnaosIzm4qwtezfRg1jOYaUmnzLX1AOD6Z+UJjtifg==", "cpu": [ "arm" ], @@ -2579,9 +2995,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.53.3.tgz", - "integrity": "sha512-CbDGaMpdE9sh7sCmTrTUyllhrg65t6SwhjlMJsLr+J8YjFuPmCEjbBSx4Z/e4SmDyH3aB5hGaJUP2ltV/vcs4w==", + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.57.1.tgz", + "integrity": "sha512-dQaAddCY9YgkFHZcFNS/606Exo8vcLHwArFZ7vxXq4rigo2bb494/xKMMwRRQW6ug7Js6yXmBZhSBRuBvCCQ3w==", "cpu": [ "arm64" ], @@ -2593,9 +3009,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.53.3.tgz", - "integrity": "sha512-Nr7SlQeqIBpOV6BHHGZgYBuSdanCXuw09hon14MGOLGmXAFYjx1wNvquVPmpZnl0tLjg25dEdr4IQ6GgyToCUA==", + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.57.1.tgz", + "integrity": "sha512-crNPrwJOrRxagUYeMn/DZwqN88SDmwaJ8Cvi/TN1HnWBU7GwknckyosC2gd0IqYRsHDEnXf328o9/HC6OkPgOg==", "cpu": [ "arm64" ], @@ -2607,9 +3023,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.53.3.tgz", - "integrity": "sha512-DZ8N4CSNfl965CmPktJ8oBnfYr3F8dTTNBQkRlffnUarJ2ohudQD17sZBa097J8xhQ26AwhHJ5mvUyQW8ddTsQ==", + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.57.1.tgz", + "integrity": "sha512-Ji8g8ChVbKrhFtig5QBV7iMaJrGtpHelkB3lsaKzadFBe58gmjfGXAOfI5FV0lYMH8wiqsxKQ1C9B0YTRXVy4w==", "cpu": [ "x64" ], @@ -2621,9 +3037,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.53.3.tgz", - "integrity": "sha512-yMTrCrK92aGyi7GuDNtGn2sNW+Gdb4vErx4t3Gv/Tr+1zRb8ax4z8GWVRfr3Jw8zJWvpGHNpss3vVlbF58DZ4w==", + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.57.1.tgz", + "integrity": "sha512-R+/WwhsjmwodAcz65guCGFRkMb4gKWTcIeLy60JJQbXrJ97BOXHxnkPFrP+YwFlaS0m+uWJTstrUA9o+UchFug==", "cpu": [ "arm64" ], @@ -2635,9 +3051,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.53.3.tgz", - "integrity": "sha512-lMfF8X7QhdQzseM6XaX0vbno2m3hlyZFhwcndRMw8fbAGUGL3WFMBdK0hbUBIUYcEcMhVLr1SIamDeuLBnXS+Q==", + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.57.1.tgz", + "integrity": "sha512-IEQTCHeiTOnAUC3IDQdzRAGj3jOAYNr9kBguI7MQAAZK3caezRrg0GxAb6Hchg4lxdZEI5Oq3iov/w/hnFWY9Q==", "cpu": [ "x64" ], @@ -2649,9 +3065,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.53.3.tgz", - "integrity": "sha512-k9oD15soC/Ln6d2Wv/JOFPzZXIAIFLp6B+i14KhxAfnq76ajt0EhYc5YPeX6W1xJkAdItcVT+JhKl1QZh44/qw==", + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.57.1.tgz", + "integrity": "sha512-F8sWbhZ7tyuEfsmOxwc2giKDQzN3+kuBLPwwZGyVkLlKGdV1nvnNwYD0fKQ8+XS6hp9nY7B+ZeK01EBUE7aHaw==", "cpu": [ "arm" ], @@ -2663,9 +3079,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.53.3.tgz", - "integrity": "sha512-vTNlKq+N6CK/8UktsrFuc+/7NlEYVxgaEgRXVUVK258Z5ymho29skzW1sutgYjqNnquGwVUObAaxae8rZ6YMhg==", + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.57.1.tgz", + "integrity": "sha512-rGfNUfn0GIeXtBP1wL5MnzSj98+PZe/AXaGBCRmT0ts80lU5CATYGxXukeTX39XBKsxzFpEeK+Mrp9faXOlmrw==", "cpu": [ "arm" ], @@ -2677,9 +3093,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.53.3.tgz", - "integrity": "sha512-RGrFLWgMhSxRs/EWJMIFM1O5Mzuz3Xy3/mnxJp/5cVhZ2XoCAxJnmNsEyeMJtpK+wu0FJFWz+QF4mjCA7AUQ3w==", + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.57.1.tgz", + "integrity": "sha512-MMtej3YHWeg/0klK2Qodf3yrNzz6CGjo2UntLvk2RSPlhzgLvYEB3frRvbEF2wRKh1Z2fDIg9KRPe1fawv7C+g==", "cpu": [ "arm64" ], @@ -2691,9 +3107,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.53.3.tgz", - "integrity": "sha512-kASyvfBEWYPEwe0Qv4nfu6pNkITLTb32p4yTgzFCocHnJLAHs+9LjUu9ONIhvfT/5lv4YS5muBHyuV84epBo/A==", + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.57.1.tgz", + "integrity": "sha512-1a/qhaaOXhqXGpMFMET9VqwZakkljWHLmZOX48R0I/YLbhdxr1m4gtG1Hq7++VhVUmf+L3sTAf9op4JlhQ5u1Q==", "cpu": [ "arm64" ], @@ -2705,9 +3121,23 @@ ] }, "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.53.3.tgz", - "integrity": "sha512-JiuKcp2teLJwQ7vkJ95EwESWkNRFJD7TQgYmCnrPtlu50b4XvT5MOmurWNrCj3IFdyjBQ5p9vnrX4JM6I8OE7g==", + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.57.1.tgz", + "integrity": "sha512-QWO6RQTZ/cqYtJMtxhkRkidoNGXc7ERPbZN7dVW5SdURuLeVU7lwKMpo18XdcmpWYd0qsP1bwKPf7DNSUinhvA==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.57.1.tgz", + "integrity": "sha512-xpObYIf+8gprgWaPP32xiN5RVTi/s5FCR+XMXSKmhfoJjrpRAjCuuqQXyxUa/eJTdAE6eJ+KDKaoEqjZQxh3Gw==", "cpu": [ "loong64" ], @@ -2719,9 +3149,23 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.53.3.tgz", - "integrity": "sha512-EoGSa8nd6d3T7zLuqdojxC20oBfNT8nexBbB/rkxgKj5T5vhpAQKKnD+h3UkoMuTyXkP5jTjK/ccNRmQrPNDuw==", + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.57.1.tgz", + "integrity": "sha512-4BrCgrpZo4hvzMDKRqEaW1zeecScDCR+2nZ86ATLhAoJ5FQ+lbHVD3ttKe74/c7tNT9c6F2viwB3ufwp01Oh2w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.57.1.tgz", + "integrity": "sha512-NOlUuzesGauESAyEYFSe3QTUguL+lvrN1HtwEEsU2rOwdUDeTMJdO5dUYl/2hKf9jWydJrO9OL/XSSf65R5+Xw==", "cpu": [ "ppc64" ], @@ -2733,9 +3177,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.53.3.tgz", - "integrity": "sha512-4s+Wped2IHXHPnAEbIB0YWBv7SDohqxobiiPA1FIWZpX+w9o2i4LezzH/NkFUl8LRci/8udci6cLq+jJQlh+0g==", + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.57.1.tgz", + "integrity": "sha512-ptA88htVp0AwUUqhVghwDIKlvJMD/fmL/wrQj99PRHFRAG6Z5nbWoWG4o81Nt9FT+IuqUQi+L31ZKAFeJ5Is+A==", "cpu": [ "riscv64" ], @@ -2747,9 +3191,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.53.3.tgz", - "integrity": "sha512-68k2g7+0vs2u9CxDt5ktXTngsxOQkSEV/xBbwlqYcUrAVh6P9EgMZvFsnHy4SEiUl46Xf0IObWVbMvPrr2gw8A==", + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.57.1.tgz", + "integrity": "sha512-S51t7aMMTNdmAMPpBg7OOsTdn4tySRQvklmL3RpDRyknk87+Sp3xaumlatU+ppQ+5raY7sSTcC2beGgvhENfuw==", "cpu": [ "riscv64" ], @@ -2761,9 +3205,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.53.3.tgz", - "integrity": "sha512-VYsFMpULAz87ZW6BVYw3I6sWesGpsP9OPcyKe8ofdg9LHxSbRMd7zrVrr5xi/3kMZtpWL/wC+UIJWJYVX5uTKg==", + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.57.1.tgz", + "integrity": "sha512-Bl00OFnVFkL82FHbEqy3k5CUCKH6OEJL54KCyx2oqsmZnFTR8IoNqBF+mjQVcRCT5sB6yOvK8A37LNm/kPJiZg==", "cpu": [ "s390x" ], @@ -2775,9 +3219,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.53.3.tgz", - "integrity": "sha512-3EhFi1FU6YL8HTUJZ51imGJWEX//ajQPfqWLI3BQq4TlvHy4X0MOr5q3D2Zof/ka0d5FNdPwZXm3Yyib/UEd+w==", + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.57.1.tgz", + "integrity": "sha512-ABca4ceT4N+Tv/GtotnWAeXZUZuM/9AQyCyKYyKnpk4yoA7QIAuBt6Hkgpw8kActYlew2mvckXkvx0FfoInnLg==", "cpu": [ "x64" ], @@ -2789,9 +3233,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.53.3.tgz", - "integrity": "sha512-eoROhjcc6HbZCJr+tvVT8X4fW3/5g/WkGvvmwz/88sDtSJzO7r/blvoBDgISDiCjDRZmHpwud7h+6Q9JxFwq1Q==", + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.57.1.tgz", + "integrity": "sha512-HFps0JeGtuOR2convgRRkHCekD7j+gdAuXM+/i6kGzQtFhlCtQkpwtNzkNj6QhCDp7DRJ7+qC/1Vg2jt5iSOFw==", "cpu": [ "x64" ], @@ -2802,10 +3246,24 @@ "linux" ] }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.57.1.tgz", + "integrity": "sha512-H+hXEv9gdVQuDTgnqD+SQffoWoc0Of59AStSzTEj/feWTBAnSfSD3+Dql1ZruJQxmykT/JVY0dE8Ka7z0DH1hw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.53.3.tgz", - "integrity": "sha512-OueLAWgrNSPGAdUdIjSWXw+u/02BRTcnfw9PN41D2vq/JSEPnJnVuBgw18VkN8wcd4fjUs+jFHVM4t9+kBSNLw==", + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.57.1.tgz", + "integrity": "sha512-4wYoDpNg6o/oPximyc/NG+mYUejZrCU2q+2w6YZqrAs2UcNUChIZXjtafAiiZSUc7On8v5NyNj34Kzj/Ltk6dQ==", "cpu": [ "arm64" ], @@ -2817,9 +3275,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.53.3.tgz", - "integrity": "sha512-GOFuKpsxR/whszbF/bzydebLiXIHSgsEUp6M0JI8dWvi+fFa1TD6YQa4aSZHtpmh2/uAlj/Dy+nmby3TJ3pkTw==", + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.57.1.tgz", + "integrity": "sha512-O54mtsV/6LW3P8qdTcamQmuC990HDfR71lo44oZMZlXU4tzLrbvTii87Ni9opq60ds0YzuAlEr/GNwuNluZyMQ==", "cpu": [ "arm64" ], @@ -2831,9 +3289,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.53.3.tgz", - "integrity": "sha512-iah+THLcBJdpfZ1TstDFbKNznlzoxa8fmnFYK4V67HvmuNYkVdAywJSoteUszvBQ9/HqN2+9AZghbajMsFT+oA==", + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.57.1.tgz", + "integrity": "sha512-P3dLS+IerxCT/7D2q2FYcRdWRl22dNbrbBEtxdWhXrfIMPP9lQhb5h4Du04mdl5Woq05jVCDPCMF7Ub0NAjIew==", "cpu": [ "ia32" ], @@ -2845,9 +3303,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.53.3.tgz", - "integrity": "sha512-J9QDiOIZlZLdcot5NXEepDkstocktoVjkaKUtqzgzpt2yWjGlbYiKyp05rWwk4nypbYUNoFAztEgixoLaSETkg==", + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.57.1.tgz", + "integrity": "sha512-VMBH2eOOaKGtIJYleXsi2B8CPVADrh+TyNxJ4mWPnKfLB/DBUmzW+5m1xUrcwWoMfSLagIRpjUFeW5CO5hyciQ==", "cpu": [ "x64" ], @@ -2859,9 +3317,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.53.3.tgz", - "integrity": "sha512-UhTd8u31dXadv0MopwGgNOBpUVROFKWVQgAg5N1ESyCz8AuBcMqm4AuTjrwgQKGDfoFuz02EuMRHQIw/frmYKQ==", + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.57.1.tgz", + "integrity": "sha512-mxRFDdHIWRxg3UfIIAwCm6NzvxG0jDX/wBN6KsQFTvKFqqg9vTrWUE68qEjHt19A5wwx5X5aUi2zuZT7YR0jrA==", "cpu": [ "x64" ], @@ -2874,15 +3332,12 @@ }, "node_modules/@sinclair/typebox": { "version": "0.33.22", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.33.22.tgz", - "integrity": "sha512-auUj4k+f4pyrIVf4GW5UKquSZFHJWri06QgARy9C0t9ZTjJLIuNIrr1yl9bWcJWJ1Gz1vOvYN1D+QPaIlNMVkQ==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/@sindresorhus/merge-streams": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz", - "integrity": "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==", "dev": true, "license": "MIT", "engines": { @@ -2893,9 +3348,9 @@ } }, "node_modules/@standard-schema/spec": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.0.0.tgz", - "integrity": "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", + "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", "dev": true, "license": "MIT" }, @@ -2916,6 +3371,97 @@ "eslint": "^8.57.0 || ^9.0.0" } }, + "node_modules/@tanstack/eslint-plugin-query/node_modules/@typescript-eslint/project-service": { + "version": "8.55.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.55.0.tgz", + "integrity": "sha512-zRcVVPFUYWa3kNnjaZGXSu3xkKV1zXy8M4nO/pElzQhFweb7PPtluDLQtKArEOGmjXoRjnUZ29NjOiF0eCDkcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.55.0", + "@typescript-eslint/types": "^8.55.0", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@tanstack/eslint-plugin-query/node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.55.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.55.0.tgz", + "integrity": "sha512-1R9cXqY7RQd7WuqSN47PK9EDpgFUK3VqdmbYrvWJZYDd0cavROGn+74ktWBlmJ13NXUQKlZ/iAEQHI/V0kKe0Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@tanstack/eslint-plugin-query/node_modules/@typescript-eslint/typescript-estree": { + "version": "8.55.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.55.0.tgz", + "integrity": "sha512-EwrH67bSWdx/3aRQhCoxDaHM+CrZjotc2UCCpEDVqfCE+7OjKAGWNY2HsCSTEVvWH2clYQK8pdeLp42EVs+xQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.55.0", + "@typescript-eslint/tsconfig-utils": "8.55.0", + "@typescript-eslint/types": "8.55.0", + "@typescript-eslint/visitor-keys": "8.55.0", + "debug": "^4.4.3", + "minimatch": "^9.0.5", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.4.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@tanstack/eslint-plugin-query/node_modules/@typescript-eslint/utils": { + "version": "8.55.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.55.0.tgz", + "integrity": "sha512-BqZEsnPGdYpgyEIkDC1BadNY8oMwckftxBT+C8W0g1iKPdeqKZBtTfnvcq0nf60u7MkjFO8RBvpRGZBPw4L2ow==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/scope-manager": "8.55.0", + "@typescript-eslint/types": "8.55.0", + "@typescript-eslint/typescript-estree": "8.55.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, "node_modules/@tanstack/query-core": { "version": "5.90.12", "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.90.12.tgz", @@ -2946,10 +3492,9 @@ }, "node_modules/@testing-library/dom": { "version": "10.4.1", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz", - "integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@babel/code-frame": "^7.10.4", "@babel/runtime": "^7.12.5", @@ -2994,9 +3539,6 @@ }, "node_modules/@turf/bbox": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@turf/bbox/-/bbox-7.2.0.tgz", - "integrity": "sha512-wzHEjCXlYZiDludDbXkpBSmv8Zu6tPGLmJ1sXQ6qDwpLE1Ew3mcWqt8AaxfTP5QwDNQa3sf2vvgTEzNbPQkCiA==", - "dev": true, "license": "MIT", "dependencies": { "@turf/helpers": "^7.2.0", @@ -3010,9 +3552,6 @@ }, "node_modules/@turf/helpers": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@turf/helpers/-/helpers-7.2.0.tgz", - "integrity": "sha512-cXo7bKNZoa7aC7ydLmUR02oB3IgDe7MxiPuRz3cCtYQHn+BJ6h1tihmamYDWWUlPHgSNF0i3ATc4WmDECZafKw==", - "dev": true, "license": "MIT", "dependencies": { "@types/geojson": "^7946.0.10", @@ -3024,9 +3563,6 @@ }, "node_modules/@turf/meta": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@turf/meta/-/meta-7.2.0.tgz", - "integrity": "sha512-igzTdHsQc8TV1RhPuOLVo74Px/hyPrVgVOTgjWQZzt3J9BVseCdpfY/0cJBdlSRI4S/yTmmHl7gAqjhpYH5Yaw==", - "dev": true, "license": "MIT", "dependencies": { "@turf/helpers": "^7.2.0", @@ -3040,7 +3576,6 @@ "version": "0.10.1", "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz", "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==", - "dev": true, "license": "MIT", "optional": true, "dependencies": { @@ -3049,15 +3584,11 @@ }, "node_modules/@types/aria-query": { "version": "5.0.4", - "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", - "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", "dev": true, "license": "MIT" }, "node_modules/@types/b4a": { "version": "1.6.5", - "resolved": "https://registry.npmjs.org/@types/b4a/-/b4a-1.6.5.tgz", - "integrity": "sha512-jVCTfZJVaU6AqYC19wHEvK+MUNkh32iv8Hhb8hvJFk8bX3Um/Lq7litbOkcKKAH8gU31mgWvpNu8ijWQN7JWZQ==", "dev": true, "license": "MIT", "dependencies": { @@ -3077,8 +3608,6 @@ }, "node_modules/@types/compress-commons": { "version": "7.0.1", - "resolved": "https://registry.npmjs.org/@types/compress-commons/-/compress-commons-7.0.1.tgz", - "integrity": "sha512-2MNs8Qv4HRZIYAmDhUqBkPTU6qj4hqB4eKczIw68e899FXY0NMVjGZsi8B3i50HsbVaTe8q9GgTIqVbhbS9aHA==", "dev": true, "license": "MIT", "dependencies": { @@ -3089,8 +3618,6 @@ }, "node_modules/@types/crc32-stream": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@types/crc32-stream/-/crc32-stream-4.0.3.tgz", - "integrity": "sha512-DTag28dyA2A3yVTijkx5dfrTCE+5RC+XdWthkQOl2CCCdptgm/3rqwJsNdN5mljOKylf0mYv9KZl4FRaa2X8qA==", "dev": true, "license": "MIT", "dependencies": { @@ -3106,17 +3633,50 @@ }, "node_modules/@types/estree": { "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", - "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", "dev": true, "license": "MIT" }, - "node_modules/@types/geojson": { - "version": "7946.0.16", - "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.16.tgz", - "integrity": "sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==", + "node_modules/@types/geojson": { + "version": "7946.0.16", + "license": "MIT" + }, + "node_modules/@types/jsdom": { + "version": "27.0.0", + "resolved": "https://registry.npmjs.org/@types/jsdom/-/jsdom-27.0.0.tgz", + "integrity": "sha512-NZyFl/PViwKzdEkQg96gtnB8wm+1ljhdDay9ahn4hgb+SfVtPCbm3TlmDUFXTA+MGN3CijicnMhG18SI5H3rFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/tough-cookie": "*", + "parse5": "^7.0.0" + } + }, + "node_modules/@types/jsdom/node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/@types/jsdom/node_modules/parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", "dev": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } }, "node_modules/@types/json-schema": { "version": "7.0.15", @@ -3127,9 +3687,6 @@ }, "node_modules/@types/mute-stream": { "version": "0.0.4", - "resolved": "https://registry.npmjs.org/@types/mute-stream/-/mute-stream-0.0.4.tgz", - "integrity": "sha512-CPM9nzrCPPJHQNA9keH9CVkVI+WR5kMa+7XEs5jcGQ0VoAGnLv242w8lIVgwAEfmE4oufJRaTc9PNLQl0ioAow==", - "dev": true, "license": "MIT", "dependencies": { "@types/node": "*" @@ -3139,7 +3696,6 @@ "version": "22.19.3", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.3.tgz", "integrity": "sha512-1N9SBnWYOJTrNZCdh/yJE+t910Y128BoyY+zBLWhL3r0TYzlTmFdXrPwHL9DyFZmlEXNQQolTZh3KHV31QDhyA==", - "dev": true, "license": "MIT", "dependencies": { "undici-types": "~6.21.0" @@ -3151,6 +3707,7 @@ "integrity": "sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "csstype": "^3.2.2" } @@ -3161,14 +3718,13 @@ "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", "dev": true, "license": "MIT", + "peer": true, "peerDependencies": { "@types/react": "^19.2.0" } }, "node_modules/@types/readable-stream": { "version": "4.0.21", - "resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-4.0.21.tgz", - "integrity": "sha512-19eKVv9tugr03IgfXlA9UVUVRbW6IuqRO5B92Dl4a6pT7K8uaGrNS0GkxiZD0BOk6PLuXl5FhWl//eX/pzYdTQ==", "dev": true, "license": "MIT", "dependencies": { @@ -3177,32 +3733,30 @@ }, "node_modules/@types/streamx": { "version": "2.9.5", - "resolved": "https://registry.npmjs.org/@types/streamx/-/streamx-2.9.5.tgz", - "integrity": "sha512-IHYsa6jYrck8VEdSwpY141FTTf6D7boPeMq9jy4qazNrFMA4VbRz/sw5LSsfR7jwdDcx0QKWkUexZvsWBC2eIQ==", "dev": true, "license": "MIT", "dependencies": { "@types/node": "*" } }, + "node_modules/@types/tough-cookie": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", + "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/whatwg-mimetype": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/whatwg-mimetype/-/whatwg-mimetype-3.0.2.tgz", - "integrity": "sha512-c2AKvDT8ToxLIOUlN51gTiHXflsfIFisS4pO7pDPoKouJCESkhZnEy623gwP9laCy5lnLDAw1vAzu2vM2YLOrA==", "dev": true, "license": "MIT" }, "node_modules/@types/wrap-ansi": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/wrap-ansi/-/wrap-ansi-3.0.0.tgz", - "integrity": "sha512-ltIpx+kM7g/MLRZfkbL7EsCEjfzCcScLpkg37eXEtx5kmrAKBkTJwd1GIAjDSL8wTpM6Hzn5YO4pSb91BEwu1g==", - "dev": true, "license": "MIT" }, "node_modules/@types/zip-stream": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@types/zip-stream/-/zip-stream-7.0.0.tgz", - "integrity": "sha512-lU8b0uAYlw8U7gnQ0tgH91DMMX99Gdh7350YDtBEKW0A2LB6NIFub7Bep3oaEuqiiyEYMOZtUShrmgyWcxy/+Q==", "dev": true, "license": "MIT", "dependencies": { @@ -3240,6 +3794,69 @@ "typescript": ">=4.8.4 <6.0.0" } }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { + "version": "8.49.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.49.0.tgz", + "integrity": "sha512-npgS3zi+/30KSOkXNs0LQXtsg9ekZ8OISAOLGWA/ZOEn0ZH74Ginfl7foziV8DT+D98WfQ5Kopwqb/PZOaIJGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.49.0", + "@typescript-eslint/visitor-keys": "8.49.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { + "version": "8.49.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.49.0.tgz", + "integrity": "sha512-e9k/fneezorUo6WShlQpMxXh8/8wfyc+biu6tnAqA81oWrEic0k21RHzP9uqqpyBBeBKu4T+Bsjy9/b8u7obXQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { + "version": "8.49.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.49.0.tgz", + "integrity": "sha512-LlKaciDe3GmZFphXIc79THF/YYBugZ7FS1pO581E/edlVVNbZKDy93evqmrfQ9/Y4uN0vVhX4iuchq26mK/iiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.49.0", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { "version": "7.0.5", "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", @@ -3256,6 +3873,7 @@ "integrity": "sha512-N9lBGA9o9aqb1hVMc9hzySbhKibHmB+N3IpoShyV6HyQYRGIhlrO5rQgttypi+yEeKsKI4idxC8Jw6gXKD4THA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.49.0", "@typescript-eslint/types": "8.49.0", @@ -3275,6 +3893,69 @@ "typescript": ">=4.8.4 <6.0.0" } }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "version": "8.49.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.49.0.tgz", + "integrity": "sha512-npgS3zi+/30KSOkXNs0LQXtsg9ekZ8OISAOLGWA/ZOEn0ZH74Ginfl7foziV8DT+D98WfQ5Kopwqb/PZOaIJGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.49.0", + "@typescript-eslint/visitor-keys": "8.49.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { + "version": "8.49.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.49.0.tgz", + "integrity": "sha512-e9k/fneezorUo6WShlQpMxXh8/8wfyc+biu6tnAqA81oWrEic0k21RHzP9uqqpyBBeBKu4T+Bsjy9/b8u7obXQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { + "version": "8.49.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.49.0.tgz", + "integrity": "sha512-LlKaciDe3GmZFphXIc79THF/YYBugZ7FS1pO581E/edlVVNbZKDy93evqmrfQ9/Y4uN0vVhX4iuchq26mK/iiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.49.0", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/@typescript-eslint/project-service": { "version": "8.49.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.49.0.tgz", @@ -3292,20 +3973,150 @@ "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.55.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.55.0.tgz", + "integrity": "sha512-fVu5Omrd3jeqeQLiB9f1YsuK/iHFOwb04bCtY4BSCLgjNbOD33ZdV6KyEqplHr+IlpgT0QTZ/iJ+wT7hvTx49Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.55.0", + "@typescript-eslint/visitor-keys": "8.55.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.49.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.49.0.tgz", + "integrity": "sha512-8prixNi1/6nawsRYxet4YOhnbW+W9FK/bQPxsGB1D3ZrDzbJ5FXw5XmzxZv82X3B+ZccuSxo/X8q9nQ+mFecWA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.49.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.49.0.tgz", + "integrity": "sha512-KTExJfQ+svY8I10P4HdxKzWsvtVnsuCifU5MvXrRwoP2KOlNZ9ADNEWWsQTJgMxLzS5VLQKDjkCT/YzgsnqmZg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.49.0", + "@typescript-eslint/typescript-estree": "8.49.0", + "@typescript-eslint/utils": "8.49.0", + "debug": "^4.3.4", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { + "version": "8.49.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.49.0.tgz", + "integrity": "sha512-e9k/fneezorUo6WShlQpMxXh8/8wfyc+biu6tnAqA81oWrEic0k21RHzP9uqqpyBBeBKu4T+Bsjy9/b8u7obXQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.55.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.55.0.tgz", + "integrity": "sha512-ujT0Je8GI5BJWi+/mMoR0wxwVEQaxM+pi30xuMiJETlX80OPovb2p9E8ss87gnSVtYXtJoU9U1Cowcr6w2FE0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.49.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.49.0.tgz", + "integrity": "sha512-jrLdRuAbPfPIdYNppHJ/D0wN+wwNfJ32YTAm10eJVsFmrVpXQnDWBn8niCSMlWjvml8jsce5E/O+86IQtTbJWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.49.0", + "@typescript-eslint/tsconfig-utils": "8.49.0", + "@typescript-eslint/types": "8.49.0", + "@typescript-eslint/visitor-keys": "8.49.0", + "debug": "^4.3.4", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/@typescript-eslint/types": { + "version": "8.49.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.49.0.tgz", + "integrity": "sha512-e9k/fneezorUo6WShlQpMxXh8/8wfyc+biu6tnAqA81oWrEic0k21RHzP9uqqpyBBeBKu4T+Bsjy9/b8u7obXQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/scope-manager": { + "node_modules/@typescript-eslint/typescript-estree/node_modules/@typescript-eslint/visitor-keys": { "version": "8.49.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.49.0.tgz", - "integrity": "sha512-npgS3zi+/30KSOkXNs0LQXtsg9ekZ8OISAOLGWA/ZOEn0ZH74Ginfl7foziV8DT+D98WfQ5Kopwqb/PZOaIJGg==", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.49.0.tgz", + "integrity": "sha512-LlKaciDe3GmZFphXIc79THF/YYBugZ7FS1pO581E/edlVVNbZKDy93evqmrfQ9/Y4uN0vVhX4iuchq26mK/iiA==", "dev": true, "license": "MIT", "dependencies": { "@typescript-eslint/types": "8.49.0", - "@typescript-eslint/visitor-keys": "8.49.0" + "eslint-visitor-keys": "^4.2.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3315,35 +4126,30 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.49.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.49.0.tgz", - "integrity": "sha512-8prixNi1/6nawsRYxet4YOhnbW+W9FK/bQPxsGB1D3ZrDzbJ5FXw5XmzxZv82X3B+ZccuSxo/X8q9nQ+mFecWA==", + "node_modules/@typescript-eslint/typescript-estree/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" + "url": "https://opencollective.com/eslint" } }, - "node_modules/@typescript-eslint/type-utils": { + "node_modules/@typescript-eslint/utils": { "version": "8.49.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.49.0.tgz", - "integrity": "sha512-KTExJfQ+svY8I10P4HdxKzWsvtVnsuCifU5MvXrRwoP2KOlNZ9ADNEWWsQTJgMxLzS5VLQKDjkCT/YzgsnqmZg==", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.49.0.tgz", + "integrity": "sha512-N3W7rJw7Rw+z1tRsHZbK395TWSYvufBXumYtEGzypgMUthlg0/hmCImeA8hgO2d2G4pd7ftpxxul2J8OdtdaFA==", "dev": true, "license": "MIT", "dependencies": { + "@eslint-community/eslint-utils": "^4.7.0", + "@typescript-eslint/scope-manager": "8.49.0", "@typescript-eslint/types": "8.49.0", - "@typescript-eslint/typescript-estree": "8.49.0", - "@typescript-eslint/utils": "8.49.0", - "debug": "^4.3.4", - "ts-api-utils": "^2.1.0" + "@typescript-eslint/typescript-estree": "8.49.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3357,12 +4163,16 @@ "typescript": ">=4.8.4 <6.0.0" } }, - "node_modules/@typescript-eslint/types": { + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": { "version": "8.49.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.49.0.tgz", - "integrity": "sha512-e9k/fneezorUo6WShlQpMxXh8/8wfyc+biu6tnAqA81oWrEic0k21RHzP9uqqpyBBeBKu4T+Bsjy9/b8u7obXQ==", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.49.0.tgz", + "integrity": "sha512-npgS3zi+/30KSOkXNs0LQXtsg9ekZ8OISAOLGWA/ZOEn0ZH74Ginfl7foziV8DT+D98WfQ5Kopwqb/PZOaIJGg==", "dev": true, "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.49.0", + "@typescript-eslint/visitor-keys": "8.49.0" + }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, @@ -3371,45 +4181,29 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/typescript-estree": { + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": { "version": "8.49.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.49.0.tgz", - "integrity": "sha512-jrLdRuAbPfPIdYNppHJ/D0wN+wwNfJ32YTAm10eJVsFmrVpXQnDWBn8niCSMlWjvml8jsce5E/O+86IQtTbJWA==", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.49.0.tgz", + "integrity": "sha512-e9k/fneezorUo6WShlQpMxXh8/8wfyc+biu6tnAqA81oWrEic0k21RHzP9uqqpyBBeBKu4T+Bsjy9/b8u7obXQ==", "dev": true, "license": "MIT", - "dependencies": { - "@typescript-eslint/project-service": "8.49.0", - "@typescript-eslint/tsconfig-utils": "8.49.0", - "@typescript-eslint/types": "8.49.0", - "@typescript-eslint/visitor-keys": "8.49.0", - "debug": "^4.3.4", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "tinyglobby": "^0.2.15", - "ts-api-utils": "^2.1.0" - }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" } }, - "node_modules/@typescript-eslint/utils": { + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": { "version": "8.49.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.49.0.tgz", - "integrity": "sha512-N3W7rJw7Rw+z1tRsHZbK395TWSYvufBXumYtEGzypgMUthlg0/hmCImeA8hgO2d2G4pd7ftpxxul2J8OdtdaFA==", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.49.0.tgz", + "integrity": "sha512-LlKaciDe3GmZFphXIc79THF/YYBugZ7FS1pO581E/edlVVNbZKDy93evqmrfQ9/Y4uN0vVhX4iuchq26mK/iiA==", "dev": true, "license": "MIT", "dependencies": { - "@eslint-community/eslint-utils": "^4.7.0", - "@typescript-eslint/scope-manager": "8.49.0", "@typescript-eslint/types": "8.49.0", - "@typescript-eslint/typescript-estree": "8.49.0" + "eslint-visitor-keys": "^4.2.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3417,20 +4211,29 @@ "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <6.0.0" + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.49.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.49.0.tgz", - "integrity": "sha512-LlKaciDe3GmZFphXIc79THF/YYBugZ7FS1pO581E/edlVVNbZKDy93evqmrfQ9/Y4uN0vVhX4iuchq26mK/iiA==", + "version": "8.55.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.55.0.tgz", + "integrity": "sha512-AxNRwEie8Nn4eFS1FzDMJWIISMGoXMb037sgCBJ3UR6o0fQTzr2tqN9WT+DkWJPhIdQCfV7T6D387566VtnCJA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.49.0", + "@typescript-eslint/types": "8.55.0", "eslint-visitor-keys": "^4.2.1" }, "engines": { @@ -3481,6 +4284,97 @@ } } }, + "node_modules/@vitest/eslint-plugin/node_modules/@typescript-eslint/project-service": { + "version": "8.55.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.55.0.tgz", + "integrity": "sha512-zRcVVPFUYWa3kNnjaZGXSu3xkKV1zXy8M4nO/pElzQhFweb7PPtluDLQtKArEOGmjXoRjnUZ29NjOiF0eCDkcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.55.0", + "@typescript-eslint/types": "^8.55.0", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@vitest/eslint-plugin/node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.55.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.55.0.tgz", + "integrity": "sha512-1R9cXqY7RQd7WuqSN47PK9EDpgFUK3VqdmbYrvWJZYDd0cavROGn+74ktWBlmJ13NXUQKlZ/iAEQHI/V0kKe0Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@vitest/eslint-plugin/node_modules/@typescript-eslint/typescript-estree": { + "version": "8.55.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.55.0.tgz", + "integrity": "sha512-EwrH67bSWdx/3aRQhCoxDaHM+CrZjotc2UCCpEDVqfCE+7OjKAGWNY2HsCSTEVvWH2clYQK8pdeLp42EVs+xQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.55.0", + "@typescript-eslint/tsconfig-utils": "8.55.0", + "@typescript-eslint/types": "8.55.0", + "@typescript-eslint/visitor-keys": "8.55.0", + "debug": "^4.4.3", + "minimatch": "^9.0.5", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.4.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@vitest/eslint-plugin/node_modules/@typescript-eslint/utils": { + "version": "8.55.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.55.0.tgz", + "integrity": "sha512-BqZEsnPGdYpgyEIkDC1BadNY8oMwckftxBT+C8W0g1iKPdeqKZBtTfnvcq0nf60u7MkjFO8RBvpRGZBPw4L2ow==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/scope-manager": "8.55.0", + "@typescript-eslint/types": "8.55.0", + "@typescript-eslint/typescript-estree": "8.55.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, "node_modules/@vitest/expect": { "version": "4.0.15", "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.0.15.tgz", @@ -3594,9 +4488,6 @@ }, "node_modules/abort-controller": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "dev": true, "license": "MIT", "dependencies": { "event-target-shim": "^5.0.0" @@ -3607,17 +4498,14 @@ }, "node_modules/abstract-logging": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/abstract-logging/-/abstract-logging-2.0.1.tgz", - "integrity": "sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA==", "dev": true, "license": "MIT" }, "node_modules/acorn": { "version": "8.15.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", - "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -3627,18 +4515,22 @@ }, "node_modules/acorn-jsx": { "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, "license": "MIT", "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, + "node_modules/agent-base": { + "version": "7.1.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, "node_modules/ajv": { "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "license": "MIT", "dependencies": { @@ -3654,8 +4546,6 @@ }, "node_modules/ajv-formats": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", "dev": true, "license": "MIT", "dependencies": { @@ -3672,8 +4562,6 @@ }, "node_modules/ajv-formats/node_modules/ajv": { "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, "license": "MIT", "dependencies": { @@ -3689,8 +4577,6 @@ }, "node_modules/ajv-formats/node_modules/fast-uri": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", - "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", "dev": true, "funding": [ { @@ -3706,16 +4592,11 @@ }, "node_modules/ajv-formats/node_modules/json-schema-traverse": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true, "license": "MIT" }, "node_modules/ansi-diff": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/ansi-diff/-/ansi-diff-1.2.0.tgz", - "integrity": "sha512-BIXwHKpjzghBjcwEV10Y4b17tjHfK4nhEqK3LqyQ3JgcMcjmi3DIevozNgrOpfvBMmrq9dfvrPJSu5/5vNUBQg==", - "dev": true, "license": "MIT", "dependencies": { "ansi-split": "^1.0.1", @@ -3723,9 +4604,9 @@ } }, "node_modules/ansi-escapes": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.2.0.tgz", - "integrity": "sha512-g6LhBsl+GBPRWGWsBtutpzBYuIIdBkLEvad5C/va/74Db018+5TZiyA26cZJAr3Rft5lprVqOIPxf5Vid6tqAw==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.3.0.tgz", + "integrity": "sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg==", "dev": true, "license": "MIT", "dependencies": { @@ -3740,9 +4621,6 @@ }, "node_modules/ansi-regex": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -3750,9 +4628,6 @@ }, "node_modules/ansi-split": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ansi-split/-/ansi-split-1.0.1.tgz", - "integrity": "sha512-RRxQym4DFtDNmHIkW6aeFVvrXURb11lGAEPXNiryjCe8bK8RsANjzJ0M2aGOkvBYwP4Bl/xZ8ijtr6D3j1x/eg==", - "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^3.0.0" @@ -3760,9 +4635,6 @@ }, "node_modules/ansi-split/node_modules/ansi-regex": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", - "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", - "dev": true, "license": "MIT", "engines": { "node": ">=4" @@ -3770,9 +4642,6 @@ }, "node_modules/ansi-styles": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -3786,9 +4655,6 @@ }, "node_modules/archiver": { "version": "7.0.1", - "resolved": "https://registry.npmjs.org/archiver/-/archiver-7.0.1.tgz", - "integrity": "sha512-ZcbTaIqJOfCc03QwD468Unz/5Ir8ATtvAHsK+FdXbDIbGfihqh9mrvdcYunQzqn4HrvWWaFyaxJhGZagaJJpPQ==", - "dev": true, "license": "MIT", "dependencies": { "archiver-utils": "^5.0.2", @@ -3805,9 +4671,6 @@ }, "node_modules/archiver-utils": { "version": "5.0.2", - "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-5.0.2.tgz", - "integrity": "sha512-wuLJMmIBQYCsGZgYLTy5FIB2pF6Lfb6cXMSF8Qywwk3t20zWnAi7zLcQFdKQmIB8wyZpY5ER38x08GbwtR2cLA==", - "dev": true, "license": "MIT", "dependencies": { "glob": "^10.0.0", @@ -3824,9 +4687,6 @@ }, "node_modules/archiver-utils/node_modules/is-stream": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -3837,15 +4697,11 @@ }, "node_modules/argparse": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true, "license": "Python-2.0" }, "node_modules/aria-query": { "version": "5.3.0", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", - "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -3864,15 +4720,10 @@ }, "node_modules/async": { "version": "3.2.6", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", - "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", - "dev": true, "license": "MIT" }, "node_modules/atomic-sleep": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz", - "integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==", "dev": true, "license": "MIT", "engines": { @@ -3881,8 +4732,6 @@ }, "node_modules/avvio": { "version": "8.4.0", - "resolved": "https://registry.npmjs.org/avvio/-/avvio-8.4.0.tgz", - "integrity": "sha512-CDSwaxINFy59iNwhYnkvALBwZiTydGkOecZyPkqBpABYR1KqGEsET0VOOYDwtleZSUIdeY36DC2bSZ24CO1igA==", "dev": true, "license": "MIT", "dependencies": { @@ -3892,9 +4741,6 @@ }, "node_modules/b4a": { "version": "1.7.1", - "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.7.1.tgz", - "integrity": "sha512-ZovbrBV0g6JxK5cGUF1Suby1vLfKjv4RWi8IxoaO/Mon8BDD9I21RxjHFtgQ+kskJqLAVyQZly3uMBui+vhc8Q==", - "dev": true, "license": "Apache-2.0", "peerDependencies": { "react-native-b4a": "*" @@ -3907,16 +4753,10 @@ }, "node_modules/balanced-match": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true, "license": "MIT" }, "node_modules/bare-addon-resolve": { "version": "1.9.4", - "resolved": "https://registry.npmjs.org/bare-addon-resolve/-/bare-addon-resolve-1.9.4.tgz", - "integrity": "sha512-unn6Vy/Yke6F99vg/7tcrvM2KUvIhTNniaSqDbam4AWkd4NhvDVSrQiRYVlNzUV2P7SPobkCK7JFVxrJk9btCg==", - "dev": true, "license": "Apache-2.0", "dependencies": { "bare-module-resolve": "^1.10.0", @@ -3933,15 +4773,11 @@ }, "node_modules/bare-events": { "version": "2.7.0", - "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.7.0.tgz", - "integrity": "sha512-b3N5eTW1g7vXkw+0CXh/HazGTcO5KYuu/RCNaJbDMPI6LHDi+7qe8EmxKUVe1sUbY2KZOVZFyj62x0OEz9qyAA==", - "dev": true, + "devOptional": true, "license": "Apache-2.0" }, "node_modules/bare-fs": { "version": "4.4.4", - "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.4.4.tgz", - "integrity": "sha512-Q8yxM1eLhJfuM7KXVP3zjhBvtMJCYRByoTT+wHXjpdMELv0xICFJX+1w4c7csa+WZEOsq4ItJ4RGwvzid6m/dw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -3965,9 +4801,6 @@ }, "node_modules/bare-module-resolve": { "version": "1.11.1", - "resolved": "https://registry.npmjs.org/bare-module-resolve/-/bare-module-resolve-1.11.1.tgz", - "integrity": "sha512-DCxeT9i8sTs3vUMA3w321OX/oXtNEu5EjObQOnTmCdNp5RXHBAvAaBDHvAi9ta0q/948QPz+co6SsGi6aQMYRg==", - "dev": true, "license": "Apache-2.0", "dependencies": { "bare-semver": "^1.0.0" @@ -3983,9 +4816,6 @@ }, "node_modules/bare-os": { "version": "3.6.2", - "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-3.6.2.tgz", - "integrity": "sha512-T+V1+1srU2qYNBmJCXZkUY5vQ0B4FSlL3QDROnKQYOqeiQR8UbjNHlPa+TIbM4cuidiN9GaTaOZgSEgsvPbh5A==", - "dev": true, "license": "Apache-2.0", "engines": { "bare": ">=1.14.0" @@ -3993,9 +4823,6 @@ }, "node_modules/bare-path": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-3.0.0.tgz", - "integrity": "sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==", - "dev": true, "license": "Apache-2.0", "dependencies": { "bare-os": "^3.0.1" @@ -4003,15 +4830,10 @@ }, "node_modules/bare-semver": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/bare-semver/-/bare-semver-1.0.1.tgz", - "integrity": "sha512-UtggzHLiTrmFOC/ogQ+Hy7VfoKoIwrP1UFcYtTxoCUdLtsIErT8+SWtOC2DH/snT9h+xDrcBEPcwKei1mzemgg==", - "dev": true, "license": "Apache-2.0" }, "node_modules/bare-stream": { "version": "2.7.0", - "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.7.0.tgz", - "integrity": "sha512-oyXQNicV1y8nc2aKffH+BUHFRXmx6VrPzlnaEvMhram0nPBrKcEdcyBg5r08D0i8VxngHFAiVyn1QKXpSG0B8A==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -4032,9 +4854,6 @@ }, "node_modules/bare-url": { "version": "2.2.2", - "resolved": "https://registry.npmjs.org/bare-url/-/bare-url-2.2.2.tgz", - "integrity": "sha512-g+ueNGKkrjMazDG3elZO1pNs3HY5+mMmOet1jtKyhOaCnkLzitxf26z7hoAEkDNgdNmnc1KIlt/dw6Po6xZMpA==", - "dev": true, "license": "Apache-2.0", "dependencies": { "bare-path": "^3.0.0" @@ -4042,8 +4861,6 @@ }, "node_modules/base-x": { "version": "3.0.11", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.11.tgz", - "integrity": "sha512-xz7wQ8xDhdyP7tQxwdteLYeFfS68tSMNCZ/Y37WJ4bhGfKPpqEIlmIyueQHqOyoPhE6xNUqjzRr8ra0eF9VRvA==", "dev": true, "license": "MIT", "dependencies": { @@ -4052,8 +4869,6 @@ }, "node_modules/base32.js": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/base32.js/-/base32.js-0.1.0.tgz", - "integrity": "sha512-n3TkB02ixgBOhTvANakDb4xaMXnYUVkNoRFJjQflcqMQhyEKxEHdj3E6N8t8sUQ0mjH/3/JxzlXuz3ul/J90pQ==", "dev": true, "license": "MIT", "engines": { @@ -4062,9 +4877,6 @@ }, "node_modules/base64-js": { "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true, "funding": [ { "type": "github", @@ -4082,9 +4894,9 @@ "license": "MIT" }, "node_modules/baseline-browser-mapping": { - "version": "2.9.7", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.7.tgz", - "integrity": "sha512-k9xFKplee6KIio3IDbwj+uaCLpqzOwakOgmqzPezM0sFJlFKcg30vk2wOiAJtkTSfx0SSQDSe8q+mWA/fSH5Zg==", + "version": "2.9.19", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.19.tgz", + "integrity": "sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg==", "dev": true, "license": "Apache-2.0", "bin": { @@ -4093,8 +4905,6 @@ }, "node_modules/bcp-47": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/bcp-47/-/bcp-47-2.1.0.tgz", - "integrity": "sha512-9IIS3UPrvIa1Ej+lVDdDwO7zLehjqsaByECw0bu2RRGP73jALm6FYbzI5gWbgHLvNdkvfXB5YrSbocZdOS0c0w==", "dev": true, "license": "MIT", "dependencies": { @@ -4109,8 +4919,6 @@ }, "node_modules/bcp-47-match": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/bcp-47-match/-/bcp-47-match-2.0.3.tgz", - "integrity": "sha512-JtTezzbAibu8G0R9op9zb3vcWZd9JF6M0xOYGPn0fNCd7wOpRB1mU2mH9T8gaBGbAAyIIVgB2G7xG0GP98zMAQ==", "dev": true, "license": "MIT", "funding": { @@ -4120,8 +4928,6 @@ }, "node_modules/bcp-47-normalize": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/bcp-47-normalize/-/bcp-47-normalize-2.3.0.tgz", - "integrity": "sha512-8I/wfzqQvttUFz7HVJgIZ7+dj3vUaIyIxYXaTRP1YWoSDfzt6TUmxaKZeuXR62qBmYr+nvuWINFRl6pZ5DlN4Q==", "dev": true, "license": "MIT", "dependencies": { @@ -4135,27 +4941,29 @@ }, "node_modules/better-sqlite3": { "version": "11.10.0", - "resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-11.10.0.tgz", - "integrity": "sha512-EwhOpyXiOEL/lKzHz9AW1msWFNzGc/z+LzeB3/jnFJpxu+th2yqvzsSWas1v9jgs9+xiXJcD5A8CJxAG2TaghQ==", - "dev": true, "hasInstallScript": true, "license": "MIT", + "peer": true, "dependencies": { "bindings": "^1.5.0", "prebuild-install": "^7.1.1" } }, + "node_modules/bidi-js": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "require-from-string": "^2.0.2" + } + }, "node_modules/big-sparse-array": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/big-sparse-array/-/big-sparse-array-1.0.3.tgz", - "integrity": "sha512-6RjV/3mSZORlMdpUaQ6rUSpG637cZm0//E54YYGtQg1c1O+AbZP8UTdJ/TchsDZcTVLmyWZcseBfp2HBeXUXOQ==", "dev": true, "license": "MIT" }, "node_modules/binary-stream-equals": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/binary-stream-equals/-/binary-stream-equals-1.0.0.tgz", - "integrity": "sha512-xiUT5LGfD8JiLhbXiG+ByOnbgb9f2ssRLfZDQMl3nZdf89EotQZGZuMkDN8J3n46emabE7RnJ1q0r7Hv3INExw==", "dev": true, "license": "MIT", "dependencies": { @@ -4164,9 +4972,6 @@ }, "node_modules/bindings": { "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dev": true, "license": "MIT", "dependencies": { "file-uri-to-path": "1.0.0" @@ -4174,9 +4979,6 @@ }, "node_modules/bl": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "dev": true, "license": "MIT", "dependencies": { "buffer": "^5.5.0", @@ -4186,9 +4988,6 @@ }, "node_modules/bl/node_modules/readable-stream": { "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, "license": "MIT", "dependencies": { "inherits": "^2.0.3", @@ -4201,8 +5000,6 @@ }, "node_modules/bogon": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/bogon/-/bogon-1.1.0.tgz", - "integrity": "sha512-a6SnToksXHuUlgeMvI/txWmTcKz7c7iBa8f0HbXL4toN1Uza/CTQ4F7n9jSDX49TCpxv3KUP100q4sZfwLyLiw==", "dev": true, "license": "MIT", "dependencies": { @@ -4212,16 +5009,11 @@ }, "node_modules/boolbase": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", "dev": true, "license": "ISC" }, "node_modules/brace-expansion": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", - "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" @@ -4229,8 +5021,6 @@ }, "node_modules/braces": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "license": "MIT", "dependencies": { @@ -4240,6 +5030,10 @@ "node": ">=8" } }, + "node_modules/browser-or-node": { + "version": "2.1.1", + "license": "MIT" + }, "node_modules/browserslist": { "version": "4.28.1", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", @@ -4260,6 +5054,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", @@ -4276,9 +5071,6 @@ }, "node_modules/buffer": { "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, "funding": [ { "type": "github", @@ -4301,26 +5093,25 @@ }, "node_modules/buffer-crc32": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-1.0.0.tgz", - "integrity": "sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==", - "dev": true, "license": "MIT", "engines": { "node": ">=8.0.0" } }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true, + "license": "MIT", + "optional": true + }, "node_modules/buffer-peek-stream": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/buffer-peek-stream/-/buffer-peek-stream-1.1.0.tgz", - "integrity": "sha512-b3MXlJ52rPOL5xCAQsiCOy/tY9WXOP/hwATporJriUDxnT3MjJgVppDzTFegpg2Nw7NMS28MKC6IKvaXLnGr+Q==", - "dev": true, "license": "MIT" }, "node_modules/bundle-name": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", - "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", - "dev": true, "license": "MIT", "dependencies": { "run-applescript": "^7.0.0" @@ -4334,8 +5125,6 @@ }, "node_modules/call-bind": { "version": "1.0.8", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", - "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", "dev": true, "license": "MIT", "dependencies": { @@ -4353,8 +5142,6 @@ }, "node_modules/call-bind-apply-helpers": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", - "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", "dev": true, "license": "MIT", "dependencies": { @@ -4367,8 +5154,6 @@ }, "node_modules/call-bound": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", - "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", "dev": true, "license": "MIT", "dependencies": { @@ -4384,15 +5169,11 @@ }, "node_modules/call-me-maybe": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.2.tgz", - "integrity": "sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==", "dev": true, "license": "MIT" }, "node_modules/callsites": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, "license": "MIT", "engines": { @@ -4400,9 +5181,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001760", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001760.tgz", - "integrity": "sha512-7AAMPcueWELt1p3mi13HR/LHH0TJLT11cnwDJEs3xA4+CK/PLKeO9Kl1oru24htkyUKtkGCvAx4ohB0Ttry8Dw==", + "version": "1.0.30001769", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001769.tgz", + "integrity": "sha512-BCfFL1sHijQlBGWBMuJyhZUhzo7wer5sVj9hqekB/7xn0Ypy+pER/edCYQm4exbXj4WiySGp40P8UuTh6w1srg==", "dev": true, "funding": [ { @@ -4421,9 +5202,9 @@ "license": "CC-BY-4.0" }, "node_modules/chai": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.1.tgz", - "integrity": "sha512-p4Z49OGG5W/WBCPSS/dH3jQ73kD6tiMmUM+bckNK6Jr5JHMG3k9bg/BvKR8lKmtVBKmOiuVaV2ws8s9oSbwysg==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz", + "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==", "dev": true, "license": "MIT", "engines": { @@ -4432,8 +5213,6 @@ }, "node_modules/chalk": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "license": "MIT", "dependencies": { @@ -4449,9 +5228,6 @@ }, "node_modules/chardet": { "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "dev": true, "license": "MIT" }, "node_modules/chokidar": { @@ -4472,16 +5248,10 @@ }, "node_modules/chownr": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true, "license": "ISC" }, "node_modules/cli-cursor": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", - "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", - "dev": true, "license": "MIT", "dependencies": { "restore-cursor": "^5.0.0" @@ -4495,9 +5265,6 @@ }, "node_modules/cli-spinners": { "version": "2.9.2", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", - "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", - "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -4524,9 +5291,9 @@ } }, "node_modules/cli-truncate/node_modules/string-width": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.1.0.tgz", - "integrity": "sha512-Kxl3KJGb/gxkaUMOjRsQ8IrXiGW75O4E3RPjFIINOVH8AMl2SQ/yWdTzWwF3FevIX9LcMAjJW+GRwAlAbTSXdg==", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.1.1.tgz", + "integrity": "sha512-KpqHIdDL9KwYk22wEOg/VIqYbrnLeSApsKT/bSj6Ez7pn3CftUiLAv2Lccpq1ALcpLV9UX1Ppn92npZWu2w/aw==", "dev": true, "license": "MIT", "dependencies": { @@ -4542,9 +5309,6 @@ }, "node_modules/cli-width": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", - "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", - "dev": true, "license": "ISC", "engines": { "node": ">= 12" @@ -4552,9 +5316,6 @@ }, "node_modules/clone": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.8" @@ -4562,8 +5323,6 @@ }, "node_modules/codecs": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/codecs/-/codecs-3.1.0.tgz", - "integrity": "sha512-Dqx8NwvBvnMeuPQdVKy/XEF71igjR5apxBvCGeV0pP1tXadOiaLvDTXt7xh+/5wI1ASB195mXQGJbw3Ml4YDWQ==", "dev": true, "license": "MIT", "dependencies": { @@ -4572,9 +5331,6 @@ }, "node_modules/color-convert": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -4585,9 +5341,6 @@ }, "node_modules/color-name": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, "license": "MIT" }, "node_modules/colorette": { @@ -4599,8 +5352,6 @@ }, "node_modules/comapeocat": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/comapeocat/-/comapeocat-1.0.0.tgz", - "integrity": "sha512-Hhx/CXdJpFklif9AeS+EgNoSPxlOEvnYYzSAbZdqkbJc3c2GpECA8vo2zHCOVM+2a0X/GhR9fjbue1AaLwEkLg==", "dev": true, "license": "MIT", "dependencies": { @@ -4625,8 +5376,6 @@ }, "node_modules/comapeocat/node_modules/@commander-js/extra-typings": { "version": "14.0.0", - "resolved": "https://registry.npmjs.org/@commander-js/extra-typings/-/extra-typings-14.0.0.tgz", - "integrity": "sha512-hIn0ncNaJRLkZrxBIp5AsW/eXEHNKYQBh0aPdoUqNgD+Io3NIykQqpKFyKcuasZhicGaEZJX/JBSIkZ4e5x8Dg==", "dev": true, "license": "MIT", "peerDependencies": { @@ -4635,8 +5384,6 @@ }, "node_modules/comapeocat/node_modules/p-event": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/p-event/-/p-event-7.0.0.tgz", - "integrity": "sha512-z4Xv/ieHhi6Dx3A5xbZI8WWTn+eSRo6buGTvA8Yv2iLyX+61SUIMKcBszZRHA6e2Apld6QEDSclAuha2iUntyA==", "dev": true, "license": "MIT", "dependencies": { @@ -4650,20 +5397,18 @@ } }, "node_modules/commander": { - "version": "14.0.2", - "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.2.tgz", - "integrity": "sha512-TywoWNNRbhoD0BXs1P3ZEScW8W5iKrnbithIl0YH+uCmBd0QpPOA8yc82DS3BIE5Ma6FnBVUsJ7wVUDz4dvOWQ==", + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz", + "integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=20" } }, "node_modules/compact-encoding": { "version": "2.16.1", - "resolved": "https://registry.npmjs.org/compact-encoding/-/compact-encoding-2.16.1.tgz", - "integrity": "sha512-vP39X4nwtesmZucaAxDg4wnudOoaJTSR+fikzi8VLVxbwLmcWXf3t0LxY0n2H1AMpdoQZ08lmUf4GY3XiDPnMQ==", - "dev": true, "license": "Apache-2.0", "dependencies": { "b4a": "^1.3.0" @@ -4671,8 +5416,6 @@ }, "node_modules/compact-encoding-net": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/compact-encoding-net/-/compact-encoding-net-1.2.0.tgz", - "integrity": "sha512-LVXpNpF7PGQeHRVVLGgYWzuVoYAaDZvKUsUxRioGfkotzvOh4AzoQF1HBH3zMNaSnx7gJXuUr3hkjnijaH/Eng==", "dev": true, "license": "ISC", "dependencies": { @@ -4681,16 +5424,11 @@ }, "node_modules/compact-encoding-struct": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/compact-encoding-struct/-/compact-encoding-struct-1.3.0.tgz", - "integrity": "sha512-8wgarWCGjtTQlpLu7ebVeeW0hEterei/D8MoIASBiZIUKV2RtzEaViAK+EMemOOOaHQFbp6yRH/k4Q2I94Qpxg==", "dev": true, "license": "ISC" }, "node_modules/compress-commons": { "version": "6.0.2", - "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-6.0.2.tgz", - "integrity": "sha512-6FqVXeETqWPoGcfzrXb37E50NP0LXT8kAMu5ooZayhWWdgEY4lBEEcbQNXtkuKQsGduxiIcI4gOTsxTmuq/bSg==", - "dev": true, "license": "MIT", "dependencies": { "crc-32": "^1.2.0", @@ -4705,9 +5443,6 @@ }, "node_modules/compress-commons/node_modules/is-stream": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -4718,15 +5453,11 @@ }, "node_modules/concat-map": { "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true, "license": "MIT" }, "node_modules/content-disposition": { "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", "dev": true, "license": "MIT", "dependencies": { @@ -4745,8 +5476,6 @@ }, "node_modules/cookie": { "version": "0.7.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", - "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", "dev": true, "license": "MIT", "engines": { @@ -4755,15 +5484,10 @@ }, "node_modules/core-util-is": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true, "license": "MIT" }, "node_modules/corestore": { "version": "6.8.4", - "resolved": "https://registry.npmjs.org/corestore/-/corestore-6.8.4.tgz", - "integrity": "sha512-rJUn1bK2Id18mxZSb64fKGCSsbbBAvPUkSZVzsLB4Nnwhf3pkwxt/JjBvKHtsrvRyPAu9xtxUdUk1cSQ1JnOPw==", "dev": true, "license": "MIT", "dependencies": { @@ -4779,8 +5503,6 @@ }, "node_modules/crc": { "version": "3.8.0", - "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", - "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==", "dev": true, "license": "MIT", "dependencies": { @@ -4789,9 +5511,6 @@ }, "node_modules/crc-32": { "version": "1.2.2", - "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", - "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", - "dev": true, "license": "Apache-2.0", "bin": { "crc32": "bin/crc32.njs" @@ -4802,8 +5521,6 @@ }, "node_modules/crc-native": { "version": "1.1.8", - "resolved": "https://registry.npmjs.org/crc-native/-/crc-native-1.1.8.tgz", - "integrity": "sha512-R/RYbD8lhG5M1k0iLX49tJdwHM0ipevJPpZw2Wk7b4EShyvx2P0uaq79xyRpcknjiVGiUfjFA8Gyy0mOlhABvw==", "dev": true, "license": "Apache-2.0", "optional": true, @@ -4813,8 +5530,6 @@ }, "node_modules/crc-universal": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/crc-universal/-/crc-universal-1.0.4.tgz", - "integrity": "sha512-CE9xWEI6Gd5V0Bdmj5NoWH3d7+EIe4zUpy1sv6uvKYznzsDP1vhiWsTBmL6q9IrH2P6RRshp+8AkhR4CMtY5Hg==", "dev": true, "license": "ISC", "optionalDependencies": { @@ -4823,9 +5538,6 @@ }, "node_modules/crc32-stream": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-6.0.0.tgz", - "integrity": "sha512-piICUB6ei4IlTv1+653yq5+KoqfBYmj9bw6LqXoOneTMDXk5nM1qt12mFW1caG3LlJXEKW1Bp0WggEmIfQB34g==", - "dev": true, "license": "MIT", "dependencies": { "crc-32": "^1.2.0", @@ -4837,9 +5549,6 @@ }, "node_modules/cross-spawn": { "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "dev": true, "license": "MIT", "dependencies": { "path-key": "^3.1.0", @@ -4852,8 +5561,6 @@ }, "node_modules/css-select": { "version": "5.2.2", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", - "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -4869,8 +5576,6 @@ }, "node_modules/css-tree": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.1.0.tgz", - "integrity": "sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==", "dev": true, "license": "MIT", "dependencies": { @@ -4883,8 +5588,6 @@ }, "node_modules/css-what": { "version": "6.2.2", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz", - "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==", "dev": true, "license": "BSD-2-Clause", "engines": { @@ -4896,8 +5599,6 @@ }, "node_modules/csso": { "version": "5.0.5", - "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", - "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", "dev": true, "license": "MIT", "dependencies": { @@ -4910,8 +5611,6 @@ }, "node_modules/csso/node_modules/css-tree": { "version": "2.2.1", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", - "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", "dev": true, "license": "MIT", "dependencies": { @@ -4925,11 +5624,31 @@ }, "node_modules/csso/node_modules/mdn-data": { "version": "2.0.28", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", - "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==", "dev": true, "license": "CC0-1.0" }, + "node_modules/cssstyle": { + "version": "5.3.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@asamuzakjp/css-color": "^4.1.1", + "@csstools/css-syntax-patches-for-csstree": "^1.0.21", + "css-tree": "^3.1.0", + "lru-cache": "^11.2.4" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/cssstyle/node_modules/lru-cache": { + "version": "11.2.6", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, "node_modules/csstype": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", @@ -4937,17 +5656,33 @@ "dev": true, "license": "MIT" }, + "node_modules/data-urls": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-mimetype": "^5.0.0", + "whatwg-url": "^16.0.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + } + }, + "node_modules/data-urls/node_modules/whatwg-mimetype": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20" + } + }, "node_modules/debounceify": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/debounceify/-/debounceify-1.1.0.tgz", - "integrity": "sha512-eKuHDVfJVg+u/0nPy8P+fhnLgbyuTgVxuCRrS/R7EpDSMMkBDgSes41MJtSAY1F1hcqfHz3Zy/qpqHHIp/EhdA==", "dev": true, "license": "MIT" }, "node_modules/debug": { "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "dev": true, "license": "MIT", "dependencies": { @@ -4962,11 +5697,13 @@ } } }, + "node_modules/decimal.js": { + "version": "10.6.0", + "dev": true, + "license": "MIT" + }, "node_modules/decompress-response": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "dev": true, "license": "MIT", "dependencies": { "mimic-response": "^3.1.0" @@ -4980,9 +5717,6 @@ }, "node_modules/deep-extend": { "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true, "license": "MIT", "engines": { "node": ">=4.0.0" @@ -4990,16 +5724,11 @@ }, "node_modules/deep-is": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true, "license": "MIT" }, "node_modules/default-browser": { "version": "5.2.1", - "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz", - "integrity": "sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==", - "dev": true, "license": "MIT", "dependencies": { "bundle-name": "^4.1.0", @@ -5014,9 +5743,6 @@ }, "node_modules/default-browser-id": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.0.tgz", - "integrity": "sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==", - "dev": true, "license": "MIT", "engines": { "node": ">=18" @@ -5027,9 +5753,6 @@ }, "node_modules/defaults": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", - "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", - "dev": true, "license": "MIT", "dependencies": { "clone": "^1.0.2" @@ -5040,8 +5763,6 @@ }, "node_modules/define-data-property": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", "dev": true, "license": "MIT", "dependencies": { @@ -5058,9 +5779,6 @@ }, "node_modules/define-lazy-prop": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", - "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", - "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -5071,8 +5789,6 @@ }, "node_modules/define-properties": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", "dev": true, "license": "MIT", "dependencies": { @@ -5089,8 +5805,6 @@ }, "node_modules/depd": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", "dev": true, "license": "MIT", "engines": { @@ -5099,8 +5813,6 @@ }, "node_modules/dequal": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", - "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", "dev": true, "license": "MIT", "engines": { @@ -5109,16 +5821,11 @@ }, "node_modules/dereference-json-schema": { "version": "0.2.1", - "resolved": "https://registry.npmjs.org/dereference-json-schema/-/dereference-json-schema-0.2.1.tgz", - "integrity": "sha512-uzJsrg225owJyRQ8FNTPHIuBOdSzIZlHhss9u6W8mp7jJldHqGuLv9cULagP/E26QVJDnjtG8U7Dw139mM1ydA==", "dev": true, "license": "MIT" }, "node_modules/detect-libc": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.0.tgz", - "integrity": "sha512-vEtk+OcP7VBRtQZ1EJ3bdgzSfBjgnEalLTp5zjJrS+2Z1w2KZly4SBdac/WDU3hhsNAZ9E8SC96ME4Ey8MZ7cg==", - "dev": true, "license": "Apache-2.0", "engines": { "node": ">=8" @@ -5126,15 +5833,11 @@ }, "node_modules/dom-accessibility-api": { "version": "0.5.16", - "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", - "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", "dev": true, "license": "MIT" }, "node_modules/dom-serializer": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", - "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", "dev": true, "license": "MIT", "dependencies": { @@ -5148,8 +5851,6 @@ }, "node_modules/domelementtype": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", - "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", "dev": true, "funding": [ { @@ -5161,8 +5862,6 @@ }, "node_modules/domhandler": { "version": "5.0.3", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", - "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -5177,8 +5876,6 @@ }, "node_modules/domutils": { "version": "3.2.2", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", - "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -5192,8 +5889,6 @@ }, "node_modules/dot-prop": { "version": "9.0.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-9.0.0.tgz", - "integrity": "sha512-1gxPBJpI/pcjQhKgIU91II6Wkay+dLcN3M6rf2uwP8hRur3HtQXjVrdAK3sjC0piaEuxzMwjXChcETiJl47lAQ==", "dev": true, "license": "MIT", "dependencies": { @@ -5208,8 +5903,6 @@ }, "node_modules/dot-prop-extra": { "version": "10.2.0", - "resolved": "https://registry.npmjs.org/dot-prop-extra/-/dot-prop-extra-10.2.0.tgz", - "integrity": "sha512-Y28/q87Py9xa4uq0uwMeDd+3oh2TWV2tChN5HjIsCg9hK3YfUEuVLxPOofHdrWA3LpryMTlVLNt/Gt3SyydOCw==", "dev": true, "license": "MIT", "dependencies": { @@ -5222,17 +5915,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/dot-prop-extra/node_modules/type-fest": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-5.1.0.tgz", - "integrity": "sha512-wQ531tuWvB6oK+pchHIu5lHe5f5wpSCqB8Kf4dWQRbOYc9HTge7JL0G4Qd44bh6QuJCccIzL3bugb8GI0MwHrg==", + "node_modules/dot-prop/node_modules/type-fest": { + "version": "4.41.0", "dev": true, "license": "(MIT OR CC0-1.0)", - "dependencies": { - "tagged-tag": "^1.0.0" - }, "engines": { - "node": ">=20" + "node": ">=16" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -5240,8 +5928,6 @@ }, "node_modules/drizzle-orm": { "version": "1.0.0-beta.1-fd8bfcc", - "resolved": "https://registry.npmjs.org/drizzle-orm/-/drizzle-orm-1.0.0-beta.1-fd8bfcc.tgz", - "integrity": "sha512-zTEIb6vktmRIG2PXH7SwCznXxBCulgPSaZiUKI+Uzc7fvWwzZlfZa7BfKRrKiguGlAh87eJpsIR8tX6a8eJt5w==", "dev": true, "license": "Apache-2.0", "peerDependencies": { @@ -5358,8 +6044,6 @@ }, "node_modules/dunder-proto": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", - "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", "dev": true, "license": "MIT", "dependencies": { @@ -5373,43 +6057,31 @@ }, "node_modules/eastasianwidth": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true, "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.267", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.267.tgz", - "integrity": "sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==", + "version": "1.5.286", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.286.tgz", + "integrity": "sha512-9tfDXhJ4RKFNerfjdCcZfufu49vg620741MNs26a9+bhLThdB+plgMeou98CAaHu/WATj2iHOOHTp1hWtABj2A==", "dev": true, "license": "ISC" }, "node_modules/emoji-regex": { "version": "10.5.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.5.0.tgz", - "integrity": "sha512-lb49vf1Xzfx080OKA0o6l8DQQpV+6Vg95zyCJX9VB/BqKYlhG7N4wgROUUHRA+ZPUefLnteQOad7z1kT2bV7bg==", - "dev": true, "license": "MIT" }, "node_modules/end-of-stream": { "version": "1.4.5", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", - "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", - "dev": true, "license": "MIT", "dependencies": { "once": "^1.4.0" } }, "node_modules/ensure-error": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/ensure-error/-/ensure-error-4.0.0.tgz", - "integrity": "sha512-7Xenn3+R6tp2UqAbH9Jqs6QCSABQok+1VAhaPaF0jjm3iuhVHCblfBh18nYtpm3K9/V4Jpxz1JIqFZyrjstBtw==", - "dev": true, + "version": "5.0.0", "license": "MIT", "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -5417,8 +6089,6 @@ }, "node_modules/entities": { "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", "dev": true, "license": "BSD-2-Clause", "engines": { @@ -5443,8 +6113,6 @@ }, "node_modules/es-define-property": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", - "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", "dev": true, "license": "MIT", "engines": { @@ -5453,8 +6121,6 @@ }, "node_modules/es-errors": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", "dev": true, "license": "MIT", "engines": { @@ -5470,8 +6136,6 @@ }, "node_modules/es-object-atoms": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", - "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", "dev": true, "license": "MIT", "dependencies": { @@ -5482,9 +6146,9 @@ } }, "node_modules/esbuild": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", - "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.3.tgz", + "integrity": "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -5495,32 +6159,32 @@ "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.12", - "@esbuild/android-arm": "0.25.12", - "@esbuild/android-arm64": "0.25.12", - "@esbuild/android-x64": "0.25.12", - "@esbuild/darwin-arm64": "0.25.12", - "@esbuild/darwin-x64": "0.25.12", - "@esbuild/freebsd-arm64": "0.25.12", - "@esbuild/freebsd-x64": "0.25.12", - "@esbuild/linux-arm": "0.25.12", - "@esbuild/linux-arm64": "0.25.12", - "@esbuild/linux-ia32": "0.25.12", - "@esbuild/linux-loong64": "0.25.12", - "@esbuild/linux-mips64el": "0.25.12", - "@esbuild/linux-ppc64": "0.25.12", - "@esbuild/linux-riscv64": "0.25.12", - "@esbuild/linux-s390x": "0.25.12", - "@esbuild/linux-x64": "0.25.12", - "@esbuild/netbsd-arm64": "0.25.12", - "@esbuild/netbsd-x64": "0.25.12", - "@esbuild/openbsd-arm64": "0.25.12", - "@esbuild/openbsd-x64": "0.25.12", - "@esbuild/openharmony-arm64": "0.25.12", - "@esbuild/sunos-x64": "0.25.12", - "@esbuild/win32-arm64": "0.25.12", - "@esbuild/win32-ia32": "0.25.12", - "@esbuild/win32-x64": "0.25.12" + "@esbuild/aix-ppc64": "0.27.3", + "@esbuild/android-arm": "0.27.3", + "@esbuild/android-arm64": "0.27.3", + "@esbuild/android-x64": "0.27.3", + "@esbuild/darwin-arm64": "0.27.3", + "@esbuild/darwin-x64": "0.27.3", + "@esbuild/freebsd-arm64": "0.27.3", + "@esbuild/freebsd-x64": "0.27.3", + "@esbuild/linux-arm": "0.27.3", + "@esbuild/linux-arm64": "0.27.3", + "@esbuild/linux-ia32": "0.27.3", + "@esbuild/linux-loong64": "0.27.3", + "@esbuild/linux-mips64el": "0.27.3", + "@esbuild/linux-ppc64": "0.27.3", + "@esbuild/linux-riscv64": "0.27.3", + "@esbuild/linux-s390x": "0.27.3", + "@esbuild/linux-x64": "0.27.3", + "@esbuild/netbsd-arm64": "0.27.3", + "@esbuild/netbsd-x64": "0.27.3", + "@esbuild/openbsd-arm64": "0.27.3", + "@esbuild/openbsd-x64": "0.27.3", + "@esbuild/openharmony-arm64": "0.27.3", + "@esbuild/sunos-x64": "0.27.3", + "@esbuild/win32-arm64": "0.27.3", + "@esbuild/win32-ia32": "0.27.3", + "@esbuild/win32-x64": "0.27.3" } }, "node_modules/escalade": { @@ -5535,15 +6199,11 @@ }, "node_modules/escape-html": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", "dev": true, "license": "MIT" }, "node_modules/escape-string-regexp": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, "license": "MIT", "engines": { @@ -5559,6 +6219,7 @@ "integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -5652,8 +6313,6 @@ }, "node_modules/eslint-scope": { "version": "8.4.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", - "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -5669,8 +6328,6 @@ }, "node_modules/eslint-visitor-keys": { "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, "license": "Apache-2.0", "engines": { @@ -5695,8 +6352,6 @@ }, "node_modules/eslint/node_modules/brace-expansion": { "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, "license": "MIT", "dependencies": { @@ -5706,8 +6361,6 @@ }, "node_modules/eslint/node_modules/eslint-visitor-keys": { "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", - "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", "dev": true, "license": "Apache-2.0", "engines": { @@ -5719,8 +6372,6 @@ }, "node_modules/eslint/node_modules/minimatch": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "license": "ISC", "dependencies": { @@ -5732,8 +6383,6 @@ }, "node_modules/espree": { "version": "10.4.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", - "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -5750,8 +6399,6 @@ }, "node_modules/espree/node_modules/eslint-visitor-keys": { "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", - "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", "dev": true, "license": "Apache-2.0", "engines": { @@ -5763,8 +6410,6 @@ }, "node_modules/esprima": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true, "license": "BSD-2-Clause", "bin": { @@ -5777,8 +6422,6 @@ }, "node_modules/esquery": { "version": "1.6.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", - "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -5790,8 +6433,6 @@ }, "node_modules/esrecurse": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -5803,8 +6444,6 @@ }, "node_modules/estraverse": { "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, "license": "BSD-2-Clause", "engines": { @@ -5823,8 +6462,6 @@ }, "node_modules/esutils": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, "license": "BSD-2-Clause", "engines": { @@ -5833,9 +6470,6 @@ }, "node_modules/event-target-shim": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -5843,26 +6477,37 @@ }, "node_modules/eventemitter3": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", - "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", "dev": true, "license": "MIT" }, "node_modules/events": { "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.8.x" } }, + "node_modules/eventsource-client": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/eventsource-client/-/eventsource-client-1.2.0.tgz", + "integrity": "sha512-kDI75RSzO3TwyG/K9w1ap8XwqSPcwi6jaMkNulfVeZmSeUM49U8kUzk1s+vKNt0tGrXgK47i+620Yasn1ccFiw==", + "license": "MIT", + "dependencies": { + "eventsource-parser": "^3.0.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/eventsource-parser": { + "version": "3.0.6", + "license": "MIT", + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/expand-template": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", - "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", - "dev": true, "license": "(MIT OR WTFPL)", "engines": { "node": ">=6" @@ -5870,8 +6515,6 @@ }, "node_modules/expect-type": { "version": "1.2.2", - "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.2.2.tgz", - "integrity": "sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -5880,9 +6523,6 @@ }, "node_modules/external-editor": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", - "dev": true, "license": "MIT", "dependencies": { "chardet": "^0.7.0", @@ -5895,43 +6535,30 @@ }, "node_modules/fast-content-type-parse": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-1.1.0.tgz", - "integrity": "sha512-fBHHqSTFLVnR61C+gltJuE5GkVQMV0S2nqUO8TJ+5Z3qAKG8vAx4FKai1s5jq/inV1+sREynIWSuQ6HgoSXpDQ==", "dev": true, "license": "MIT" }, "node_modules/fast-decode-uri-component": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/fast-decode-uri-component/-/fast-decode-uri-component-1.0.1.tgz", - "integrity": "sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==", "dev": true, "license": "MIT" }, "node_modules/fast-deep-equal": { "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true, "license": "MIT" }, "node_modules/fast-fifo": { "version": "1.3.2", - "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", - "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", - "dev": true, "license": "MIT" }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true, "license": "MIT" }, "node_modules/fast-json-stringify": { "version": "5.16.1", - "resolved": "https://registry.npmjs.org/fast-json-stringify/-/fast-json-stringify-5.16.1.tgz", - "integrity": "sha512-KAdnLvy1yu/XrRtP+LJnxbBGrhN+xXu+gt3EUvZhYGKCr3lFHq/7UFJHHFgmJKoqlh6B40bZLEv7w46B0mqn1g==", "dev": true, "license": "MIT", "dependencies": { @@ -5946,8 +6573,6 @@ }, "node_modules/fast-json-stringify/node_modules/ajv": { "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, "license": "MIT", "dependencies": { @@ -5963,8 +6588,6 @@ }, "node_modules/fast-json-stringify/node_modules/ajv-formats": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", - "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", "dev": true, "license": "MIT", "dependencies": { @@ -5981,8 +6604,6 @@ }, "node_modules/fast-json-stringify/node_modules/ajv/node_modules/fast-uri": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", - "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", "dev": true, "funding": [ { @@ -5998,22 +6619,16 @@ }, "node_modules/fast-json-stringify/node_modules/json-schema-traverse": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true, "license": "MIT" }, "node_modules/fast-levenshtein": { "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true, "license": "MIT" }, "node_modules/fast-querystring": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/fast-querystring/-/fast-querystring-1.1.2.tgz", - "integrity": "sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg==", "dev": true, "license": "MIT", "dependencies": { @@ -6022,8 +6637,6 @@ }, "node_modules/fast-redact": { "version": "3.5.0", - "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.5.0.tgz", - "integrity": "sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==", "dev": true, "license": "MIT", "engines": { @@ -6032,15 +6645,11 @@ }, "node_modules/fast-uri": { "version": "2.4.0", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-2.4.0.tgz", - "integrity": "sha512-ypuAmmMKInk5q7XcepxlnUWDLWv4GFtaJqAzWKqn62IpQ3pejtr5dTVbt3vwqVaMKmkNR55sTT+CqUKIaT21BA==", "dev": true, "license": "MIT" }, "node_modules/fastify": { "version": "4.29.1", - "resolved": "https://registry.npmjs.org/fastify/-/fastify-4.29.1.tgz", - "integrity": "sha512-m2kMNHIG92tSNWv+Z3UeTR9AWLLuo7KctC7mlFPtMEVrfjIhmQhkQnT9v15qA/BfVq3vvj134Y0jl9SBje3jXQ==", "dev": true, "funding": [ { @@ -6074,15 +6683,11 @@ }, "node_modules/fastify-plugin": { "version": "4.5.1", - "resolved": "https://registry.npmjs.org/fastify-plugin/-/fastify-plugin-4.5.1.tgz", - "integrity": "sha512-stRHYGeuqpEZTL1Ef0Ovr2ltazUT9g844X5z/zEBFLG8RYlpDiOCIG+ATvYEp+/zmc7sN29mcIMp8gvYplYPIQ==", "dev": true, "license": "MIT" }, "node_modules/fastq": { "version": "1.19.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", - "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", "dev": true, "license": "ISC", "dependencies": { @@ -6091,8 +6696,6 @@ }, "node_modules/file-entry-cache": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", - "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", "dev": true, "license": "MIT", "dependencies": { @@ -6104,15 +6707,10 @@ }, "node_modules/file-uri-to-path": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true, "license": "MIT" }, "node_modules/fill-range": { "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "license": "MIT", "dependencies": { @@ -6124,9 +6722,6 @@ }, "node_modules/filter-obj": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-6.1.0.tgz", - "integrity": "sha512-xdMtCAODmPloU9qtmPcdBV9Kd27NtMse+4ayThxqIHUES5Z2S6bGpap5PpdmNM56ub7y3i1eyr+vJJIIgWGKmA==", - "dev": true, "license": "MIT", "engines": { "node": ">=18" @@ -6137,8 +6732,6 @@ }, "node_modules/find-my-way": { "version": "8.2.2", - "resolved": "https://registry.npmjs.org/find-my-way/-/find-my-way-8.2.2.tgz", - "integrity": "sha512-Dobi7gcTEq8yszimcfp/R7+owiT4WncAJ7VTTgFH1jYJ5GaG1FbhjwDG820hptN0QDFvzVY3RfCzdInvGPGzjA==", "dev": true, "license": "MIT", "dependencies": { @@ -6152,8 +6745,6 @@ }, "node_modules/find-up": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, "license": "MIT", "dependencies": { @@ -6169,8 +6760,6 @@ }, "node_modules/flat-cache": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", - "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", "dev": true, "license": "MIT", "dependencies": { @@ -6183,23 +6772,16 @@ }, "node_modules/flat-tree": { "version": "1.13.0", - "resolved": "https://registry.npmjs.org/flat-tree/-/flat-tree-1.13.0.tgz", - "integrity": "sha512-fT3HIuCPwHhFgJ20QYzDHgUG0zMmFg5cHvFiFo5h+QMSJ28TihsEVY0f8HGliuO+pOzmvjMx1odToeaEWkTnyQ==", "dev": true, "license": "MIT" }, "node_modules/flatted": { "version": "3.3.3", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", - "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", "dev": true, "license": "ISC" }, "node_modules/foreground-child": { "version": "3.3.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", - "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", - "dev": true, "license": "ISC", "dependencies": { "cross-spawn": "^7.0.6", @@ -6214,15 +6796,11 @@ }, "node_modules/format-util": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/format-util/-/format-util-1.0.5.tgz", - "integrity": "sha512-varLbTj0e0yVyRpqQhuWV+8hlePAgaoFRhNFj50BNjEIrw1/DphHSObtqwskVCPWNgzwPoQrZAbfa/SBiicNeg==", "dev": true, "license": "MIT" }, "node_modules/forwarded": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", "dev": true, "license": "MIT", "engines": { @@ -6231,15 +6809,10 @@ }, "node_modules/fs-constants": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true, "license": "MIT" }, "node_modules/fs-native-extensions": { "version": "1.4.3", - "resolved": "https://registry.npmjs.org/fs-native-extensions/-/fs-native-extensions-1.4.3.tgz", - "integrity": "sha512-dbf0K+UBeWfFmPgxN4Z1eNFRz0OGORfeMLxCDSjfCq5xF2JbmCLAQiO6B4qn1KKdtWAFAwwA1UwNZ8GTy0bIWw==", "dev": true, "license": "Apache-2.0", "optional": true, @@ -6265,8 +6838,6 @@ }, "node_modules/function-bind": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "dev": true, "license": "MIT", "funding": { @@ -6285,9 +6856,6 @@ }, "node_modules/get-east-asian-width": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.4.0.tgz", - "integrity": "sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==", - "dev": true, "license": "MIT", "engines": { "node": ">=18" @@ -6298,8 +6866,6 @@ }, "node_modules/get-intrinsic": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", - "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", "dev": true, "license": "MIT", "dependencies": { @@ -6323,8 +6889,6 @@ }, "node_modules/get-proto": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", - "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", "dev": true, "license": "MIT", "dependencies": { @@ -6337,16 +6901,10 @@ }, "node_modules/github-from-package": { "version": "0.0.0", - "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", - "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", - "dev": true, "license": "MIT" }, "node_modules/glob": { "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", - "dev": true, "license": "ISC", "dependencies": { "foreground-child": "^3.1.0", @@ -6365,8 +6923,6 @@ }, "node_modules/glob-parent": { "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, "license": "ISC", "dependencies": { @@ -6391,8 +6947,6 @@ }, "node_modules/globalthis": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", - "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", "dev": true, "license": "MIT", "dependencies": { @@ -6408,8 +6962,6 @@ }, "node_modules/gopd": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", - "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", "dev": true, "license": "MIT", "engines": { @@ -6421,9 +6973,6 @@ }, "node_modules/graceful-fs": { "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true, "license": "ISC" }, "node_modules/happy-dom": { @@ -6443,8 +6992,6 @@ }, "node_modules/happy-dom/node_modules/@types/node": { "version": "20.19.17", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.17.tgz", - "integrity": "sha512-gfehUI8N1z92kygssiuWvLiwcbOB3IRktR6hTDgJlXMYh5OvkPSRmgfoBUmfZt+vhwJtX7v1Yw4KvvAf7c5QKQ==", "dev": true, "license": "MIT", "dependencies": { @@ -6453,8 +7000,6 @@ }, "node_modules/has-flag": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, "license": "MIT", "engines": { @@ -6463,8 +7008,6 @@ }, "node_modules/has-property-descriptors": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "dev": true, "license": "MIT", "dependencies": { @@ -6476,8 +7019,6 @@ }, "node_modules/has-symbols": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", - "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "dev": true, "license": "MIT", "engines": { @@ -6489,8 +7030,6 @@ }, "node_modules/hasown": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "dev": true, "license": "MIT", "dependencies": { @@ -6517,10 +7056,19 @@ "hermes-estree": "0.25.1" } }, + "node_modules/html-encoding-sniffer": { + "version": "6.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@exodus/bytes": "^1.6.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + } + }, "node_modules/http-errors": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", "dev": true, "license": "MIT", "dependencies": { @@ -6534,10 +7082,32 @@ "node": ">= 0.8" } }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/husky": { "version": "9.1.7", - "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.7.tgz", - "integrity": "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==", "dev": true, "license": "MIT", "bin": { @@ -6552,8 +7122,6 @@ }, "node_modules/hyperbee": { "version": "2.26.5", - "resolved": "https://registry.npmjs.org/hyperbee/-/hyperbee-2.26.5.tgz", - "integrity": "sha512-6XIwQIF9wuFVCSS6ciXX+TNv3aUGzEujvI8rUYMjwDCBU+aYVbJuq2k2CEhjeLQSZHnt8j95h2lUtjkV1pBqKg==", "dev": true, "license": "MIT", "dependencies": { @@ -6573,8 +7141,6 @@ }, "node_modules/hyperblobs": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/hyperblobs/-/hyperblobs-2.3.0.tgz", - "integrity": "sha512-iBCLVEo6FK+Xd7cpLM3DQ6cTfuMmKPfDZNj5/JqKEgziBEuI0ZGGyMM5dqaVvtRX4s71y8BhrgsDi2p0pWdSmg==", "dev": true, "license": "MIT", "dependencies": { @@ -6585,8 +7151,6 @@ }, "node_modules/hypercore": { "version": "10.19.0", - "resolved": "https://registry.npmjs.org/hypercore/-/hypercore-10.19.0.tgz", - "integrity": "sha512-vdK9QC2BmylhL1gqUYBICgRLHYhPqX6f4iOYfQKqcV+xOkiLIJglBNLHIUVYHqGw5W0YunhRzbpA/9IhPtrJOw==", "dev": true, "license": "MIT", "dependencies": { @@ -6614,9 +7178,6 @@ }, "node_modules/hypercore-crypto": { "version": "3.4.2", - "resolved": "https://registry.npmjs.org/hypercore-crypto/-/hypercore-crypto-3.4.2.tgz", - "integrity": "sha512-16ii4M6T1dFfRa41Szv3IR0wXfImJMYJ8ysZEGwHEDH7sMeWVEBck6tg1GCNutYl39E+H7wMY2p3ndCRfj+XdQ==", - "dev": true, "license": "MIT", "dependencies": { "b4a": "^1.6.6", @@ -6626,8 +7187,6 @@ }, "node_modules/hypercore-errors": { "version": "1.5.0", - "resolved": "https://registry.npmjs.org/hypercore-errors/-/hypercore-errors-1.5.0.tgz", - "integrity": "sha512-5KQ/SuDxsvet+7qWA35Ay6zdD9WyAHQoyWHGcPUTbmJBd300gvNIJoi3oma7kp4TTCSzii6qYumNZe/s0j/saQ==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -6636,8 +7195,6 @@ }, "node_modules/hypercore-id-encoding": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/hypercore-id-encoding/-/hypercore-id-encoding-1.3.0.tgz", - "integrity": "sha512-W6sHdGo5h7LXEsoWfKf/KfuROZmZRQDlGqJF2EPHW+noCK66Vvr0+zE6cL0vqQi18s0kQPeN7Sq3QyR0Ytc2VQ==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -6647,8 +7204,6 @@ }, "node_modules/hyperdrive": { "version": "11.5.3", - "resolved": "https://registry.npmjs.org/hyperdrive/-/hyperdrive-11.5.3.tgz", - "integrity": "sha512-0542G6n9eAXK/+fl6bs+9rvxCrL/dQo9mZsbY+BFSCD3S6ymBlaVnjOCuQdNflYBOHFVNnbBYdDvZ9meInv+tw==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -6666,9 +7221,6 @@ }, "node_modules/iconv-lite": { "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3" @@ -6679,9 +7231,6 @@ }, "node_modules/ieee754": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true, "funding": [ { "type": "github", @@ -6700,8 +7249,6 @@ }, "node_modules/ignore": { "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, "license": "MIT", "engines": { @@ -6710,8 +7257,6 @@ }, "node_modules/import-fresh": { "version": "3.3.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", - "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", "dev": true, "license": "MIT", "dependencies": { @@ -6727,8 +7272,6 @@ }, "node_modules/imurmurhash": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, "license": "MIT", "engines": { @@ -6737,8 +7280,6 @@ }, "node_modules/index-to-position": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/index-to-position/-/index-to-position-1.2.0.tgz", - "integrity": "sha512-Yg7+ztRkqslMAS2iFaU+Oa4KTSidr63OsFGlOrJoW981kIYO3CGCS3wA95P1mUi/IVSJkn0D479KTJpVpvFNuw==", "dev": true, "license": "MIT", "engines": { @@ -6750,23 +7291,14 @@ }, "node_modules/inherits": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true, "license": "ISC" }, "node_modules/ini": { "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true, "license": "ISC" }, "node_modules/into-stream": { "version": "8.0.1", - "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-8.0.1.tgz", - "integrity": "sha512-Vp2df7Utjs/1/sv0Vlj2X4u2e2yaCrcMd4T9u0D9B36XvxIOBHA2JIZTXCp2TPCa7w/ebwWVkXhbp9At1wJ0zg==", - "dev": true, "license": "MIT", "engines": { "node": ">=16" @@ -6777,8 +7309,6 @@ }, "node_modules/ipaddr.js": { "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", "dev": true, "license": "MIT", "engines": { @@ -6787,8 +7317,6 @@ }, "node_modules/is-alphabetical": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", - "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", "dev": true, "license": "MIT", "funding": { @@ -6798,8 +7326,6 @@ }, "node_modules/is-alphanumerical": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", - "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", "dev": true, "license": "MIT", "dependencies": { @@ -6813,8 +7339,6 @@ }, "node_modules/is-decimal": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", - "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", "dev": true, "license": "MIT", "funding": { @@ -6824,9 +7348,6 @@ }, "node_modules/is-docker": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", - "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", - "dev": true, "license": "MIT", "bin": { "is-docker": "cli.js" @@ -6840,8 +7361,6 @@ }, "node_modules/is-extglob": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, "license": "MIT", "engines": { @@ -6866,8 +7385,6 @@ }, "node_modules/is-glob": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, "license": "MIT", "dependencies": { @@ -6879,9 +7396,6 @@ }, "node_modules/is-inside-container": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", - "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", - "dev": true, "license": "MIT", "dependencies": { "is-docker": "^3.0.0" @@ -6898,9 +7412,6 @@ }, "node_modules/is-interactive": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz", - "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -6911,8 +7422,6 @@ }, "node_modules/is-it-type": { "version": "5.1.3", - "resolved": "https://registry.npmjs.org/is-it-type/-/is-it-type-5.1.3.tgz", - "integrity": "sha512-AX2uU0HW+TxagTgQXOJY7+2fbFHemC7YFBwN1XqD8qQMKdtfbOC8OC3fUb4s5NU59a3662Dzwto8tWDdZYRXxg==", "dev": true, "license": "MIT", "dependencies": { @@ -6924,8 +7433,6 @@ }, "node_modules/is-number": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, "license": "MIT", "engines": { @@ -6934,8 +7441,6 @@ }, "node_modules/is-options": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-options/-/is-options-1.0.2.tgz", - "integrity": "sha512-u+Ai74c8Q74aS8BuHwPdI1jptGOT1FQXgCq8/zv0xRuE+wRgSMEJLj8lVO8Zp9BeGb29BXY6AsNPinfqjkr7Fg==", "dev": true, "license": "MIT", "dependencies": { @@ -6944,8 +7449,6 @@ }, "node_modules/is-plain-obj": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", - "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", "dev": true, "license": "MIT", "engines": { @@ -6955,11 +7458,25 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/is-stream": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", + "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-unicode-supported": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz", - "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=18" @@ -6970,9 +7487,6 @@ }, "node_modules/is-wsl": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", - "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", - "dev": true, "license": "MIT", "dependencies": { "is-inside-container": "^1.0.0" @@ -6986,22 +7500,15 @@ }, "node_modules/isarray": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", "dev": true, "license": "MIT" }, "node_modules/isexe": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true, "license": "ISC" }, "node_modules/iso-3166": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/iso-3166/-/iso-3166-4.3.0.tgz", - "integrity": "sha512-H4kM/sVbxTjSl9xnQCYOrNWdpN0R8Uz26j1BuXI9E6U+kw5wmd3HyPgr/v4+NCuvV/NcvwTfZxd5XZ4lPKvBNA==", "dev": true, "license": "MIT", "funding": { @@ -7009,11 +7516,14 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/itty-router": { + "version": "5.0.22", + "resolved": "https://registry.npmjs.org/itty-router/-/itty-router-5.0.22.tgz", + "integrity": "sha512-9hmdGErWdYDOurGYxSbqLhy4EFReIwk71hMZTJ5b+zfa2zjMNV1ftFno2b8VjAQvX615gNB8Qxbl9JMRqHnIVA==", + "license": "MIT" + }, "node_modules/jackspeak": { "version": "3.4.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", - "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", - "dev": true, "license": "BlueOak-1.0.0", "dependencies": { "@isaacs/cliui": "^8.0.2" @@ -7027,15 +7537,11 @@ }, "node_modules/js-tokens": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "dev": true, "license": "MIT" }, "node_modules/js-yaml": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, "license": "MIT", "dependencies": { @@ -7045,20 +7551,71 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/jsdom": { + "version": "28.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@acemir/cssom": "^0.9.31", + "@asamuzakjp/dom-selector": "^6.7.6", + "@exodus/bytes": "^1.11.0", + "cssstyle": "^5.3.7", + "data-urls": "^7.0.0", + "decimal.js": "^10.6.0", + "html-encoding-sniffer": "^6.0.0", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.6", + "is-potential-custom-element-name": "^1.0.1", + "parse5": "^8.0.0", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^6.0.0", + "undici": "^7.20.0", + "w3c-xmlserializer": "^5.0.0", + "webidl-conversions": "^8.0.1", + "whatwg-mimetype": "^5.0.0", + "whatwg-url": "^16.0.0", + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "canvas": "^3.0.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/jsdom/node_modules/undici": { + "version": "7.21.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20.18.1" + } + }, + "node_modules/jsdom/node_modules/whatwg-mimetype": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20" + } + }, "node_modules/jsep": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/jsep/-/jsep-1.4.0.tgz", - "integrity": "sha512-B7qPcEVE3NVkmSJbaYxvv4cHkVW7DQsZz13pUMrfS8z8Q/BuShN+gcTXrUlPiGqM2/t/EEaI030bpxMqY8gMlw==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">= 10.16.0" } }, "node_modules/jsesc": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", - "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", "dev": true, "license": "MIT", "bin": { @@ -7070,15 +7627,11 @@ }, "node_modules/json-buffer": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", "dev": true, "license": "MIT" }, "node_modules/json-parse-even-better-errors": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-4.0.0.tgz", - "integrity": "sha512-lR4MXjGNgkJc7tkQ97kb2nuEMnNCyU//XYVH0MKTGcXEiSudQ5MKGKen3C5QubYy0vmq+JGitUg92uuywGEwIA==", "dev": true, "license": "MIT", "engines": { @@ -7087,8 +7640,6 @@ }, "node_modules/json-schema-faker": { "version": "0.5.9", - "resolved": "https://registry.npmjs.org/json-schema-faker/-/json-schema-faker-0.5.9.tgz", - "integrity": "sha512-fNKLHgDvfGNNTX1zqIjqFMJjCLzJ2kvnJ831x4aqkAoeE4jE2TxvpJdhOnk3JU3s42vFzmXvkpbYzH5H3ncAzg==", "dev": true, "license": "MIT", "dependencies": { @@ -7101,9 +7652,6 @@ }, "node_modules/json-schema-ref-parser": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/json-schema-ref-parser/-/json-schema-ref-parser-6.1.0.tgz", - "integrity": "sha512-pXe9H1m6IgIpXmE5JSb8epilNTGsmTb2iPohAXpOdhqGFbQjNeHHsZxU+C8w6T81GZxSPFLeUoqDJmzxx5IGuw==", - "deprecated": "Please switch to @apidevtools/json-schema-ref-parser", "dev": true, "license": "MIT", "dependencies": { @@ -7114,8 +7662,6 @@ }, "node_modules/json-schema-ref-parser/node_modules/argparse": { "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, "license": "MIT", "dependencies": { @@ -7124,8 +7670,6 @@ }, "node_modules/json-schema-ref-parser/node_modules/js-yaml": { "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dev": true, "license": "MIT", "dependencies": { @@ -7138,8 +7682,6 @@ }, "node_modules/json-schema-ref-resolver": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-schema-ref-resolver/-/json-schema-ref-resolver-1.0.1.tgz", - "integrity": "sha512-EJAj1pgHc1hxF6vo2Z3s69fMjO1INq6eGHXZ8Z6wCQeldCuwxGK9Sxf4/cScGn3FZubCVUehfWtcDM/PLteCQw==", "dev": true, "license": "MIT", "dependencies": { @@ -7148,15 +7690,11 @@ }, "node_modules/json-schema-traverse": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true, "license": "MIT" }, "node_modules/json-stable-stringify": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.3.0.tgz", - "integrity": "sha512-qtYiSSFlwot9XHtF9bD9c7rwKjr+RecWT//ZnPvSmEjpV5mmPOCN4j8UjY5hbjNkOwZ/jQv3J6R1/pL7RwgMsg==", "dev": true, "license": "MIT", "dependencies": { @@ -7175,16 +7713,11 @@ }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true, "license": "MIT" }, "node_modules/json-stringify-pretty-compact": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/json-stringify-pretty-compact/-/json-stringify-pretty-compact-4.0.0.tgz", - "integrity": "sha512-3CNZ2DnrpByG9Nqj6Xo8vqbjT4F6N+tb4Gb28ESAZjYZ5yqvmc56J+/kuIwkaAMOyblTQhUW7PxMkUb8Q36N3Q==", - "dev": true, "license": "MIT" }, "node_modules/json5": { @@ -7202,8 +7735,6 @@ }, "node_modules/jsonify": { "version": "0.0.1", - "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.1.tgz", - "integrity": "sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg==", "dev": true, "license": "Public Domain", "funding": { @@ -7212,8 +7743,6 @@ }, "node_modules/jsonpath-plus": { "version": "10.3.0", - "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-10.3.0.tgz", - "integrity": "sha512-8TNmfeTCk2Le33A3vRRwtuworG/L5RrgMvdjhKZxvyShO+mBu2fP50OWUjRLNtvw344DdDarFh9buFAZs5ujeA==", "dev": true, "license": "MIT", "dependencies": { @@ -7231,8 +7760,6 @@ }, "node_modules/keyv": { "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", "dev": true, "license": "MIT", "dependencies": { @@ -7240,10 +7767,9 @@ } }, "node_modules/ky": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/ky/-/ky-1.10.0.tgz", - "integrity": "sha512-YRPCzHEWZffbfvmRrfwa+5nwBHwZuYiTrfDX0wuhGBPV0pA/zCqcOq93MDssON/baIkpYbvehIX5aLpMxrRhaA==", - "dev": true, + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/ky/-/ky-1.14.3.tgz", + "integrity": "sha512-9zy9lkjac+TR1c2tG+mkNSVlyOpInnWdSMiue4F+kq8TwJSgv6o8jhLRg8Ho6SnZ9wOYUq/yozts9qQCfk7bIw==", "license": "MIT", "engines": { "node": ">=18" @@ -7254,9 +7780,6 @@ }, "node_modules/lazystream": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", - "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", - "dev": true, "license": "MIT", "dependencies": { "readable-stream": "^2.0.5" @@ -7267,16 +7790,10 @@ }, "node_modules/lazystream/node_modules/isarray": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true, "license": "MIT" }, "node_modules/lazystream/node_modules/readable-stream": { "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, "license": "MIT", "dependencies": { "core-util-is": "~1.0.0", @@ -7290,16 +7807,10 @@ }, "node_modules/lazystream/node_modules/safe-buffer": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true, "license": "MIT" }, "node_modules/lazystream/node_modules/string_decoder": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, "license": "MIT", "dependencies": { "safe-buffer": "~5.1.0" @@ -7307,8 +7818,6 @@ }, "node_modules/levn": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, "license": "MIT", "dependencies": { @@ -7321,8 +7830,6 @@ }, "node_modules/light-my-request": { "version": "5.14.0", - "resolved": "https://registry.npmjs.org/light-my-request/-/light-my-request-5.14.0.tgz", - "integrity": "sha512-aORPWntbpH5esaYpGOOmri0OHDOe3wC5M2MQxZ9dvMLZm6DnaAn0kJlcbU9hwsQgLzmZyReKwFwwPkR+nHu5kA==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -7376,8 +7883,6 @@ }, "node_modules/locate-path": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, "license": "MIT", "dependencies": { @@ -7392,23 +7897,15 @@ }, "node_modules/lodash": { "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true, "license": "MIT" }, "node_modules/lodash.merge": { "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true, "license": "MIT" }, "node_modules/log-symbols": { "version": "7.0.1", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-7.0.1.tgz", - "integrity": "sha512-ja1E3yCr9i/0hmBVaM0bfwDjnGy8I/s6PP4DFp+yP+a+mrHO4Rm7DtmnqROTUkHIkqffC84YY7AeqX6oFk0WFg==", - "dev": true, "license": "MIT", "dependencies": { "is-unicode-supported": "^2.0.0", @@ -7443,22 +7940,15 @@ }, "node_modules/long": { "version": "5.3.2", - "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", - "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", "dev": true, "license": "Apache-2.0" }, "node_modules/lru-cache": { "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true, "license": "ISC" }, "node_modules/lz-string": { "version": "1.5.0", - "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", - "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", "dev": true, "license": "MIT", "bin": { @@ -7467,8 +7957,6 @@ }, "node_modules/magic-bytes.js": { "version": "1.12.1", - "resolved": "https://registry.npmjs.org/magic-bytes.js/-/magic-bytes.js-1.12.1.tgz", - "integrity": "sha512-ThQLOhN86ZkJ7qemtVRGYM+gRgR8GEXNli9H/PMvpnZsE44Xfh3wx9kGJaldg314v85m+bFW6WBMaVHJc/c3zA==", "dev": true, "license": "MIT" }, @@ -7484,9 +7972,6 @@ }, "node_modules/map-obj": { "version": "5.0.2", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-5.0.2.tgz", - "integrity": "sha512-K6K2NgKnTXimT3779/4KxSvobxOtMmx1LBZ3NwRxT/MDIR3Br/fQ4Q+WCX5QxjyUR8zg5+RV9Tbf2c5pAWTD2A==", - "dev": true, "license": "MIT", "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" @@ -7497,8 +7982,6 @@ }, "node_modules/math-intrinsics": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", - "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", "dev": true, "license": "MIT", "engines": { @@ -7507,9 +7990,6 @@ }, "node_modules/mbtiles-reader": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/mbtiles-reader/-/mbtiles-reader-1.0.0.tgz", - "integrity": "sha512-KSjGEy/6J25RX4pqus3BNPyKo4IIlZka3iou53M4TWjaWHoAiEdFWPpzK4XEuI2oQkjJSM/tRKGMNor6yh0G+Q==", - "dev": true, "license": "MIT", "dependencies": { "@mapbox/sphericalmercator": "^2.0.1", @@ -7518,22 +7998,15 @@ } }, "node_modules/mbtiles-reader/node_modules/@mapbox/sphericalmercator": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@mapbox/sphericalmercator/-/sphericalmercator-2.0.1.tgz", - "integrity": "sha512-k1vM33y0oGIgip01EqdrWEMZLsYj9fP3jH7PZmeSCsCuubTQGjyrOANGSsqh+JtyqydYfXk9VBUVcyabvNTYXg==", - "dev": true + "version": "2.0.1" }, "node_modules/mdn-data": { "version": "2.12.2", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.12.2.tgz", - "integrity": "sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==", "dev": true, "license": "CC0-1.0" }, "node_modules/memorystream": { "version": "0.3.1", - "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", - "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", "dev": true, "engines": { "node": ">= 0.10.0" @@ -7541,8 +8014,6 @@ }, "node_modules/micromatch": { "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, "license": "MIT", "dependencies": { @@ -7555,8 +8026,6 @@ }, "node_modules/mime": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-4.1.0.tgz", - "integrity": "sha512-X5ju04+cAzsojXKes0B/S4tcYtFAJ6tTMuSPBEn9CPGlrWr8Fiw7qYeLT0XyH80HSoAoqWCaz+MWKh22P7G1cw==", "dev": true, "funding": [ "https://github.com/sponsors/broofa" @@ -7571,9 +8040,6 @@ }, "node_modules/mimic-function": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", - "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", - "dev": true, "license": "MIT", "engines": { "node": ">=18" @@ -7584,9 +8050,6 @@ }, "node_modules/mimic-response": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -7597,9 +8060,6 @@ }, "node_modules/minimatch": { "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" @@ -7613,9 +8073,6 @@ }, "node_modules/minimist": { "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -7623,9 +8080,6 @@ }, "node_modules/minipass": { "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "dev": true, "license": "ISC", "engines": { "node": ">=16 || 14 >=14.17" @@ -7633,8 +8087,6 @@ }, "node_modules/mirror-drive": { "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mirror-drive/-/mirror-drive-1.6.0.tgz", - "integrity": "sha512-mAEhDeH5UZ5T5ZO4rksHv7q0BDNIvDrY/YeFQcYXFyGc7QCc/CEybdi3zdhn2cjAhEAsPDWANWR1arfvmSAJmA==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -7646,8 +8098,6 @@ }, "node_modules/mkdirp": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", - "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", "dev": true, "license": "MIT", "bin": { @@ -7662,22 +8112,15 @@ }, "node_modules/mkdirp-classic": { "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", - "dev": true, "license": "MIT" }, "node_modules/ms": { "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true, "license": "MIT" }, "node_modules/multi-core-indexer": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/multi-core-indexer/-/multi-core-indexer-1.0.0.tgz", - "integrity": "sha512-7EEXJuBS+uhpDnNlfEn/PbT09pdCWulI8NHYS9v+t0sEksyD+X5HNsdJKDsIDtnBlYdMzxJRnZwMDVPfp/aPYw==", "dev": true, "license": "MIT", "dependencies": { @@ -7692,8 +8135,6 @@ }, "node_modules/multi-core-indexer/node_modules/@types/node": { "version": "18.19.127", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.127.tgz", - "integrity": "sha512-gSjxjrnKXML/yo0BO099uPixMqfpJU0TKYjpfLU7TrtA2WWDki412Np/RSTPRil1saKBhvVVKzVx/p/6p94nVA==", "dev": true, "license": "MIT", "dependencies": { @@ -7702,16 +8143,11 @@ }, "node_modules/multi-core-indexer/node_modules/undici-types": { "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", "dev": true, "license": "MIT" }, "node_modules/mute-stream": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz", - "integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==", - "dev": true, "license": "ISC", "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" @@ -7719,8 +8155,6 @@ }, "node_modules/mutexify": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/mutexify/-/mutexify-1.4.0.tgz", - "integrity": "sha512-pbYSsOrSB/AKN5h/WzzLRMFgZhClWccf2XIB4RSMC8JbquiB0e0/SH5AIfdQMdyHmYtv4seU7yV/TvAwPLJ1Yg==", "dev": true, "license": "MIT", "dependencies": { @@ -7742,9 +8176,6 @@ }, "node_modules/nanoassert": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/nanoassert/-/nanoassert-2.0.0.tgz", - "integrity": "sha512-7vO7n28+aYO4J+8w96AzhmU8G+Y/xpPDJz/se19ICsqj/momRbb9mh9ZUtkoJ5X3nTnPdhEJyc0qnM6yAsHBaA==", - "dev": true, "license": "ISC" }, "node_modules/nanoid": { @@ -7768,23 +8199,15 @@ }, "node_modules/napi-build-utils": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz", - "integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==", - "dev": true, "license": "MIT" }, "node_modules/natural-compare": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true, "license": "MIT" }, "node_modules/node-abi": { "version": "3.77.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.77.0.tgz", - "integrity": "sha512-DSmt0OEcLoK4i3NuscSbGjOf3bqiDEutejqENSplMSFA/gmB8mkED9G4pKWnPl7MDU4rSHebKPHeitpDfyH0cQ==", - "dev": true, "license": "MIT", "dependencies": { "semver": "^7.3.5" @@ -7802,9 +8225,6 @@ }, "node_modules/noise-curve-ed": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/noise-curve-ed/-/noise-curve-ed-2.1.0.tgz", - "integrity": "sha512-zAzJx+VwZM3w6EA1hTmDhJfvAnCeBQn/1FAeZ0LtGxCcCtlAK/uJXQVF/eDVUOaAZ286lHlx77WJ+qj9SmsRRg==", - "dev": true, "license": "ISC", "dependencies": { "b4a": "^1.1.0", @@ -7814,9 +8234,6 @@ }, "node_modules/noise-curve-ed/node_modules/sodium-native": { "version": "5.0.8", - "resolved": "https://registry.npmjs.org/sodium-native/-/sodium-native-5.0.8.tgz", - "integrity": "sha512-2ZxmF9Llvo/3X3NAc8VV6JFoswObg9u27Q8Be4BtCLDiejXuTt6Nm7+iIWUv+WMcs1eJ7YV5U2f4e8LidfIlRQ==", - "dev": true, "license": "MIT", "dependencies": { "require-addon": "^1.1.0", @@ -7828,9 +8245,6 @@ }, "node_modules/noise-curve-ed/node_modules/sodium-universal": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/sodium-universal/-/sodium-universal-5.0.1.tgz", - "integrity": "sha512-rv+aH+tnKB5H0MAc2UadHShLMslpJsc4wjdnHRtiSIEYpOetCgu8MS4ExQRia+GL/MK3uuCyZPeEsi+J3h+Q+Q==", - "dev": true, "license": "MIT", "dependencies": { "sodium-native": "^5.0.1" @@ -7846,9 +8260,6 @@ }, "node_modules/noise-handshake": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/noise-handshake/-/noise-handshake-4.1.0.tgz", - "integrity": "sha512-ZHt2+mOXTvjtaWS2h/JPvQjmknfKrEld2xdSsRYWXnYiJmK/N+dtxrDVSt1cr9wGAlhH7Ek43lIZNsL5bVeX9A==", - "dev": true, "license": "Apache-2.0", "dependencies": { "b4a": "^1.1.0", @@ -7858,9 +8269,6 @@ }, "node_modules/noise-handshake/node_modules/sodium-native": { "version": "5.0.8", - "resolved": "https://registry.npmjs.org/sodium-native/-/sodium-native-5.0.8.tgz", - "integrity": "sha512-2ZxmF9Llvo/3X3NAc8VV6JFoswObg9u27Q8Be4BtCLDiejXuTt6Nm7+iIWUv+WMcs1eJ7YV5U2f4e8LidfIlRQ==", - "dev": true, "license": "MIT", "dependencies": { "require-addon": "^1.1.0", @@ -7872,9 +8280,6 @@ }, "node_modules/noise-handshake/node_modules/sodium-universal": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/sodium-universal/-/sodium-universal-5.0.1.tgz", - "integrity": "sha512-rv+aH+tnKB5H0MAc2UadHShLMslpJsc4wjdnHRtiSIEYpOetCgu8MS4ExQRia+GL/MK3uuCyZPeEsi+J3h+Q+Q==", - "dev": true, "license": "MIT", "dependencies": { "sodium-native": "^5.0.1" @@ -7890,9 +8295,6 @@ }, "node_modules/normalize-path": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -7900,8 +8302,6 @@ }, "node_modules/npm-normalize-package-bin": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-4.0.0.tgz", - "integrity": "sha512-TZKxPvItzai9kN9H/TkmCtx/ZN/hvr3vUycjlfmH0ootY9yFBzNOpiXAdIn1Iteqsvk4lQn6B5PTrt+n6h8k/w==", "dev": true, "license": "ISC", "engines": { @@ -7937,8 +8337,6 @@ }, "node_modules/npm-run-all2/node_modules/ansi-styles": { "version": "6.2.3", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", - "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", "dev": true, "license": "MIT", "engines": { @@ -7950,8 +8348,6 @@ }, "node_modules/npm-run-all2/node_modules/isexe": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", - "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", "dev": true, "license": "ISC", "engines": { @@ -7973,8 +8369,6 @@ }, "node_modules/npm-run-all2/node_modules/which": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", - "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", "dev": true, "license": "ISC", "dependencies": { @@ -7989,8 +8383,6 @@ }, "node_modules/nth-check": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", - "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -8002,8 +8394,6 @@ }, "node_modules/object-keys": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", "dev": true, "license": "MIT", "engines": { @@ -8023,8 +8413,6 @@ }, "node_modules/on-exit-leak-free": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz", - "integrity": "sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==", "dev": true, "license": "MIT", "engines": { @@ -8033,9 +8421,6 @@ }, "node_modules/once": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, "license": "ISC", "dependencies": { "wrappy": "1" @@ -8043,8 +8428,6 @@ }, "node_modules/ono": { "version": "4.0.11", - "resolved": "https://registry.npmjs.org/ono/-/ono-4.0.11.tgz", - "integrity": "sha512-jQ31cORBFE6td25deYeD80wxKBMj+zBmHTrVxnc6CKhx8gho6ipmWM5zj/oeoqioZ99yqBls9Z/9Nss7J26G2g==", "dev": true, "license": "MIT", "dependencies": { @@ -8053,9 +8436,6 @@ }, "node_modules/open": { "version": "10.2.0", - "resolved": "https://registry.npmjs.org/open/-/open-10.2.0.tgz", - "integrity": "sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==", - "dev": true, "license": "MIT", "dependencies": { "default-browser": "^5.2.1", @@ -8072,8 +8452,6 @@ }, "node_modules/optionator": { "version": "0.9.4", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", - "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, "license": "MIT", "dependencies": { @@ -8090,9 +8468,6 @@ }, "node_modules/ora": { "version": "8.2.0", - "resolved": "https://registry.npmjs.org/ora/-/ora-8.2.0.tgz", - "integrity": "sha512-weP+BZ8MVNnlCm8c0Qdc1WSWq4Qn7I+9CJGm7Qali6g44e/PUzbjNqJX5NJ9ljlNMosfJvg1fKEGILklK9cwnw==", - "dev": true, "license": "MIT", "dependencies": { "chalk": "^5.3.0", @@ -8114,9 +8489,6 @@ }, "node_modules/ora/node_modules/chalk": { "version": "5.6.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", - "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", - "dev": true, "license": "MIT", "engines": { "node": "^12.17.0 || ^14.13 || >=16.0.0" @@ -8127,9 +8499,6 @@ }, "node_modules/ora/node_modules/log-symbols": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-6.0.0.tgz", - "integrity": "sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==", - "dev": true, "license": "MIT", "dependencies": { "chalk": "^5.3.0", @@ -8144,9 +8513,6 @@ }, "node_modules/ora/node_modules/log-symbols/node_modules/is-unicode-supported": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", - "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -8157,9 +8523,6 @@ }, "node_modules/os-tmpdir": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -8167,9 +8530,6 @@ }, "node_modules/p-defer": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-4.0.1.tgz", - "integrity": "sha512-Mr5KC5efvAK5VUptYEIopP1bakB85k2IWXaRC0rsh1uwn1L6M0LVml8OIQ4Gudg4oyZakf7FmeRLkMMtZW1i5A==", - "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -8180,9 +8540,6 @@ }, "node_modules/p-event": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/p-event/-/p-event-6.0.1.tgz", - "integrity": "sha512-Q6Bekk5wpzW5qIyUP4gdMEujObYstZl6DMMOSenwBvV0BlE5LkDwkjs5yHbZmdCEq2o4RJx4tE1vwxFVf2FG1w==", - "dev": true, "license": "MIT", "dependencies": { "p-timeout": "^6.1.2" @@ -8196,8 +8553,6 @@ }, "node_modules/p-limit": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, "license": "MIT", "dependencies": { @@ -8212,8 +8567,6 @@ }, "node_modules/p-locate": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, "license": "MIT", "dependencies": { @@ -8226,10 +8579,31 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/p-mutex": { + "version": "0.1.0", + "license": "MIT", + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-mutex/node_modules/yocto-queue": { + "version": "1.2.2", + "license": "MIT", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/p-queue": { "version": "8.1.1", - "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-8.1.1.tgz", - "integrity": "sha512-aNZ+VfjobsWryoiPnEApGGmf5WmNsCo9xu8dfaYamG5qaLP7ClhLN6NgsFe6SwJ2UbLEBK5dv9x8Mn5+RVhMWQ==", "dev": true, "license": "MIT", "dependencies": { @@ -8245,9 +8619,6 @@ }, "node_modules/p-timeout": { "version": "6.1.4", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-6.1.4.tgz", - "integrity": "sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg==", - "dev": true, "license": "MIT", "engines": { "node": ">=14.16" @@ -8258,15 +8629,10 @@ }, "node_modules/package-json-from-dist": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", - "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", - "dev": true, "license": "BlueOak-1.0.0" }, "node_modules/parent-module": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, "license": "MIT", "dependencies": { @@ -8278,8 +8644,6 @@ }, "node_modules/parse-json": { "version": "8.3.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-8.3.0.tgz", - "integrity": "sha512-ybiGyvspI+fAoRQbIPRddCcSTV9/LsJbf0e/S85VLowVGzRmokfneg2kwVW/KU5rOXrPSbF1qAKPMgNTqqROQQ==", "dev": true, "license": "MIT", "dependencies": { @@ -8294,11 +8658,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/parse-json/node_modules/type-fest": { + "version": "4.41.0", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/parse-ms": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-4.0.0.tgz", - "integrity": "sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==", - "dev": true, "license": "MIT", "engines": { "node": ">=18" @@ -8307,10 +8679,30 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/parse5": { + "version": "8.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5/node_modules/entities": { + "version": "6.0.1", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/path-exists": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, "license": "MIT", "engines": { @@ -8319,9 +8711,6 @@ }, "node_modules/path-key": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -8329,9 +8718,6 @@ }, "node_modules/path-scurry": { "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", - "dev": true, "license": "BlueOak-1.0.0", "dependencies": { "lru-cache": "^10.2.0", @@ -8353,15 +8739,11 @@ }, "node_modules/picocolors": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "dev": true, "license": "ISC" }, "node_modules/picomatch": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, "license": "MIT", "engines": { @@ -8373,8 +8755,6 @@ }, "node_modules/pidtree": { "version": "0.6.0", - "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz", - "integrity": "sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==", "dev": true, "license": "MIT", "bin": { @@ -8386,8 +8766,6 @@ }, "node_modules/pino": { "version": "9.10.0", - "resolved": "https://registry.npmjs.org/pino/-/pino-9.10.0.tgz", - "integrity": "sha512-VOFxoNnxICtxaN8S3E73pR66c5MTFC+rwRcNRyHV/bV/c90dXvJqMfjkeRFsGBDXmlUN3LccJQPqGIufnaJePA==", "dev": true, "license": "MIT", "dependencies": { @@ -8409,8 +8787,6 @@ }, "node_modules/pino-abstract-transport": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-2.0.0.tgz", - "integrity": "sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw==", "dev": true, "license": "MIT", "dependencies": { @@ -8419,15 +8795,11 @@ }, "node_modules/pino-std-serializers": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-7.0.0.tgz", - "integrity": "sha512-e906FRY0+tV27iq4juKzSYPbUj2do2X2JX4EzSca1631EB2QJQUqGbDuERal7LCtOpxl6x3+nvo9NPZcmjkiFA==", "dev": true, "license": "MIT" }, "node_modules/pino/node_modules/process-warning": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-5.0.0.tgz", - "integrity": "sha512-a39t9ApHNx2L4+HBnQKqxxHNs1r7KF+Intd8Q/g1bUh6q0WIp9voPXJ/x0j+ZL45KF1pJd9+q2jLIRMfvEshkA==", "dev": true, "funding": [ { @@ -8443,8 +8815,6 @@ }, "node_modules/polite-json": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/polite-json/-/polite-json-5.0.0.tgz", - "integrity": "sha512-OLS/0XeUAcE8a2fdwemNja+udKgXNnY6yKVIXqAD2zVRx1KvY6Ato/rZ2vdzbxqYwPW0u6SCNC/bAMPNzpzxbw==", "dev": true, "license": "MIT", "engines": { @@ -8485,9 +8855,6 @@ }, "node_modules/prebuild-install": { "version": "7.1.3", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz", - "integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==", - "dev": true, "license": "MIT", "dependencies": { "detect-libc": "^2.0.0", @@ -8512,8 +8879,6 @@ }, "node_modules/prelude-ls": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, "license": "MIT", "engines": { @@ -8526,6 +8891,7 @@ "integrity": "sha512-v6UNi1+3hSlVvv8fSaoUbggEM5VErKmmpGA7Pl3HF8V6uKY7rvClBOJlH6yNwQtfTueNkGVpOv/mtWL9L4bgRA==", "dev": true, "license": "MIT", + "peer": true, "bin": { "prettier": "bin/prettier.cjs" }, @@ -8538,9 +8904,6 @@ }, "node_modules/pretty-bytes": { "version": "6.1.1", - "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-6.1.1.tgz", - "integrity": "sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==", - "dev": true, "license": "MIT", "engines": { "node": "^14.13.1 || >=16.0.0" @@ -8551,8 +8914,6 @@ }, "node_modules/pretty-format": { "version": "27.5.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", - "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", "dev": true, "license": "MIT", "dependencies": { @@ -8566,8 +8927,6 @@ }, "node_modules/pretty-format/node_modules/ansi-styles": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, "license": "MIT", "engines": { @@ -8579,9 +8938,6 @@ }, "node_modules/pretty-ms": { "version": "9.3.0", - "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.3.0.tgz", - "integrity": "sha512-gjVS5hOP+M3wMm5nmNOucbIrqudzs9v/57bWRHQWLYklXqoXKrVfYW2W9+glfGsqtPgpiz5WwyEEB+ksXIx3gQ==", - "dev": true, "license": "MIT", "dependencies": { "parse-ms": "^4.0.0" @@ -8595,9 +8951,6 @@ }, "node_modules/process": { "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.6.0" @@ -8605,22 +8958,15 @@ }, "node_modules/process-nextick-args": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true, "license": "MIT" }, "node_modules/process-warning": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-3.0.0.tgz", - "integrity": "sha512-mqn0kFRl0EoqhnL0GQ0veqFHyIN1yig9RHh/InzORTUiZHFRAur+aMtRkELNwGs9aNwKS6tg/An4NYBPGwvtzQ==", "dev": true, "license": "MIT" }, "node_modules/protobufjs": { "version": "7.5.4", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.4.tgz", - "integrity": "sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg==", "dev": true, "hasInstallScript": true, "license": "BSD-3-Clause", @@ -8644,8 +8990,6 @@ }, "node_modules/protocol-buffers-encodings": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/protocol-buffers-encodings/-/protocol-buffers-encodings-1.2.0.tgz", - "integrity": "sha512-daeNPuKh1NlLD1uDfbLpD+xyUTc07nEtfHwmBZmt/vH0B7VOM+JOCOpDcx9ZRpqHjAiIkGqyTDi+wfGSl17R9w==", "dev": true, "license": "MIT", "dependencies": { @@ -8656,15 +9000,11 @@ }, "node_modules/protocol-buffers-encodings/node_modules/varint": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/varint/-/varint-5.0.0.tgz", - "integrity": "sha512-gC13b/bWrqQoKY2EmROCZ+AR0jitc6DnDGaQ6Ls9QpKmuSgJB1eQ7H3KETtQm7qSdMWMKCmsshyCmUwMLh3OAA==", "dev": true, "license": "MIT" }, "node_modules/protomux": { "version": "3.10.1", - "resolved": "https://registry.npmjs.org/protomux/-/protomux-3.10.1.tgz", - "integrity": "sha512-jgBqx8ZyaBWea/DFG4eOu1scOaeBwcnagiRC1XFVrjeGt7oAb0Pk5udPpBUpJ4DJBRjra50jD6YcZiQQTRqaaA==", "dev": true, "license": "MIT", "dependencies": { @@ -8677,8 +9017,6 @@ }, "node_modules/proxy-addr": { "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", "dev": true, "license": "MIT", "dependencies": { @@ -8691,9 +9029,6 @@ }, "node_modules/pump": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz", - "integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==", - "dev": true, "license": "MIT", "dependencies": { "end-of-stream": "^1.1.0", @@ -8702,8 +9037,6 @@ }, "node_modules/punycode": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, "license": "MIT", "engines": { @@ -8712,22 +9045,16 @@ }, "node_modules/queue-tick": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", - "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==", "dev": true, "license": "MIT" }, "node_modules/quick-format-unescaped": { "version": "4.0.4", - "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz", - "integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==", "dev": true, "license": "MIT" }, "node_modules/quickbit-native": { "version": "2.4.8", - "resolved": "https://registry.npmjs.org/quickbit-native/-/quickbit-native-2.4.8.tgz", - "integrity": "sha512-FcCcqI+nIAWGknqhtrYT5TSD7t/N+Xd8ctM+2PrIIBuwOi5hx0SxAvuPtzLIEMfT/2h9+fhBakUe2uALOHX6yw==", "dev": true, "license": "Apache-2.0", "optional": true, @@ -8737,8 +9064,6 @@ }, "node_modules/quickbit-universal": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/quickbit-universal/-/quickbit-universal-2.2.0.tgz", - "integrity": "sha512-w02i1R8n7+6pEKTud8DfF8zbFY9o7RtPlUc3jWbtCkDKvhbx/AvV7oNnz4/TcmsPGpSJS+fq5Ud6RH6+YPvSGg==", "dev": true, "license": "ISC", "dependencies": { @@ -8751,22 +9076,15 @@ }, "node_modules/quickselect": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/quickselect/-/quickselect-2.0.0.tgz", - "integrity": "sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw==", - "dev": true, "license": "ISC" }, "node_modules/rache": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/rache/-/rache-1.0.0.tgz", - "integrity": "sha512-e0k0g0w/8jOCB+7YqCIlOa+OJ38k0wrYS4x18pMSmqOvLKoyhmMhmQyCcvfY6VaP8D75cqkEnlakXs+RYYLqNg==", "dev": true, "license": "Apache-2.0" }, "node_modules/random-access-file": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/random-access-file/-/random-access-file-4.1.2.tgz", - "integrity": "sha512-GQM6R78DceZDcQod8KxlDFwXIiUvlvuy1EOzxTDsjuDjW5NlnlZi0MOk6iI4itAj/2vcvdqcEExYbVpC/dJcEw==", "dev": true, "license": "MIT", "dependencies": { @@ -8780,8 +9098,6 @@ }, "node_modules/random-access-memory": { "version": "6.2.1", - "resolved": "https://registry.npmjs.org/random-access-memory/-/random-access-memory-6.2.1.tgz", - "integrity": "sha512-hUeu1PbGLmWeyze9LwwSNaqloivNYjFsARIYxRdgUgn0wrdvMG+RszrfTG8814zfcXOgy4pFO2TpX/Cl3hRO4w==", "dev": true, "license": "MIT", "dependencies": { @@ -8792,8 +9108,6 @@ }, "node_modules/random-access-storage": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/random-access-storage/-/random-access-storage-3.0.2.tgz", - "integrity": "sha512-Es9maUyWdJXWKckKy9s1+vT+DEgAt+PBb9lxPaake/0EDUsHehloKGv9v1zimS2V3gpFAcQXubvc1Rgci2sDPQ==", "dev": true, "license": "MIT", "dependencies": { @@ -8803,16 +9117,11 @@ }, "node_modules/random-array-iterator": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/random-array-iterator/-/random-array-iterator-1.0.0.tgz", - "integrity": "sha512-u7xCM93XqKEvPTP6xZp2ehttcAemKnh73oKNf1FvzuVCfpt6dILDt1Kxl1LeBjm2iNIeR49VGFhy4Iz3yOun+Q==", "dev": true, "license": "MIT" }, "node_modules/rc": { "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", "dependencies": { "deep-extend": "^0.6.0", @@ -8826,9 +9135,6 @@ }, "node_modules/rc/node_modules/strip-json-comments": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -8840,6 +9146,7 @@ "integrity": "sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=0.10.0" } @@ -8850,6 +9157,7 @@ "integrity": "sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "scheduler": "^0.27.0" }, @@ -8859,15 +9167,11 @@ }, "node_modules/react-is": { "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true, "license": "MIT" }, "node_modules/read-package-json-fast": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/read-package-json-fast/-/read-package-json-fast-4.0.0.tgz", - "integrity": "sha512-qpt8EwugBWDw2cgE2W+/3oxC+KTez2uSVR8JU9Q36TXPAGCaozfQUs59v4j4GFpWTaw0i6hAZSvOmu1J0uOEUg==", "dev": true, "license": "ISC", "dependencies": { @@ -8880,16 +9184,11 @@ }, "node_modules/read-write-mutexify": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/read-write-mutexify/-/read-write-mutexify-2.1.0.tgz", - "integrity": "sha512-fDw/p5/acI1ytVY1UbxEDma/ej1yJH/n9NcjS9YNzcE6sPBPWdlru3ydRa/UBowUg4zqOvNMD5SOGYJrlQ6MzQ==", "dev": true, "license": "MIT" }, "node_modules/readable-stream": { "version": "4.7.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz", - "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==", - "dev": true, "license": "MIT", "dependencies": { "abort-controller": "^3.0.0", @@ -8904,9 +9203,6 @@ }, "node_modules/readable-stream/node_modules/buffer": { "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "dev": true, "funding": [ { "type": "github", @@ -8929,9 +9225,6 @@ }, "node_modules/readdir-glob": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.3.tgz", - "integrity": "sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==", - "dev": true, "license": "Apache-2.0", "dependencies": { "minimatch": "^5.1.0" @@ -8939,9 +9232,6 @@ }, "node_modules/readdir-glob/node_modules/minimatch": { "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" @@ -8966,8 +9256,6 @@ }, "node_modules/ready-resource": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/ready-resource/-/ready-resource-1.2.0.tgz", - "integrity": "sha512-nfcco/8iAFV0M+2PYnmIc+/xY0iRb35d42HFHQ7AfjulbGEAFa+XWpByfwSyeVeiBoMLLFVMv1HixxNCqzSQ1g==", "dev": true, "license": "MIT", "dependencies": { @@ -8976,8 +9264,6 @@ }, "node_modules/real-require": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz", - "integrity": "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==", "dev": true, "license": "MIT", "engines": { @@ -8986,9 +9272,6 @@ }, "node_modules/require-addon": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/require-addon/-/require-addon-1.1.0.tgz", - "integrity": "sha512-KbXAD5q2+v1GJnkzd8zzbOxchTkStSyJZ9QwoCq3QwEXAaIlG3wDYRZGzVD357jmwaGY7hr5VaoEAL0BkF0Kvg==", - "dev": true, "license": "Apache-2.0", "dependencies": { "bare-addon-resolve": "^1.3.0", @@ -9000,8 +9283,6 @@ }, "node_modules/require-from-string": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "dev": true, "license": "MIT", "engines": { @@ -9010,8 +9291,6 @@ }, "node_modules/resolve-from": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, "license": "MIT", "engines": { @@ -9020,8 +9299,6 @@ }, "node_modules/resolve-import": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/resolve-import/-/resolve-import-2.0.0.tgz", - "integrity": "sha512-jpKjLibLuc8D1XEV2+7zb0aqN7I8d12u89g/v6IsgCzdVlccMQJq4TKkPw5fbhHdxhm7nbVtN+KvOTnjFf+nEA==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { @@ -9037,8 +9314,6 @@ }, "node_modules/resolve-import/node_modules/glob": { "version": "11.0.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.3.tgz", - "integrity": "sha512-2Nim7dha1KVkaiF4q6Dj+ngPPMdfvLJEOpZk/jKiUAkqKebpGAWQXAq9z1xu9HKu5lWfqw/FASuccEjyznjPaA==", "dev": true, "license": "ISC", "dependencies": { @@ -9061,8 +9336,6 @@ }, "node_modules/resolve-import/node_modules/jackspeak": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.1.1.tgz", - "integrity": "sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { @@ -9077,8 +9350,6 @@ }, "node_modules/resolve-import/node_modules/lru-cache": { "version": "11.2.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.1.tgz", - "integrity": "sha512-r8LA6i4LP4EeWOhqBaZZjDWwehd1xUJPCJd9Sv300H0ZmcUER4+JPh7bqqZeqs1o5pgtgvXm+d9UGrB5zZGDiQ==", "dev": true, "license": "ISC", "engines": { @@ -9087,8 +9358,6 @@ }, "node_modules/resolve-import/node_modules/minimatch": { "version": "10.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.3.tgz", - "integrity": "sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==", "dev": true, "license": "ISC", "dependencies": { @@ -9103,8 +9372,6 @@ }, "node_modules/resolve-import/node_modules/path-scurry": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.0.tgz", - "integrity": "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { @@ -9120,16 +9387,11 @@ }, "node_modules/resolve-reject-promise": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/resolve-reject-promise/-/resolve-reject-promise-1.1.0.tgz", - "integrity": "sha512-LWsTOA91AqzBTjSGgX79Tc130pwcBK6xjpJEO+qRT5IKZ6bGnHKcc8QL3upUBcWuU8OTIDzKK2VNSwmmlqvAVg==", "dev": true, "license": "MIT" }, "node_modules/restore-cursor": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", - "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", - "dev": true, "license": "MIT", "dependencies": { "onetime": "^7.0.0", @@ -9144,9 +9406,6 @@ }, "node_modules/restore-cursor/node_modules/onetime": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", - "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", - "dev": true, "license": "MIT", "dependencies": { "mimic-function": "^5.0.0" @@ -9160,8 +9419,6 @@ }, "node_modules/ret": { "version": "0.4.3", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.4.3.tgz", - "integrity": "sha512-0f4Memo5QP7WQyUEAYUO3esD/XjOc3Zjjg5CPsAq1p8sIu0XPeMbHJemKA0BO7tV0X7+A0FoEpbmHXWxPyD3wQ==", "dev": true, "license": "MIT", "engines": { @@ -9170,8 +9427,6 @@ }, "node_modules/reusify": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", - "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", "dev": true, "license": "MIT", "engines": { @@ -9181,15 +9436,11 @@ }, "node_modules/rfdc": { "version": "1.4.1", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", - "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", "dev": true, "license": "MIT" }, "node_modules/rimraf": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.0.1.tgz", - "integrity": "sha512-9dkvaxAsk/xNXSJzMgFqqMCuFgt2+KsOFek3TMLfo8NCPfWpBmqwyNn5Y+NX56QUYfCtsyhF3ayiboEoUmJk/A==", "dev": true, "license": "ISC", "dependencies": { @@ -9208,8 +9459,6 @@ }, "node_modules/rimraf/node_modules/glob": { "version": "11.0.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.3.tgz", - "integrity": "sha512-2Nim7dha1KVkaiF4q6Dj+ngPPMdfvLJEOpZk/jKiUAkqKebpGAWQXAq9z1xu9HKu5lWfqw/FASuccEjyznjPaA==", "dev": true, "license": "ISC", "dependencies": { @@ -9232,8 +9481,6 @@ }, "node_modules/rimraf/node_modules/jackspeak": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.1.1.tgz", - "integrity": "sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { @@ -9248,8 +9495,6 @@ }, "node_modules/rimraf/node_modules/lru-cache": { "version": "11.2.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.1.tgz", - "integrity": "sha512-r8LA6i4LP4EeWOhqBaZZjDWwehd1xUJPCJd9Sv300H0ZmcUER4+JPh7bqqZeqs1o5pgtgvXm+d9UGrB5zZGDiQ==", "dev": true, "license": "ISC", "engines": { @@ -9258,8 +9503,6 @@ }, "node_modules/rimraf/node_modules/minimatch": { "version": "10.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.3.tgz", - "integrity": "sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==", "dev": true, "license": "ISC", "dependencies": { @@ -9274,8 +9517,6 @@ }, "node_modules/rimraf/node_modules/path-scurry": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.0.tgz", - "integrity": "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { @@ -9290,9 +9531,9 @@ } }, "node_modules/rollup": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.53.3.tgz", - "integrity": "sha512-w8GmOxZfBmKknvdXU1sdM9NHcoQejwF/4mNgj2JuEEdRaHwwF12K7e9eXn1nLZ07ad+du76mkVsyeb2rKGllsA==", + "version": "4.57.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.57.1.tgz", + "integrity": "sha512-oQL6lgK3e2QZeQ7gcgIkS2YZPg5slw37hYufJ3edKlfQSGGm8ICoxswK15ntSzF/a8+h7ekRy7k7oWc3BQ7y8A==", "dev": true, "license": "MIT", "dependencies": { @@ -9306,35 +9547,36 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.53.3", - "@rollup/rollup-android-arm64": "4.53.3", - "@rollup/rollup-darwin-arm64": "4.53.3", - "@rollup/rollup-darwin-x64": "4.53.3", - "@rollup/rollup-freebsd-arm64": "4.53.3", - "@rollup/rollup-freebsd-x64": "4.53.3", - "@rollup/rollup-linux-arm-gnueabihf": "4.53.3", - "@rollup/rollup-linux-arm-musleabihf": "4.53.3", - "@rollup/rollup-linux-arm64-gnu": "4.53.3", - "@rollup/rollup-linux-arm64-musl": "4.53.3", - "@rollup/rollup-linux-loong64-gnu": "4.53.3", - "@rollup/rollup-linux-ppc64-gnu": "4.53.3", - "@rollup/rollup-linux-riscv64-gnu": "4.53.3", - "@rollup/rollup-linux-riscv64-musl": "4.53.3", - "@rollup/rollup-linux-s390x-gnu": "4.53.3", - "@rollup/rollup-linux-x64-gnu": "4.53.3", - "@rollup/rollup-linux-x64-musl": "4.53.3", - "@rollup/rollup-openharmony-arm64": "4.53.3", - "@rollup/rollup-win32-arm64-msvc": "4.53.3", - "@rollup/rollup-win32-ia32-msvc": "4.53.3", - "@rollup/rollup-win32-x64-gnu": "4.53.3", - "@rollup/rollup-win32-x64-msvc": "4.53.3", + "@rollup/rollup-android-arm-eabi": "4.57.1", + "@rollup/rollup-android-arm64": "4.57.1", + "@rollup/rollup-darwin-arm64": "4.57.1", + "@rollup/rollup-darwin-x64": "4.57.1", + "@rollup/rollup-freebsd-arm64": "4.57.1", + "@rollup/rollup-freebsd-x64": "4.57.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.57.1", + "@rollup/rollup-linux-arm-musleabihf": "4.57.1", + "@rollup/rollup-linux-arm64-gnu": "4.57.1", + "@rollup/rollup-linux-arm64-musl": "4.57.1", + "@rollup/rollup-linux-loong64-gnu": "4.57.1", + "@rollup/rollup-linux-loong64-musl": "4.57.1", + "@rollup/rollup-linux-ppc64-gnu": "4.57.1", + "@rollup/rollup-linux-ppc64-musl": "4.57.1", + "@rollup/rollup-linux-riscv64-gnu": "4.57.1", + "@rollup/rollup-linux-riscv64-musl": "4.57.1", + "@rollup/rollup-linux-s390x-gnu": "4.57.1", + "@rollup/rollup-linux-x64-gnu": "4.57.1", + "@rollup/rollup-linux-x64-musl": "4.57.1", + "@rollup/rollup-openbsd-x64": "4.57.1", + "@rollup/rollup-openharmony-arm64": "4.57.1", + "@rollup/rollup-win32-arm64-msvc": "4.57.1", + "@rollup/rollup-win32-ia32-msvc": "4.57.1", + "@rollup/rollup-win32-x64-gnu": "4.57.1", + "@rollup/rollup-win32-x64-msvc": "4.57.1", "fsevents": "~2.3.2" } }, "node_modules/rpc-reflector": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/rpc-reflector/-/rpc-reflector-3.0.1.tgz", - "integrity": "sha512-yUcgwFwrEWMgMgCjLUJwRYGT9KuIYyBb1KI7kqfxC83Y0oXNVwxTKIT3YrkPjuGm72YpU8o3Nj2nI7YFOaI3mQ==", "dev": true, "license": "ISC", "dependencies": { @@ -9352,22 +9594,18 @@ }, "node_modules/rpc-reflector/node_modules/@types/node": { "version": "18.19.127", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.127.tgz", - "integrity": "sha512-gSjxjrnKXML/yo0BO099uPixMqfpJU0TKYjpfLU7TrtA2WWDki412Np/RSTPRil1saKBhvVVKzVx/p/6p94nVA==", "dev": true, "license": "MIT", "dependencies": { "undici-types": "~5.26.4" } - }, - "node_modules/rpc-reflector/node_modules/is-stream": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", - "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==", + }, + "node_modules/rpc-reflector/node_modules/ensure-error": { + "version": "4.0.0", "dev": true, "license": "MIT", "engines": { - "node": ">=18" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -9375,16 +9613,11 @@ }, "node_modules/rpc-reflector/node_modules/undici-types": { "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", "dev": true, "license": "MIT" }, "node_modules/run-applescript": { "version": "7.1.0", - "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.1.0.tgz", - "integrity": "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==", - "dev": true, "license": "MIT", "engines": { "node": ">=18" @@ -9393,18 +9626,48 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/run-time-assertions": { + "version": "1.5.2", + "license": "(MIT or CC0 1.0)", + "dependencies": { + "@augment-vir/common": "^29.3.0", + "expect-type": "~0.15.0", + "type-fest": "^4.22.0" + } + }, + "node_modules/run-time-assertions/node_modules/@augment-vir/common": { + "version": "29.3.0", + "license": "MIT", + "dependencies": { + "browser-or-node": "^3.0.0", + "run-time-assertions": "^1.5.1", + "type-fest": "^4.21.0" + } + }, + "node_modules/run-time-assertions/node_modules/browser-or-node": { + "version": "3.0.0", + "license": "MIT" + }, + "node_modules/run-time-assertions/node_modules/expect-type": { + "version": "0.15.0", + "license": "Apache-2.0" + }, + "node_modules/run-time-assertions/node_modules/type-fest": { + "version": "4.41.0", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/rw": { "version": "1.3.3", - "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", - "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==", - "dev": true, "license": "BSD-3-Clause" }, "node_modules/safe-buffer": { "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, "funding": [ { "type": "github", @@ -9423,8 +9686,6 @@ }, "node_modules/safe-regex2": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/safe-regex2/-/safe-regex2-3.1.0.tgz", - "integrity": "sha512-RAAZAGbap2kBfbVhvmnTFv73NWLMvDGOITFYTZBAaY8eR+Ir4ef7Up/e7amo+y1+AH+3PtLkrt9mvcTsG9LXug==", "dev": true, "license": "MIT", "dependencies": { @@ -9433,8 +9694,6 @@ }, "node_modules/safe-stable-stringify": { "version": "2.5.0", - "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz", - "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==", "dev": true, "license": "MIT", "engines": { @@ -9443,32 +9702,34 @@ }, "node_modules/safer-buffer": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true, "license": "MIT" }, "node_modules/safety-catch": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/safety-catch/-/safety-catch-1.0.2.tgz", - "integrity": "sha512-C1UYVZ4dtbBxEtvOcpjBaaD27nP8MlvyAQEp2fOTOEe6pfUpk1cDUxij6BR1jZup6rSyUTaBBplK7LanskrULA==", "dev": true, "license": "MIT" }, "node_modules/same-data": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/same-data/-/same-data-1.0.0.tgz", - "integrity": "sha512-Eqn7N2yV+aKMlUHTRqUwYG1Iv0cJqjlvLKj/GoP5PozJn361QaOYX14+v87r7NqQUZC22noP/LfLrSQiPwAygw==", "dev": true, "license": "MIT" }, "node_modules/sax": { "version": "1.4.1", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", - "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==", "dev": true, "license": "ISC" }, + "node_modules/saxes": { + "version": "6.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=v12.22.7" + } + }, "node_modules/scheduler": { "version": "0.27.0", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", @@ -9476,18 +9737,24 @@ "dev": true, "license": "MIT" }, + "node_modules/secret-stream-http": { + "version": "1.0.1", + "license": "MIT", + "dependencies": { + "@hyperswarm/secret-stream": "^6.8.1", + "streamx": "^2.22.1", + "undici": "^6.21.3" + } + }, "node_modules/secure-json-parse": { "version": "2.7.0", - "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.7.0.tgz", - "integrity": "sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==", "dev": true, "license": "BSD-3-Clause" }, "node_modules/semver": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", - "dev": true, + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -9498,8 +9765,6 @@ }, "node_modules/serialize-error": { "version": "12.0.0", - "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-12.0.0.tgz", - "integrity": "sha512-ZYkZLAvKTKQXWuh5XpBw7CdbSzagarX39WyZ2H07CDLC5/KfsRGlIXV8d4+tfqX1M7916mRqR1QfNHSij+c9Pw==", "dev": true, "license": "MIT", "dependencies": { @@ -9512,17 +9777,24 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/serialize-error/node_modules/type-fest": { + "version": "4.41.0", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/set-cookie-parser": { "version": "2.7.1", - "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz", - "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==", "dev": true, "license": "MIT" }, "node_modules/set-function-length": { "version": "1.2.2", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", - "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", "dev": true, "license": "MIT", "dependencies": { @@ -9539,16 +9811,11 @@ }, "node_modules/setprototypeof": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", "dev": true, "license": "ISC" }, "node_modules/shebang-command": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" @@ -9559,9 +9826,6 @@ }, "node_modules/shebang-regex": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -9569,8 +9833,6 @@ }, "node_modules/shell-quote": { "version": "1.8.3", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz", - "integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==", "dev": true, "license": "MIT", "engines": { @@ -9582,16 +9844,11 @@ }, "node_modules/siginfo": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", - "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", "dev": true, "license": "ISC" }, "node_modules/signal-exit": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, "license": "ISC", "engines": { "node": ">=14" @@ -9602,8 +9859,6 @@ }, "node_modules/signed-varint": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/signed-varint/-/signed-varint-2.0.1.tgz", - "integrity": "sha512-abgDPg1106vuZZOvw7cFwdCABddfJRz5akcCcchzTbhyhYnsG31y4AlZEgp315T7W3nQq5P4xeOm186ZiPVFzw==", "dev": true, "license": "MIT", "dependencies": { @@ -9612,15 +9867,11 @@ }, "node_modules/signed-varint/node_modules/varint": { "version": "5.0.2", - "resolved": "https://registry.npmjs.org/varint/-/varint-5.0.2.tgz", - "integrity": "sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow==", "dev": true, "license": "MIT" }, "node_modules/simdle-native": { "version": "1.3.7", - "resolved": "https://registry.npmjs.org/simdle-native/-/simdle-native-1.3.7.tgz", - "integrity": "sha512-O3+kYD48jByt/IY/WEpdZshtRbAcotOmDMhs2PrW2MVpgRVoCuTGLtNJO5LjZNYzh7qLIhTScpa16FJWHaSScQ==", "dev": true, "license": "Apache-2.0", "optional": true, @@ -9631,8 +9882,6 @@ }, "node_modules/simdle-universal": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/simdle-universal/-/simdle-universal-1.1.2.tgz", - "integrity": "sha512-3n3w1bs+uwgHKQjt6arez83EywNlhZzYvNOhvAASTl/8KqNIcqr6aHyGt3JRlfuUC7iB0tomJRPlJ2cRGIpBzA==", "dev": true, "license": "ISC", "dependencies": { @@ -9644,9 +9893,6 @@ }, "node_modules/simple-concat": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", - "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", - "dev": true, "funding": [ { "type": "github", @@ -9665,9 +9911,6 @@ }, "node_modules/simple-get": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", - "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", - "dev": true, "funding": [ { "type": "github", @@ -9691,8 +9934,6 @@ }, "node_modules/simple-invariant": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/simple-invariant/-/simple-invariant-2.0.1.tgz", - "integrity": "sha512-1sbhsxqI+I2tqlmjbz99GXNmZtr6tKIyEgGGnJw/MKGblalqk/XoOYYFJlBzTKZCxx8kLaD3FD5s9BEEjx5Pyg==", "dev": true, "license": "MIT", "engines": { @@ -9731,9 +9972,6 @@ }, "node_modules/sodium-native": { "version": "4.3.3", - "resolved": "https://registry.npmjs.org/sodium-native/-/sodium-native-4.3.3.tgz", - "integrity": "sha512-OnxSlN3uyY8D0EsLHpmm2HOFmKddQVvEMmsakCrXUzSd8kjjbzL413t4ZNF3n0UxSwNgwTyUvkmZHTfuCeiYSw==", - "dev": true, "license": "MIT", "dependencies": { "require-addon": "^1.1.0" @@ -9741,9 +9979,6 @@ }, "node_modules/sodium-secretstream": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/sodium-secretstream/-/sodium-secretstream-1.2.0.tgz", - "integrity": "sha512-q/DbraNFXm1KfCiiZvapmz5UC3OlpirYFIvBK2MhGaOFSb3gRyk8OXTi17UI9SGfshQNCpsVvlopogbzZNyW6Q==", - "dev": true, "license": "MIT", "dependencies": { "b4a": "^1.1.1", @@ -9752,9 +9987,6 @@ }, "node_modules/sodium-secretstream/node_modules/sodium-native": { "version": "5.0.8", - "resolved": "https://registry.npmjs.org/sodium-native/-/sodium-native-5.0.8.tgz", - "integrity": "sha512-2ZxmF9Llvo/3X3NAc8VV6JFoswObg9u27Q8Be4BtCLDiejXuTt6Nm7+iIWUv+WMcs1eJ7YV5U2f4e8LidfIlRQ==", - "dev": true, "license": "MIT", "dependencies": { "require-addon": "^1.1.0", @@ -9766,9 +9998,6 @@ }, "node_modules/sodium-secretstream/node_modules/sodium-universal": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/sodium-universal/-/sodium-universal-5.0.1.tgz", - "integrity": "sha512-rv+aH+tnKB5H0MAc2UadHShLMslpJsc4wjdnHRtiSIEYpOetCgu8MS4ExQRia+GL/MK3uuCyZPeEsi+J3h+Q+Q==", - "dev": true, "license": "MIT", "dependencies": { "sodium-native": "^5.0.1" @@ -9784,9 +10013,6 @@ }, "node_modules/sodium-universal": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/sodium-universal/-/sodium-universal-4.0.1.tgz", - "integrity": "sha512-sNp13PrxYLaUFHTGoDKkSDFvoEu51bfzE12RwGlqU1fcrkpAOK0NvizaJzOWV0Omtk9me2+Pnbjcf/l0efxuGQ==", - "dev": true, "license": "MIT", "dependencies": { "sodium-native": "^4.0.0" @@ -9802,8 +10028,6 @@ }, "node_modules/sonic-boom": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-4.2.0.tgz", - "integrity": "sha512-INb7TM37/mAcsGmc9hyyI6+QR3rR1zVRu36B0NeGXKnOOLiZOfER5SA+N7X7k3yUYRzLWafduTDvJAfDswwEww==", "dev": true, "license": "MIT", "dependencies": { @@ -9812,18 +10036,37 @@ }, "node_modules/source-map-js": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", - "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/split2": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", - "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", "dev": true, "license": "ISC", "engines": { @@ -9832,22 +10075,16 @@ }, "node_modules/sprintf-js": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true, "license": "BSD-3-Clause" }, "node_modules/stackback": { "version": "0.0.2", - "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", - "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", "dev": true, "license": "MIT" }, "node_modules/start-stop-state-machine": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/start-stop-state-machine/-/start-stop-state-machine-1.2.0.tgz", - "integrity": "sha512-U9OtWHh+YKPqXHPZc5Ziz5+P/bdKFq14Lz8GnsPXyxNN6RC18nvJ0QAey5FfDpW9DDSaakByrQ4VcnPYm4a+YA==", "dev": true, "license": "MIT", "dependencies": { @@ -9856,8 +10093,6 @@ }, "node_modules/statuses": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", "dev": true, "license": "MIT", "engines": { @@ -9873,9 +10108,6 @@ }, "node_modules/stdin-discarder": { "version": "0.2.2", - "resolved": "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.2.2.tgz", - "integrity": "sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=18" @@ -9886,9 +10118,6 @@ }, "node_modules/streamx": { "version": "2.22.1", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.22.1.tgz", - "integrity": "sha512-znKXEBxfatz2GBNK02kRnCXjV+AA4kjZIUxeWSr3UGirZMJfTE9uiwKHobnbgxWyL/JWro8tTq+vOqAK1/qbSA==", - "dev": true, "license": "MIT", "dependencies": { "fast-fifo": "^1.3.2", @@ -9900,9 +10129,6 @@ }, "node_modules/string_decoder": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, "license": "MIT", "dependencies": { "safe-buffer": "~5.2.0" @@ -9910,8 +10136,6 @@ }, "node_modules/string-argv": { "version": "0.3.2", - "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", - "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", "dev": true, "license": "MIT", "engines": { @@ -9920,8 +10144,6 @@ }, "node_modules/string-timing-safe-equal": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/string-timing-safe-equal/-/string-timing-safe-equal-0.1.0.tgz", - "integrity": "sha512-AMhfQVC+que87xh7nAW2ShSDK6E3CYFC3zGieewF7OHBW9vGPCatMuVPzZ9afoIOT5q6ldKPOKeuQf9hVZlvhw==", "dev": true, "license": "Unlicense", "engines": { @@ -9930,9 +10152,6 @@ }, "node_modules/string-width": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", - "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", - "dev": true, "license": "MIT", "dependencies": { "emoji-regex": "^10.3.0", @@ -9949,9 +10168,6 @@ "node_modules/string-width-cjs": { "name": "string-width", "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", @@ -9964,16 +10180,10 @@ }, "node_modules/string-width-cjs/node_modules/emoji-regex": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, "license": "MIT" }, "node_modules/string-width-cjs/node_modules/is-fullwidth-code-point": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -9981,9 +10191,6 @@ }, "node_modules/string-width-cjs/node_modules/strip-ansi": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" @@ -9994,9 +10201,6 @@ }, "node_modules/strip-ansi": { "version": "7.1.2", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", - "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", - "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" @@ -10011,9 +10215,6 @@ "node_modules/strip-ansi-cjs": { "name": "strip-ansi", "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" @@ -10024,9 +10225,6 @@ }, "node_modules/strip-ansi/node_modules/ansi-regex": { "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", - "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", - "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -10037,8 +10235,6 @@ }, "node_modules/strip-json-comments": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, "license": "MIT", "engines": { @@ -10050,8 +10246,6 @@ }, "node_modules/styled-map-package": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/styled-map-package/-/styled-map-package-3.0.0.tgz", - "integrity": "sha512-loV0X8heQHZozqGidcZGCd9JSSpL0aCqI03r0JhS/tFlSTQtaSV4/88J/MNha84ZUtj7T8PBvIKMD7BO+UeuRw==", "dev": true, "license": "MIT", "dependencies": { @@ -10095,8 +10289,6 @@ }, "node_modules/styled-map-package/node_modules/@commander-js/extra-typings": { "version": "12.1.0", - "resolved": "https://registry.npmjs.org/@commander-js/extra-typings/-/extra-typings-12.1.0.tgz", - "integrity": "sha512-wf/lwQvWAA0goIghcb91dQYpkLBcyhOhQNqG/VgWhnKzgt+UOMvra7EX/2fv70arm5RW+PUHoQHHDa6/p77Eqg==", "dev": true, "license": "MIT", "peerDependencies": { @@ -10105,8 +10297,6 @@ }, "node_modules/styled-map-package/node_modules/chalk": { "version": "5.6.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", - "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", "dev": true, "license": "MIT", "engines": { @@ -10118,31 +10308,15 @@ }, "node_modules/styled-map-package/node_modules/commander": { "version": "12.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", - "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "node_modules/styled-map-package/node_modules/is-stream": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", - "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/styled-map-package/node_modules/p-limit": { "version": "6.2.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-6.2.0.tgz", - "integrity": "sha512-kuUqqHNUqoIWp/c467RI4X6mmyuojY5jGutNU0wVTmEOOfcuwLqyMVoAi9MKi2Ak+5i9+nhmrK4ufZE8069kHA==", "dev": true, "license": "MIT", "dependencies": { @@ -10157,8 +10331,6 @@ }, "node_modules/styled-map-package/node_modules/yocto-queue": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.1.tgz", - "integrity": "sha512-AyeEbWOu/TAXdxlV9wmGcR0+yh2j3vYPGOECcIj2S7MkrLyC7ne+oye2BKTItt0ii2PHk4cDy+95+LshzbXnGg==", "dev": true, "license": "MIT", "engines": { @@ -10170,8 +10342,6 @@ }, "node_modules/sub-encoder": { "version": "2.1.3", - "resolved": "https://registry.npmjs.org/sub-encoder/-/sub-encoder-2.1.3.tgz", - "integrity": "sha512-Xxx04ygZo/1J3yHvaSA6VhDmiSaBQkw/PmO3YnnYFXle+tfOGToC6FcDpIfMztWZXJzuKG14b/57HMkiL58C6A==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -10181,8 +10351,6 @@ }, "node_modules/supports-color": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "license": "MIT", "dependencies": { @@ -10194,8 +10362,6 @@ }, "node_modules/svgo": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-4.0.0.tgz", - "integrity": "sha512-VvrHQ+9uniE+Mvx3+C9IEe/lWasXCU0nXMY2kZeLrHNICuRiC8uMPyM14UEaMOFA5mhyQqEkB02VoQ16n3DLaw==", "dev": true, "license": "MIT", "dependencies": { @@ -10220,18 +10386,19 @@ }, "node_modules/svgo/node_modules/commander": { "version": "11.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", - "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", "dev": true, "license": "MIT", "engines": { "node": ">=16" } }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "dev": true, + "license": "MIT" + }, "node_modules/sync-content": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/sync-content/-/sync-content-2.0.1.tgz", - "integrity": "sha512-NI1mo514yFhr8pV/5Etvgh+pSBUIpoAKoiBIUwALVlQQNAwb40bTw8hhPFaip/dvv0GhpHVOq0vq8iY02ppLTg==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { @@ -10253,8 +10420,6 @@ }, "node_modules/sync-content/node_modules/glob": { "version": "11.0.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.3.tgz", - "integrity": "sha512-2Nim7dha1KVkaiF4q6Dj+ngPPMdfvLJEOpZk/jKiUAkqKebpGAWQXAq9z1xu9HKu5lWfqw/FASuccEjyznjPaA==", "dev": true, "license": "ISC", "dependencies": { @@ -10277,8 +10442,6 @@ }, "node_modules/sync-content/node_modules/jackspeak": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.1.1.tgz", - "integrity": "sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { @@ -10293,8 +10456,6 @@ }, "node_modules/sync-content/node_modules/lru-cache": { "version": "11.2.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.1.tgz", - "integrity": "sha512-r8LA6i4LP4EeWOhqBaZZjDWwehd1xUJPCJd9Sv300H0ZmcUER4+JPh7bqqZeqs1o5pgtgvXm+d9UGrB5zZGDiQ==", "dev": true, "license": "ISC", "engines": { @@ -10303,8 +10464,6 @@ }, "node_modules/sync-content/node_modules/minimatch": { "version": "10.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.3.tgz", - "integrity": "sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==", "dev": true, "license": "ISC", "dependencies": { @@ -10319,8 +10478,6 @@ }, "node_modules/sync-content/node_modules/path-scurry": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.0.tgz", - "integrity": "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { @@ -10336,8 +10493,6 @@ }, "node_modules/tagged-tag": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/tagged-tag/-/tagged-tag-1.0.0.tgz", - "integrity": "sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==", "dev": true, "license": "MIT", "engines": { @@ -10349,9 +10504,6 @@ }, "node_modules/tar-fs": { "version": "2.1.4", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.4.tgz", - "integrity": "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==", - "dev": true, "license": "MIT", "dependencies": { "chownr": "^1.1.1", @@ -10362,9 +10514,6 @@ }, "node_modules/tar-fs/node_modules/readable-stream": { "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, "license": "MIT", "dependencies": { "inherits": "^2.0.3", @@ -10377,9 +10526,6 @@ }, "node_modules/tar-fs/node_modules/tar-stream": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", - "dev": true, "license": "MIT", "dependencies": { "bl": "^4.0.3", @@ -10394,9 +10540,6 @@ }, "node_modules/tar-stream": { "version": "3.1.7", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", - "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", - "dev": true, "license": "MIT", "dependencies": { "b4a": "^1.6.4", @@ -10406,19 +10549,41 @@ }, "node_modules/temp-dir": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-3.0.0.tgz", - "integrity": "sha512-nHc6S/bwIilKHNRgK/3jlhDoIHcp45YgyiwcAk46Tr0LfEqGBVpmiAyuiuxeVE44m3mXnEeVhaipLOEWmH+Njw==", - "dev": true, "license": "MIT", "engines": { "node": ">=14.16" } }, + "node_modules/terser": { + "version": "5.46.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.46.0.tgz", + "integrity": "sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg==", + "dev": true, + "license": "BSD-2-Clause", + "optional": true, + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.15.0", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true, + "license": "MIT", + "optional": true + }, "node_modules/text-decoder": { "version": "1.2.3", - "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.3.tgz", - "integrity": "sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==", - "dev": true, "license": "Apache-2.0", "dependencies": { "b4a": "^1.6.4" @@ -10426,8 +10591,6 @@ }, "node_modules/thread-stream": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-3.1.0.tgz", - "integrity": "sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==", "dev": true, "license": "MIT", "dependencies": { @@ -10436,8 +10599,6 @@ }, "node_modules/throttle-debounce": { "version": "5.0.2", - "resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-5.0.2.tgz", - "integrity": "sha512-B71/4oyj61iNH0KeCamLuE2rmKuTO5byTOSVwECM5FA7TiAiAW+UqTKZ9ERueC4qvgSttUhdmq1mXC3kJqGX7A==", "dev": true, "license": "MIT", "engines": { @@ -10446,22 +10607,15 @@ }, "node_modules/timeout-refresh": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/timeout-refresh/-/timeout-refresh-2.0.1.tgz", - "integrity": "sha512-SVqEcMZBsZF9mA78rjzCrYrUs37LMJk3ShZ851ygZYW1cMeIjs9mL57KO6Iv5mmjSQnOe/29/VAfGXo+oRCiVw==", - "dev": true, "license": "MIT" }, "node_modules/tiny-typed-emitter": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tiny-typed-emitter/-/tiny-typed-emitter-2.1.0.tgz", - "integrity": "sha512-qVtvMxeXbVej0cQWKqVSSAHmKZEHAvxdF8HEUBFWts8h+xEo5m/lEiPakuyZ3BnCBjOD8i24kzNOiOLLgsSxhA==", "dev": true, "license": "MIT" }, "node_modules/tinybench": { "version": "2.9.0", - "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", - "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", "dev": true, "license": "MIT" }, @@ -10516,6 +10670,7 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -10525,9 +10680,6 @@ }, "node_modules/tinyqueue": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/tinyqueue/-/tinyqueue-3.0.0.tgz", - "integrity": "sha512-gRa9gwYU3ECmQYv3lslts5hxuIa90veaEcxDYuu3QGOIAEM2mOZkVHp48ANJuu1CURtRdHKUBY5Lm1tHV+sD4g==", - "dev": true, "license": "ISC" }, "node_modules/tinyrainbow": { @@ -10540,11 +10692,24 @@ "node": ">=14.0.0" } }, + "node_modules/tldts": { + "version": "7.0.23", + "dev": true, + "license": "MIT", + "dependencies": { + "tldts-core": "^7.0.23" + }, + "bin": { + "tldts": "bin/cli.js" + } + }, + "node_modules/tldts-core": { + "version": "7.0.23", + "dev": true, + "license": "MIT" + }, "node_modules/tmp": { "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, "license": "MIT", "dependencies": { "os-tmpdir": "~1.0.2" @@ -10555,8 +10720,6 @@ }, "node_modules/to-regex-range": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, "license": "MIT", "dependencies": { @@ -10568,8 +10731,6 @@ }, "node_modules/toad-cache": { "version": "3.7.0", - "resolved": "https://registry.npmjs.org/toad-cache/-/toad-cache-3.7.0.tgz", - "integrity": "sha512-/m8M+2BJUpoJdgAHoG+baCwBT+tf2VraSfkBgl0Y00qIWt41DJ8R5B8nsEw0I58YwF5IZH6z24/2TobDKnqSWw==", "dev": true, "license": "MIT", "engines": { @@ -10578,18 +10739,38 @@ }, "node_modules/toidentifier": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", "dev": true, "license": "MIT", "engines": { "node": ">=0.6" } }, + "node_modules/tough-cookie": { + "version": "6.0.0", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "tldts": "^7.0.5" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/tr46": { + "version": "6.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "engines": { + "node": ">=20" + } + }, "node_modules/ts-api-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", - "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.4.0.tgz", + "integrity": "sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==", "dev": true, "license": "MIT", "engines": { @@ -10601,8 +10782,6 @@ }, "node_modules/tsdoc-markdown": { "version": "1.4.1", - "resolved": "https://registry.npmjs.org/tsdoc-markdown/-/tsdoc-markdown-1.4.1.tgz", - "integrity": "sha512-N+yt68b/L22zVr1T4yyRjG0OihgfExkDlNTPJyhFa7yh/27h4y8qNzKqSzloLjelQn9R5laDeTY6iwMpURHnLw==", "dev": true, "license": "MIT", "bin": { @@ -10640,8 +10819,6 @@ }, "node_modules/tshy/node_modules/chalk": { "version": "5.6.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", - "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", "dev": true, "license": "MIT", "engines": { @@ -10653,8 +10830,6 @@ }, "node_modules/tshy/node_modules/minimatch": { "version": "10.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.3.tgz", - "integrity": "sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==", "dev": true, "license": "ISC", "dependencies": { @@ -10669,16 +10844,10 @@ }, "node_modules/tslib": { "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "dev": true, "license": "0BSD" }, "node_modules/tunnel-agent": { "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "dev": true, "license": "Apache-2.0", "dependencies": { "safe-buffer": "^5.0.1" @@ -10689,8 +10858,6 @@ }, "node_modules/type-check": { "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, "license": "MIT", "dependencies": { @@ -10701,24 +10868,38 @@ } }, "node_modules/type-fest": { - "version": "4.41.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", - "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "version": "5.4.3", "dev": true, "license": "(MIT OR CC0-1.0)", + "dependencies": { + "tagged-tag": "^1.0.0" + }, "engines": { - "node": ">=16" + "node": ">=20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/typebox": { + "version": "1.0.79", + "license": "MIT" + }, + "node_modules/typed-event-target": { + "version": "3.4.0", + "license": "(MIT or CC0 1.0)", + "dependencies": { + "@augment-vir/common": "^26.2.0", + "run-time-assertions": "^1.1.0" + } + }, "node_modules/typescript": { "version": "5.9.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -10751,10 +10932,19 @@ "typescript": ">=4.8.4 <6.0.0" } }, + "node_modules/uint8array-extras": { + "version": "1.5.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/un-m49": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/un-m49/-/un-m49-2.2.0.tgz", - "integrity": "sha512-4Akx3yTLm32m/JqAMQOvOSkaF8IA26c+baVBDKMQZlI1fOLftD8mdfj107ps5HBtb7K4ltmMsoQMcaz9yRV6zw==", "dev": true, "license": "MIT", "funding": { @@ -10764,9 +10954,6 @@ }, "node_modules/undici": { "version": "6.21.3", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.21.3.tgz", - "integrity": "sha512-gBLkYIlEnSp8pFbT64yFgGE6UIB9tAkhukC23PmMDCe5Nd+cRqKxSjw5y54MK2AZMgZfJWMaNE4nYUHgi1XEOw==", - "dev": true, "license": "MIT", "engines": { "node": ">=18.17" @@ -10774,32 +10961,24 @@ }, "node_modules/undici-types": { "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", - "dev": true, "license": "MIT" }, "node_modules/unix-path-resolve": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unix-path-resolve/-/unix-path-resolve-1.0.2.tgz", - "integrity": "sha512-kG4g5nobBBaMnH2XbrS4sLUXEpx4nY2J3C6KAlAUcnahG2HChxSPVKWYrqEq76iTo+cyMkLUjqxGaQR2tz097Q==", "dev": true, "license": "MIT" }, "node_modules/unslab": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/unslab/-/unslab-1.3.0.tgz", - "integrity": "sha512-YATkfKAFj47kTzmiQrWXMyRvaVrHsW6MEALa4bm+FhiA2YG4oira+Z3DXN6LrYOYn2Y8eO94Lwl9DOHjs1FpoQ==", - "dev": true, "license": "Apache-2.0", "dependencies": { "b4a": "^1.6.6" } }, "node_modules/update-browserslist-db": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.2.tgz", - "integrity": "sha512-E85pfNzMQ9jpKkA7+TJAi4TJN+tBCuWh5rUcS/sv6cFi+1q9LYDwDI5dpUL0u/73EElyQ8d3TEaeW4sPedBqYA==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", "dev": true, "funding": [ { @@ -10829,8 +11008,6 @@ }, "node_modules/uri-js": { "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -10839,15 +11016,10 @@ }, "node_modules/util-deprecate": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true, "license": "MIT" }, "node_modules/valibot": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/valibot/-/valibot-1.1.0.tgz", - "integrity": "sha512-Nk8lX30Qhu+9txPYTwM0cFlWLdPFsFr6LblzqIySfbZph9+BFsAHsNvHOymEviUepeIW6KFHzpX8TKhbptBXXw==", "dev": true, "license": "MIT", "peerDependencies": { @@ -10861,19 +11033,18 @@ }, "node_modules/varint": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/varint/-/varint-6.0.0.tgz", - "integrity": "sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg==", "dev": true, "license": "MIT" }, "node_modules/vite": { - "version": "7.2.7", - "resolved": "https://registry.npmjs.org/vite/-/vite-7.2.7.tgz", - "integrity": "sha512-ITcnkFeR3+fI8P1wMgItjGrR10170d8auB4EpMLPqmx6uxElH3a/hHGQabSHKdqd4FXWO1nFIp9rRn7JQ34ACQ==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.1.tgz", + "integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "esbuild": "^0.25.0", + "esbuild": "^0.27.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", @@ -10965,6 +11136,7 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -10978,6 +11150,7 @@ "integrity": "sha512-n1RxDp8UJm6N0IbJLQo+yzLZ2sQCDyl1o0LeugbPWf8+8Fttp29GghsQBjYJVmWq3gBFfe9Hs1spR44vovn2wA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@vitest/expect": "4.0.15", "@vitest/mocker": "4.0.15", @@ -11052,8 +11225,6 @@ }, "node_modules/vitest/node_modules/picomatch": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", "engines": { @@ -11063,10 +11234,19 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/w3c-xmlserializer": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/walk-up-path": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/walk-up-path/-/walk-up-path-4.0.0.tgz", - "integrity": "sha512-3hu+tD8YzSLGuFYtPRb48vdhKMi0KQV5sn+uWr8+7dMEq/2G/dtLrdDinkLjqq5TIbIBjYJ4Ax/n3YiaW7QM8A==", "dev": true, "license": "ISC", "engines": { @@ -11075,29 +11255,42 @@ }, "node_modules/wcwidth": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", - "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", - "dev": true, "license": "MIT", "dependencies": { "defaults": "^1.0.3" } }, + "node_modules/webidl-conversions": { + "version": "8.0.1", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=20" + } + }, "node_modules/whatwg-mimetype": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", - "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==", "dev": true, "license": "MIT", "engines": { "node": ">=12" } }, + "node_modules/whatwg-url": { + "version": "16.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@exodus/bytes": "^1.11.0", + "tr46": "^6.0.0", + "webidl-conversions": "^8.0.1" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + } + }, "node_modules/which": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, "license": "ISC", "dependencies": { "isexe": "^2.0.0" @@ -11111,15 +11304,10 @@ }, "node_modules/which-runtime": { "version": "1.3.2", - "resolved": "https://registry.npmjs.org/which-runtime/-/which-runtime-1.3.2.tgz", - "integrity": "sha512-5kwCfWml7+b2NO7KrLMhYihjRx0teKkd3yGp1Xk5Vaf2JGdSh+rgVhEALAD9c/59dP+YwJHXoEO7e8QPy7gOkw==", - "dev": true, "license": "Apache-2.0" }, "node_modules/why-is-node-running": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", - "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", "dev": true, "license": "MIT", "dependencies": { @@ -11135,8 +11323,6 @@ }, "node_modules/word-wrap": { "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true, "license": "MIT", "engines": { @@ -11164,9 +11350,6 @@ "node_modules/wrap-ansi-cjs": { "name": "wrap-ansi", "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", @@ -11182,16 +11365,10 @@ }, "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, "license": "MIT" }, "node_modules/wrap-ansi-cjs/node_modules/is-fullwidth-code-point": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -11199,9 +11376,6 @@ }, "node_modules/wrap-ansi-cjs/node_modules/string-width": { "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", @@ -11214,9 +11388,6 @@ }, "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" @@ -11240,15 +11411,10 @@ }, "node_modules/wrappy": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true, "license": "ISC" }, "node_modules/ws": { "version": "8.18.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", - "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", "dev": true, "license": "MIT", "engines": { @@ -11269,9 +11435,6 @@ }, "node_modules/wsl-utils": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/wsl-utils/-/wsl-utils-0.1.0.tgz", - "integrity": "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==", - "dev": true, "license": "MIT", "dependencies": { "is-wsl": "^3.1.0" @@ -11285,15 +11448,24 @@ }, "node_modules/xache": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/xache/-/xache-1.2.1.tgz", - "integrity": "sha512-igRS6jPreJ54ABdzhh4mCDXcz+XMaWO2q1ABRV2yWYuk29jlp8VT7UBdCqNkX7rpYBbXsebVVKkwIuYZjyZNqA==", + "dev": true, + "license": "MIT" + }, + "node_modules/xml-name-validator": { + "version": "5.0.0", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/xmlchars": { + "version": "2.2.0", "dev": true, "license": "MIT" }, "node_modules/xstate": { "version": "5.22.0", - "resolved": "https://registry.npmjs.org/xstate/-/xstate-5.22.0.tgz", - "integrity": "sha512-5d73WWQaAozOaHl/la5TuriybLab9DNkzzYEte5UG2YwsVCR7SSDZJkyS6qfaOYGCFOjZjjSwEEVro4iqN3Slw==", "dev": true, "license": "MIT", "funding": { @@ -11310,8 +11482,6 @@ }, "node_modules/yaml": { "version": "2.8.1", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.1.tgz", - "integrity": "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==", "dev": true, "license": "ISC", "bin": { @@ -11323,8 +11493,6 @@ }, "node_modules/yauzl-promise": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yauzl-promise/-/yauzl-promise-4.0.0.tgz", - "integrity": "sha512-/HCXpyHXJQQHvFq9noqrjfa/WpQC2XYs3vI7tBiAi4QiIU1knvYhZGaO1QPjwIVMdqflxbmwgMXtYeaRiAE0CA==", "dev": true, "license": "MIT", "dependencies": { @@ -11338,8 +11506,6 @@ }, "node_modules/yocto-queue": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, "license": "MIT", "engines": { @@ -11351,9 +11517,6 @@ }, "node_modules/yoctocolors": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.1.2.tgz", - "integrity": "sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==", - "dev": true, "license": "MIT", "engines": { "node": ">=18" @@ -11364,9 +11527,6 @@ }, "node_modules/yoctocolors-cjs": { "version": "2.1.3", - "resolved": "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.3.tgz", - "integrity": "sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==", - "dev": true, "license": "MIT", "engines": { "node": ">=18" @@ -11377,8 +11537,6 @@ }, "node_modules/z32": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/z32/-/z32-1.1.0.tgz", - "integrity": "sha512-1WUHy+VS6d0HPNspDxvLssBbeQjXMjSnpv0vH82vRAUfg847NmX3OXozp/hRP5jPhxBbrVzrgvAt+UsGNzRFQQ==", "dev": true, "license": "MIT", "dependencies": { @@ -11387,9 +11545,6 @@ }, "node_modules/zip-stream": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-6.0.1.tgz", - "integrity": "sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==", - "dev": true, "license": "MIT", "dependencies": { "archiver-utils": "^5.0.0", @@ -11402,8 +11557,6 @@ }, "node_modules/zip-stream-promise": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/zip-stream-promise/-/zip-stream-promise-1.0.2.tgz", - "integrity": "sha512-bGIB91TYzyjQPxMk69n+5W7gtvz5QMo/OgtQDQZYj9uocpRce67pR/oyosSdj65/G4ews32vYN+1XGTbGRXnAQ==", "dev": true, "license": "MIT", "dependencies": { @@ -11414,8 +11567,6 @@ }, "node_modules/zip-stream-promise/node_modules/compress-commons": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-7.0.0.tgz", - "integrity": "sha512-8WWFRMWaa37dwjWCxDcmdx6sxfjQTAEQ6s96BWqX9WYC6Mgg95EvwPYS/7QGX3txkst7TD1jIL2HCY9AixLGfA==", "dev": true, "license": "MIT", "dependencies": { @@ -11431,8 +11582,6 @@ }, "node_modules/zip-stream-promise/node_modules/crc32-stream": { "version": "7.0.1", - "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-7.0.1.tgz", - "integrity": "sha512-IBWsY8xznyQrcHn8h4bC8/4ErNke5elzgG8GcqF4RFPw6aHkWWRc7Tgw6upjaTX/CT/yQgqYENkxYsTYN+hW2g==", "dev": true, "license": "MIT", "dependencies": { @@ -11443,23 +11592,8 @@ "node": ">=18" } }, - "node_modules/zip-stream-promise/node_modules/is-stream": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", - "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/zip-stream-promise/node_modules/zip-stream": { "version": "7.0.2", - "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-7.0.2.tgz", - "integrity": "sha512-g1TjcvzTXLWwDDyZSdC+w7tNdeNCq/qA8Amm8kxGBldyW2yxtSHHlYinxTRvlcaE4Tt3l1ZPsWSA+P9sn20MRw==", "dev": true, "license": "MIT", "dependencies": { @@ -11472,11 +11606,12 @@ } }, "node_modules/zod": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/zod/-/zod-4.1.13.tgz", - "integrity": "sha512-AvvthqfqrAhNH9dnfmrfKzX5upOdjUVJYFqNSlkmGf64gRaTzlPwz99IHYnVs28qYAybvAlBV+H7pn0saFY4Ig==", + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.6.tgz", + "integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==", "dev": true, "license": "MIT", + "peer": true, "funding": { "url": "https://github.com/sponsors/colinhacks" } diff --git a/package.json b/package.json index fb71023..5a49873 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,7 @@ } }, "scripts": { - "docs:generate": "tsdoc --src=src/contexts/*,src/hooks/*,src/lib/types.ts --dest=docs/API.md --noemoji --types", + "docs:generate": "tsdoc --src=src/contexts/*,src/hooks/* --dest=docs/API.md --noemoji --types", "lint:eslint": "eslint --cache .", "lint:format": "prettier --cache --check .", "lint": "npm-run-all --parallel --continue-on-error --print-label --aggregate-output lint:*", @@ -64,7 +64,7 @@ "react": "^18 || ^19" }, "devDependencies": { - "@comapeo/core": "5.2.1", + "@comapeo/core": "5.4.0", "@comapeo/ipc": "6.0.2", "@comapeo/schema": "2.2.0", "@eslint/compat": "2.0.0", @@ -77,6 +77,7 @@ "@tanstack/react-query": "5.90.12", "@testing-library/dom": "10.4.1", "@testing-library/react": "16.3.1", + "@types/jsdom": "^27.0.0", "@types/node": "22.19.3", "@types/react": "19.2.7", "@types/react-dom": "19.2.3", @@ -88,6 +89,8 @@ "globals": "16.5.0", "happy-dom": "20.0.11", "husky": "9.1.7", + "jsdom": "28.0.0", + "ky": "^1.14.3", "lint-staged": "16.2.7", "npm-run-all2": "8.0.4", "prettier": "3.7.4", @@ -96,8 +99,15 @@ "react-dom": "19.2.3", "tsdoc-markdown": "1.4.1", "tshy": "3.1.0", + "type-fest": "5.4.3", "typescript": "5.9.3", "typescript-eslint": "8.49.0", + "uint8array-extras": "1.5.0", "vitest": "4.0.15" + }, + "dependencies": { + "@comapeo/map-server": "^1.0.0-pre.7", + "ensure-error": "5.0.0", + "eventsource-client": "1.2.0" } } diff --git a/src/contexts/ClientApi.ts b/src/contexts/ClientApi.ts index 9f578d4..9911053 100644 --- a/src/contexts/ClientApi.ts +++ b/src/contexts/ClientApi.ts @@ -8,7 +8,7 @@ import { useEffect, type Context, type JSX, - type ReactNode, + type PropsWithChildren, } from 'react' import { getInvitesQueryKey } from '../lib/react-query/invites.js' @@ -26,23 +26,21 @@ export const ClientApiContext: Context = export function ClientApiProvider({ children, clientApi, -}: { - children: ReactNode - clientApi: MapeoClientApi -}): JSX.Element { +}: PropsWithChildren<{ clientApi: MapeoClientApi }>): JSX.Element { const queryClient = useQueryClient() useEffect(() => { - function invalidateCache() { + function invalidateInviteCache() { queryClient.invalidateQueries({ queryKey: getInvitesQueryKey() }) } - clientApi.invite.addListener('invite-received', invalidateCache) - clientApi.invite.addListener('invite-updated', invalidateCache) + // Invite listeners + clientApi.invite.addListener('invite-received', invalidateInviteCache) + clientApi.invite.addListener('invite-updated', invalidateInviteCache) return () => { - clientApi.invite.removeListener('invite-received', invalidateCache) - clientApi.invite.removeListener('invite-updated', invalidateCache) + clientApi.invite.removeListener('invite-received', invalidateInviteCache) + clientApi.invite.removeListener('invite-updated', invalidateInviteCache) } }, [clientApi, queryClient]) diff --git a/src/contexts/MapServer.ts b/src/contexts/MapServer.ts new file mode 100644 index 0000000..b49b6cf --- /dev/null +++ b/src/contexts/MapServer.ts @@ -0,0 +1,144 @@ +import { + createEventSource, + type EventSourceClient, + type EventSourceOptions, +} from 'eventsource-client' +import { + createContext, + createElement, + useContext, + useMemo, + type Context, + type JSX, + type PropsWithChildren, +} from 'react' + +import { useClientApi } from '../hooks/client.js' +import { createHttp } from '../lib/http.js' +import { + ReceivedMapSharesProvider, + SentMapSharesProvider, +} from './MapShares.js' + +export type MapServerApiOptions = { + getBaseUrl(): Promise + fetch?( + input: string | URL | Request, + options?: RequestInit, + ): Promise +} + +export type MapServerApi = ReturnType & { + createEventSource(options: EventSourceOptions): EventSourceClient + getMapStyleJsonUrl(mapId: string): Promise +} + +/** + * Utility function to create a MapServerApi instance. + * Only exported for unit testing purposes. + * @private + * + * @param opts.getBaseUrl A function that returns a promise that resolves to the base URL of the map server. + * @param opts.fetch An optional custom fetch function to use for making requests to the map server. If not provided, the global `fetch` will be used. + */ +export function createMapServerApi({ + getBaseUrl, + fetch = globalThis.fetch, +}: MapServerApiOptions): MapServerApi { + const wrappedFetch = async (input: string | URL, init?: RequestInit) => { + const baseUrl = await getBaseUrl() + return fetch(new URL(input, baseUrl).href, init) + } + const api = createHttp(wrappedFetch) + Object.defineProperty(api, 'createEventSource', { + value: (options: EventSourceOptions) => { + return createEventSource({ + ...options, + fetch: async (input, init) => { + const baseUrl = await getBaseUrl() + return fetch(new URL(input, baseUrl), init) + }, + }) + }, + }) + Object.defineProperty(api, 'getMapStyleJsonUrl', { + value: async (mapId: string) => { + const baseUrl = await getBaseUrl() + return new URL(`/maps/${mapId}/style.json`, baseUrl).href + }, + }) + return api as MapServerApi +} + +export const MapServerContext: Context = + createContext(null) + +export type MapServerProviderProps = PropsWithChildren + +/** + * Create a context provider that holds a `MapServerFetch` function, which waits + * for the map server to be ready before making requests. + * + * @param opts.children React children node + * @param opts.getBaseUrl A function that returns a promise that resolves to the base URL of the map server. + * @param opts.fetch An optional custom fetch function to use for making requests to the map server. If not provided, the global `fetch` will be used. + * + * @example + * ```tsx + * import { createServer } from '@comapeo/map-server' + * + * const server = createServer() + * const listenPromise = server.listen() + * + * const getBaseUrl = async () => { + * const { localPort } = await listenPromise + * return new URL(`http://localhost:${localPort}/`) + * } + * + * const mapServerApi = createMapServerApi({ getBaseUrl }) + * + * function App() { + * return ( + * + * + * + * ) + * } + * ``` + */ +export function MapServerProvider({ + children, + getBaseUrl, + fetch, +}: MapServerProviderProps): JSX.Element { + const clientApi = useClientApi() + const mapServerApi = useMemo( + () => createMapServerApi({ getBaseUrl, fetch }), + [getBaseUrl, fetch], + ) + return createElement( + MapServerContext.Provider, + { value: mapServerApi }, + createElement( + SentMapSharesProvider, + { clientApi, mapServerApi }, + createElement( + ReceivedMapSharesProvider, + { clientApi, mapServerApi }, + children, + ), + ), + ) +} + +/** + * Internal hook to get the MapServerApi (instance of ky) from context. + * Throws if used outside of MapServerProvider. + */ +export function useMapServerApi(): MapServerApi { + const api = useContext(MapServerContext) + if (!api) { + throw new Error('useMapServerApi must be used within a MapServerProvider') + } + return api +} diff --git a/src/contexts/MapShares.ts b/src/contexts/MapShares.ts new file mode 100644 index 0000000..bc45d07 --- /dev/null +++ b/src/contexts/MapShares.ts @@ -0,0 +1,157 @@ +import type { MapeoClientApi } from '@comapeo/ipc' +import { + createContext, + createElement, + useCallback, + useContext, + useMemo, + useSyncExternalStore, + type Context, + type JSX, + type PropsWithChildren, +} from 'react' + +import { + createReceivedMapSharesStore, + createSentMapSharesStore, + type ReceivedMapSharesStore, + type ReceivedMapShareState, + type SentMapSharesStore, + type SentMapShareState, +} from '../lib/map-shares-stores.js' +import type { MapServerApi } from './MapServer.js' + +/** + * @internal + */ +export const ReceivedMapSharesContext: Context = + createContext(null) + +/** + * @internal + */ +export const SentMapSharesContext: Context = + createContext(null) + +type MapSharesProviderProps = PropsWithChildren<{ + clientApi: MapeoClientApi + mapServerApi: MapServerApi +}> + +/** + * @internal + */ +export function ReceivedMapSharesProvider({ + children, + clientApi, + mapServerApi, +}: MapSharesProviderProps): JSX.Element { + const mapSharesStore = useMemo( + () => createReceivedMapSharesStore({ clientApi, mapServerApi }), + [clientApi, mapServerApi], + ) + return createElement( + ReceivedMapSharesContext.Provider, + { value: mapSharesStore }, + children, + ) +} + +/** + * @internal + */ +export function SentMapSharesProvider({ + children, + clientApi, + mapServerApi, +}: MapSharesProviderProps): JSX.Element { + const mapSharesStore = useMemo( + () => createSentMapSharesStore({ clientApi, mapServerApi }), + [clientApi, mapServerApi], + ) + + return createElement( + SentMapSharesContext.Provider, + { value: mapSharesStore }, + children, + ) +} + +const identity = (arg: T): T => arg + +/** + * Internal hook to get the MapSharesStore from context. + */ +function useMapSharesActions< + TStore extends ReceivedMapSharesStore | SentMapSharesStore, +>(context: Context): TStore['actions'] { + const store = useContext(context) + if (!store) { + throw new Error('useMapSharesActions must be used within MapSharesProvider') + } + return store.actions +} + +function useMapSharesState< + TStore extends ReceivedMapSharesStore | SentMapSharesStore, + TSelector, +>( + context: Context, + selector: ( + state: Array< + TStore extends ReceivedMapSharesStore + ? ReceivedMapShareState + : SentMapShareState + >, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + ) => TSelector = identity as any, +): TSelector { + const store = useContext(context) + if (!store) { + throw new Error('useMapSharesState must be used within MapSharesProvider') + } + return useSyncExternalStore( + store.subscribe, + useCallback( + // Casting here because of TS not resolving generic conditional types correctly + () => selector(store.getSnapshot() as Parameters[0]), + [selector, store], + ), + ) +} + +/** + * @internal + */ +export function useReceivedMapSharesActions() { + return useMapSharesActions(ReceivedMapSharesContext) +} + +/** + * @internal + */ +export function useReceivedMapSharesState(): Array +export function useReceivedMapSharesState( + selector: (state: Array) => T, +): T +export function useReceivedMapSharesState( + selector?: (state: Array) => T, +): Array | T { + return useMapSharesState(ReceivedMapSharesContext, selector) +} + +/** + * @internal + */ +export function useSentMapSharesActions() { + return useMapSharesActions(SentMapSharesContext) +} + +/** + * @internal + */ +export function useSentMapSharesState( + selector?: (state: Array) => T, +) { + return useMapSharesState(SentMapSharesContext, selector) +} diff --git a/src/hooks/maps.ts b/src/hooks/maps.ts index 4c66b34..7692358 100644 --- a/src/hooks/maps.ts +++ b/src/hooks/maps.ts @@ -1,7 +1,32 @@ -import { useSuspenseQuery } from '@tanstack/react-query' +import { CUSTOM_MAP_ID } from '@comapeo/map-server/constants.js' +import { errors } from '@comapeo/map-server/errors.js' +import { + useMutation, + useQuery, + useQueryClient, + useSuspenseQuery, +} from '@tanstack/react-query' +import { useCallback } from 'react' -import { mapStyleJsonUrlQueryOptions } from '../lib/react-query/maps.js' -import { useClientApi } from './client.js' +import { useMapServerApi } from '../contexts/MapServer.js' +import { + useReceivedMapSharesActions, + useReceivedMapSharesState, + useSentMapSharesActions, + useSentMapSharesState, +} from '../contexts/MapShares.js' +import { + type ReceivedMapShareState, + type SentMapShareState, +} from '../lib/map-shares-stores.js' +import { + mapImportMutationOptions, + mapInfoQueryOptions, + mapRemoveMutationOptions, + mapSharesMutationOptions, + mapStyleJsonUrlQueryOptions, +} from '../lib/react-query/maps.js' +import { filterMutationResult } from '../lib/react-query/mutation-result.js' /** * Get a URL that points to a StyleJSON resource served by the embedded HTTP server. @@ -29,16 +54,286 @@ import { useClientApi } from './client.js' * } * ``` */ -export function useMapStyleUrl({ - refreshToken, -}: { - refreshToken?: string -} = {}) { - const clientApi = useClientApi() +export function useMapStyleUrl() { + const mapServerApi = useMapServerApi() const { data, error, isRefetching } = useSuspenseQuery( - mapStyleJsonUrlQueryOptions({ clientApi, refreshToken }), + mapStyleJsonUrlQueryOptions({ mapServerApi }), + ) + + return { data, error, isRefetching } +} + +/** + * Import a custom SMP map file, replacing any existing custom map. The mutation + * resolves once the file is successfully uploaded and processed by the server. + * + * @example + * ```tsx + * function MapImportExample() { + * const { mutate: importMap } = useImportCustomMapFile() + * + * } + * ``` + */ +export function useImportCustomMapFile() { + const mapServerApi = useMapServerApi() + const queryClient = useQueryClient() + const options = mapImportMutationOptions({ mapServerApi, queryClient }) + const result = useMutation(options) + return filterMutationResult(result) +} + +export function useRemoveCustomMapFile() { + const mapServerApi = useMapServerApi() + const queryClient = useQueryClient() + const options = mapRemoveMutationOptions({ mapServerApi, queryClient }) + const result = useMutation(options) + return filterMutationResult(result) +} + +export function useGetCustomMapInfo() { + const mapServerApi = useMapServerApi() + const { data, error, isRefetching } = useQuery( + mapInfoQueryOptions({ mapServerApi, mapId: CUSTOM_MAP_ID }), ) return { data, error, isRefetching } } + +// ============================================ +// RECEIVER HOOKS +// ============================================ + +/** + * Get all map shares that the device has received. Automatically updates when + * new shares arrive or share states change. + * + * IMPORTANT: This hook will not trigger a re-render when download progress + * updates, only when the status changes. This is to avoid excessive re-renders + * during downloads. Use `useSingleReceivedMapShare` to get real-time updates on + * a specific share, including download progress. + * + * @example + * ```tsx + * function MapSharesList() { + * const shares = useManyReceivedMapShares() + * + * return shares.map(share => ( + *
+ * {share.mapName} from {share.senderDeviceName} - {share.state} + *
+ * )) + * } + * ``` + */ +export function useManyReceivedMapShares() { + return useReceivedMapSharesState() +} + +/** + * Get a single received map share based on its shareId. + * + * @param opts.shareId ID of the map share + * + * @example + * ```tsx + * function MapShareDetail({ shareId }: { shareId: string }) { + * const share = useSingleReceivedMapShare({ shareId }) + * + * return
{share.mapName} - {share.state}
+ * } + * ``` + */ +export function useSingleReceivedMapShare({ shareId }: { shareId: string }) { + const mapShare = useReceivedMapSharesState( + useCallback( + (shares: Array) => + shares.find((s) => s.shareId === shareId), + [shareId], + ), + ) + if (!mapShare) { + throw new Error(`Map share with id ${shareId} not found`) + } + return mapShare +} + +/** + * Accept and download a map share that has been received. The mutate promise + * resolves once the map _starts_ downloading, before it finishes downloading. + * Use `useManyMapShares` or `useSingleMapShare` to track download progress. + * + * Throws if the share is not in `status="pending"` or if the download fails to + * start (e.g. if the shareId if invalid). + * + * @example + * ```tsx + * function AcceptButton({ shareId }: { shareId: string }) { + * const { mutate: accept } = useAcceptMapShare() + * + * return + * } + * ``` + */ +export function useDownloadReceivedMapShare() { + const { download } = useReceivedMapSharesActions() + const options = mapSharesMutationOptions({ action: download }) + const result = useMutation(options) + return filterMutationResult(result) +} + +/** + * Decline a map share that has been received. Notifies the sender that the + * share was declined. + * + * Throws if the share is not with `status="pending"` + * Throws if shareId is invalid + * Throws if decline request fails (e.g. network error) + * + * @example + * ```tsx + * function DeclineButton({ shareId }: { shareId: string }) { + * const { mutate: decline } = useDeclineMapShare() + * + * return ( + * + * ) + * } + * ``` + */ +export function useDeclineReceivedMapShare() { + const { decline } = useReceivedMapSharesActions() + const options = mapSharesMutationOptions({ action: decline }) + const result = useMutation(options) + return filterMutationResult(result) +} + +/** + * Abort an in-progress map share download. + * + * Throws if the share is not in `status="downloading"` + * Throws if shareId is invalid + * + * @example + * ```tsx + * function AbortButton({ shareId }: { shareId: string }) { + * const { mutate: abort } = useAbortMapShareDownload() + * + * return + * } + * ``` + */ +export function useAbortReceivedMapShareDownload() { + const { abort } = useReceivedMapSharesActions() + const options = mapSharesMutationOptions({ action: abort }) + const result = useMutation(options) + return filterMutationResult(result) +} + +// ============================================ +// SENDER HOOKS +// ============================================ + +/** + * Share a map with a device. The mutation resolves immediately after sending + * the share offer, without waiting for the recipient to accept or reject. The + * mutation resolves with the created map share object, including its ID, which + * can be used to track the share status with `useSingleSentMapShare`. + * + * @param opts.projectId Public ID of project for sending the map share: you can only send map shares to users on the same project + * + * @example + * ```tsx + * function SendMapButton({ projectId, deviceId }: { projectId: string; deviceId: string }) { + * const { mutate: send } = useSendMapShare({ projectId }, { + * onSuccess: (mapShare) => { + * console.log('Share sent with id', mapShare.shareId) + * } + * }) + * + * return ( + * + * ) + * } + * ``` + */ +export function useSendMapShare({ projectId }: { projectId: string }) { + const { createAndSend } = useSentMapSharesActions() + const options = mapSharesMutationOptions({ action: createAndSend, projectId }) + const result = useMutation(options) + return filterMutationResult(result) +} + +/** + * Cancel a map share that was previously sent. If the recipient has not yet + * started downloading the share, they will not be notified until they attempt + * to accept the share and begin downloading it. If they are already downloading + * the share, the download will be canceled before completion. If the download + * is already complete, this action will throw an error. + * + * @param opts.projectId Public ID of project to request the map share cancellation for. + * + * @example + * ```tsx + * function CancelShareButton({ projectId, shareId }: { projectId: string; shareId: string }) { + * const { mutate: cancel } = useRequestCancelMapShare({ projectId }) + * + * return + * } + * ``` + */ +export function useCancelSentMapShare() { + const { cancel } = useSentMapSharesActions() + const options = mapSharesMutationOptions({ action: cancel }) + const result = useMutation(options) + return filterMutationResult(result) +} + +/** + * Track the status and progress of a sent map share. Returns the current state + * of the share, updated in real-time. When the recipient starts downloading, or + * if they decline the share, then the returned share will update. + * + * Throws if no share with the specified ID is found. + * + * @param opts.shareId ID of the sent map share + * + * @example + * ```tsx + * function SentShareStatus({ shareId }: { shareId: string }) { + * const mapShare = useSingleSentMapShare({ shareId }) + * + * return (
+ *
Share status: {mapShare.status}
+ * {mapShare.status === 'pending' &&
Waiting for recipient to accept...
} + * {mapShare.status === 'downloading' && (
Download in progress: {mapShare.downloadProgress}%
)} + * {mapShare.status === 'declined' &&
Share was declined by recipient
} + * {mapShare.status === 'canceled' &&
Share was canceled
} + *
) + * } + * ``` + */ +export function useSingleSentMapShare({ + shareId, +}: { + shareId: string +}): SentMapShareState { + const mapShare = useSentMapSharesState( + useCallback( + (shares: Array) => + shares.find((s) => s.shareId === shareId), + [shareId], + ), + ) + if (!mapShare) { + throw new errors.MAP_SHARE_NOT_FOUND( + `Sent map share with id ${shareId} not found`, + ) + } + return mapShare +} diff --git a/src/index.ts b/src/index.ts index d73eeb0..a6de675 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,5 @@ export { ClientApiProvider } from './contexts/ClientApi.js' +export { MapServerProvider } from './contexts/MapServer.js' export { useClientApi, useIsArchiveDevice, @@ -23,7 +24,29 @@ export { useSendInvite, useSingleInvite, } from './hooks/invites.js' -export { useMapStyleUrl } from './hooks/maps.js' +export { + useMapStyleUrl, + useImportCustomMapFile, + useRemoveCustomMapFile, + useGetCustomMapInfo, + useManyReceivedMapShares, + useSingleReceivedMapShare, + useDeclineReceivedMapShare, + useDownloadReceivedMapShare, + useAbortReceivedMapShareDownload, + useSendMapShare, + useCancelSentMapShare, + useSingleSentMapShare, +} from './hooks/maps.js' +export type { + SentMapShareState, + ReceivedMapShareState, + AbortMapShareOptions, + CancelMapShareOptions, + DeclineMapShareOptions, + DownloadMapShareOptions, + CreateAndSendMapShareOptions, +} from './lib/map-shares-stores.js' export { useAddServerPeer, useAttachmentUrl, diff --git a/src/lib/ensure-error.ts b/src/lib/ensure-error.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/lib/http.ts b/src/lib/http.ts new file mode 100644 index 0000000..95a494f --- /dev/null +++ b/src/lib/http.ts @@ -0,0 +1,135 @@ +import type { JsonValue } from 'type-fest' + +type HttpInit = RequestInit & { json?: JsonValue } +type ResponsePromise = Promise & { + json(): Promise + text(): Promise +} +type RequestMethod = (typeof requestMethods)[number] +type Input = string | URL + +const requestMethods = [ + 'get', + 'post', + 'put', + 'patch', + 'head', + 'delete', +] as const + +function createHttp( + fetchFn: ( + input: string | URL, + init?: RequestInit, + ) => Promise = globalThis.fetch, +) { + const alias = + (method: Uppercase) => + (input: Input, options: HttpInit = {}): ResponsePromise => { + const { json, headers, ...rest } = options + const h = new Headers(headers) + + if (json !== undefined) { + rest.body = JSON.stringify(json) + if (!h.has('content-type')) h.set('content-type', 'application/json') + } + + if (!h.has('accept')) h.set('accept', 'application/json') + + const responsePromise = fetchFn(input, { + ...rest, + method, + headers: h, + }).then((response) => { + if (!response.ok) + throw new HTTPError(response, { method, url: input.toString() }) + return response + }) as ResponsePromise + + responsePromise.json = () => + responsePromise + .catch((e) => { + // For http errors, parse the body as json to get the error details, but rethrow other errors (e.g. network errors) + if (isHTTPError(e)) return e.response + throw e + }) + .then(async (r) => { + if (r.status === 204) return '' + const text = await r.text() + const parsed = text === '' ? '' : JSON.parse(text) + if (r.ok) return parsed + throw new HTTPError(r, { + method: options.method ?? 'GET', + url: input.toString(), + ...parsed, + }) + }) + + responsePromise.text = () => responsePromise.then((r) => r.text()) + + return responsePromise + } + + const http = {} as Record> + for (const method of requestMethods) { + http[method] = alias(upperCase(method)) + } + return http +} + +/** + * http - A minimal fetch wrapper to reduce some boilerplate. + * + * @example + * ```js + * import http from './http.js' + * + * const data = await http.get('https://api.example.com/items').json() + * await http.post('https://api.example.com/items', { json: { name: 'foo' } }).json() + * + * // Custom fetch implementation: + * import { createHttp } from './http.js' + * const http = createHttp(myCustomFetch) + * ``` + */ +const http = createHttp() + +type HTTPErrorObject = { + message?: string + code?: string + [key: string]: unknown +} + +class HTTPError extends Error { + readonly response: Response + readonly status: number + readonly code: string = 'UNKNOWN_ERROR'; + [key: string]: unknown + + constructor( + response: Response, + { method, url, ...body }: { method: string; url: string } & HTTPErrorObject, + ) { + const status = response.status || 500 + const message = + body.message || `Request failed with ${status}: ${method} ${url}` + super(message) + Object.assign(this, body) + // override status in body with status from response + this.status = status + this.name = 'HTTPError' + this.response = response + } +} + +function isHTTPError(error: unknown): error is HTTPError { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + return error instanceof HTTPError || (error as any)?.name === HTTPError.name +} + +export default http +export { createHttp, HTTPError, isHTTPError } + +function upperCase(str: T): Uppercase { + return str.toUpperCase() as Uppercase +} diff --git a/src/lib/map-shares-stores.ts b/src/lib/map-shares-stores.ts new file mode 100644 index 0000000..48e6126 --- /dev/null +++ b/src/lib/map-shares-stores.ts @@ -0,0 +1,405 @@ +/* eslint-disable no-ex-assign */ +import type { MapShare } from '@comapeo/core' +import type { MapeoClientApi } from '@comapeo/ipc' +import { type MapShareState as ServerMapShareState } from '@comapeo/map-server' +import { CUSTOM_MAP_ID } from '@comapeo/map-server/constants.js' +import { errors } from '@comapeo/map-server/errors.js' +import ensureError from 'ensure-error' +import { isHTTPError } from 'ky' +import type { DistributedOmit, SharedUnionFields, Simplify } from 'type-fest' + +import type { MapServerApi } from '../contexts/MapServer.js' + +type DistributedIntersection = U extends unknown ? Simplify : never +export type ReceivedMapShareState = DistributedIntersection< + Simplify, + ServerMapShareState +> +export type SentMapShareState = ServerMapShareState +type MapShareStateUpdate = Simplify< + DistributedOmit< + ServerMapShareState, + Exclude, 'status'> + > +> +type MapShareStatus = ServerMapShareState['status'] +export type ReceivedMapSharesStore = ReturnType< + typeof createReceivedMapSharesStore +> +export type SentMapSharesStore = ReturnType + +// ============================================ +// ACTION OPTIONS TYPES +// These are defined here so that VSCode tooltips work for the mutation +// functions - if the documentation comments are added inline for the store +// actions, they do not show for the mutate() function in hooks. +// ============================================ + +/** Known reasons for declining a map share */ +export const DeclineReason = { + /** User explicitly rejected the map share */ + user_rejected: 'user_rejected', + /** Device storage is full */ + storage_full: 'storage_full', +} as const + +/** Options for downloading a received map share */ +export type DownloadMapShareOptions = { + /** ID of the map share to download */ + shareId: string +} + +/** Options for declining a received map share */ +export type DeclineMapShareOptions = { + /** ID of the map share to decline */ + shareId: string + /** Reason for declining (e.g., 'user_rejected', 'storage_full') */ + reason: (typeof DeclineReason)[keyof typeof DeclineReason] | (string & {}) +} + +/** Options for aborting an in-progress map share download */ +export type AbortMapShareOptions = { + /** ID of the map share download to abort */ + shareId: string +} + +/** Options for creating and sending a map share */ +export type CreateAndSendMapShareOptions = { + /** Public ID of the project to send the share on behalf of */ + projectId: string + /** Device ID of the recipient */ + receiverDeviceId: string + /** ID of the map to share - not needed until we support multiple maps */ + mapId?: string +} + +/** Options for canceling a sent map share */ +export type CancelMapShareOptions = { + /** ID of the map share to cancel */ + shareId: string +} + +/** + * This is like a mini zustand store. Keeping the map shares in an external + * store avoids unnecessary re-renders of the entire app when map shares are + * updated (e.g. if we kept the state in the context), and it avoids potential + * tearing issues with concurrent rendering. + * + * This is the base store for both sent and received map shares, since they + * share a lot of logic around managing the map shares and monitoring their + * status. + */ +function createMapSharesStore< + TMapShare extends DistributedIntersection< + MapShareStateUpdate, + { shareId: MapShare['shareId'] } + >, +>({ mapServerApi }: { mapServerApi: MapServerApi }) { + let mapShares: Array = [] + const listeners = new Set<() => void>() + + function update(shareId: string, stateUpdate: MapShareStateUpdate) { + const index = mapShares.findIndex((s) => s.shareId === shareId) + const existing = mapShares[index] + if (!existing) { + throw new errors.MAP_SHARE_NOT_FOUND( + `Map share with id ${shareId} not found`, + ) + } + assertValidStatusTransition(existing.status, stateUpdate.status) + mapShares[index] = { ...existing, ...stateUpdate } + const isDownloadProgressUpdate = + stateUpdate.status === 'downloading' && existing.status === 'downloading' + // IMPORTANT: For download progress updates, the store state is mutated, so + // maintains Object.is equality. This means that components listening to the + // store state without a selector _will not update_ when download progress + // updates. However, all other updates will result in a re-render, and using + // a selector to listen to an individual map share will also update during + // download progress. + if (!isDownloadProgressUpdate) { + mapShares = [...mapShares] + } + emit() + } + + function add(mapShare: TMapShare) { + mapShares = [...mapShares, mapShare] + emit() + } + + function get(shareId: string) { + const mapShare = mapShares.find((share) => share.shareId === shareId) + if (!mapShare) { + throw new errors.MAP_SHARE_NOT_FOUND( + `Map share with id ${shareId} not found`, + ) + } + return mapShare + } + + function handleError(shareId: string, cause: unknown) { + const error = ensureError(cause) + const errorCode = 'code' in error ? String(error.code) : 'UNKNOWN_ERROR' + try { + update(shareId, { + status: 'error', + error: { + message: error.message, + code: errorCode, + }, + }) + } catch { + // TODO: log errors + } + } + + function monitor(mapShareId: string, path: string) { + // TODO: add a timeout in case the download stalls and never completes + const es = mapServerApi.createEventSource({ + url: path, + onMessage({ data }) { + try { + const stateUpdate = JSON.parse(data) + if (isFinalStatus(stateUpdate.status)) { + es.close() + } + update(mapShareId, stateUpdate) + } catch { + // NB: Don't handleError here - because we optimistically update the + // status, some of the updates from the event source will throw for + // being an invalid status transition, but we can just ignore those + // errors. + // TODO: Custom errors for status transitions, and only ignore those. + es.close() + } + }, + }) + } + + function emit() { + listeners.forEach((l) => l()) + } + + return { + subscribe(listener: () => void) { + listeners.add(listener) + return () => listeners.delete(listener) + }, + getSnapshot() { + return mapShares + }, + update, + add, + get, + handleError, + monitor, + } +} + +/** + * Store and actions for received map shares. + */ +export function createReceivedMapSharesStore({ + clientApi, + mapServerApi, +}: { + clientApi: MapeoClientApi + mapServerApi: MapServerApi +}) { + const { subscribe, getSnapshot, update, add, get, handleError, monitor } = + createMapSharesStore({ mapServerApi }) + // Tracks downloads in progress so they can be aborted. Currently there is no + // cleanup, but this is unlikely to be an issue in practice. + const downloads = new Map>() + + clientApi.on('map-share', (mapShare: MapShare) => { + add({ ...mapShare, status: 'pending' }) + }) + + const actions = { + async download({ shareId }: DownloadMapShareOptions) { + const mapShare = get(shareId) + update(shareId, { status: 'downloading', bytesDownloaded: 0 }) + try { + const downloadIdPromise = mapServerApi + .post(`downloads`, { + json: { + senderDeviceId: mapShare.senderDeviceId, + shareId: mapShare.shareId, + mapShareUrls: mapShare.mapShareUrls, + estimatedSizeBytes: mapShare.estimatedSizeBytes, + }, + }) + .json<{ downloadId: string }>() + .then(({ downloadId }) => downloadId) + // Not strictly necessary, because the `await downloadIdPromise` in the + // same tick below ensures that this is handled, but this protects + // against a refactor which could add another async function between + // setting the promise on the map and awaiting the downloadIdPromise, + // which would result in an unhandled rejection without this. + downloadIdPromise.catch(noop) + downloads.set(shareId, downloadIdPromise) + const downloadId = await downloadIdPromise + monitor(shareId, `downloads/${downloadId}/events`) + } catch (e) { + downloads.delete(shareId) + e = await readHttpError(e) + handleError(shareId, e) + throw e + } + }, + async decline({ shareId, reason }: DeclineMapShareOptions) { + const mapShare = get(shareId) + update(shareId, { status: 'declined', reason }) + try { + await mapServerApi.post(`mapShares/${shareId}/decline`, { + json: { + senderDeviceId: mapShare.senderDeviceId, + mapShareUrls: mapShare.mapShareUrls, + reason, + }, + }) + } catch (e) { + e = await readHttpError(e) + handleError(shareId, e) + throw e + } + }, + async abort({ shareId }: AbortMapShareOptions) { + update(shareId, { status: 'aborted' }) + try { + const downloadId = await downloads.get(shareId) + if (!downloadId) { + throw new errors.DOWNLOAD_NOT_FOUND( + `No download in progress for map share with id ${shareId}`, + ) + } + await mapServerApi.post(`downloads/${downloadId}/abort`) + } catch (e) { + e = await readHttpError(e) + handleError(shareId, e) + throw e + } finally { + downloads.delete(shareId) + } + }, + } + + return { + subscribe, + getSnapshot, + actions, + } +} + +/** + * Store and actions for sent map share. + */ +export function createSentMapSharesStore({ + clientApi, + mapServerApi, +}: { + clientApi: MapeoClientApi + mapServerApi: MapServerApi +}) { + const { subscribe, getSnapshot, update, add, handleError, monitor } = + createMapSharesStore({ mapServerApi }) + + const actions = { + async createAndSend({ + projectId, + receiverDeviceId, + mapId = CUSTOM_MAP_ID, + }: CreateAndSendMapShareOptions) { + const mapShare = await mapServerApi + .post('mapShares', { + json: { receiverDeviceId, mapId }, + }) + .json() + try { + const project = await clientApi.getProject(projectId) + await project.$sendMapShare( + // TODO fix up types on this in @comapeo/core so we don't have to cast + mapShare as unknown as Omit< + SentMapShareState, + 'mapShareUrls' | 'bounds' + > & { mapShareUrls: Array; bounds: Array }, + ) + } catch (e) { + await mapServerApi.post(`mapShares/${mapShare.shareId}/cancel`) + throw e + } + add(mapShare) + monitor(mapShare.shareId, `mapShares/${mapShare.shareId}/events`) + return mapShare + }, + + async cancel({ shareId }: CancelMapShareOptions) { + update(shareId, { status: 'canceled' }) + try { + await mapServerApi.post(`mapShares/${shareId}/cancel`) + } catch (e) { + e = await readHttpError(e) + handleError(shareId, e) + throw e + } + }, + } + + return { + subscribe, + getSnapshot, + actions, + } +} + +async function readHttpError(e: unknown) { + if (!isHTTPError(e)) return e + return e.response.json().catch((e) => e) +} + +const allowedStatusTransitions: Record< + MapShareStatus, + Array +> = { + pending: ['pending', 'downloading', 'declined', 'canceled', 'error'], + downloading: ['downloading', 'aborted', 'completed', 'canceled', 'error'], + completed: ['error'], + canceled: ['error'], + aborted: ['error'], + declined: ['error'], + error: ['error'], +} + +/** + * Asserts that the transition from current to next status is valid. Throws if + * the transition is invalid. + */ +function assertValidStatusTransition( + current: MapShareStatus, + next: MapShareStatus, +) { + if (!allowedStatusTransitions[current].includes(next)) { + throw new Error(`Invalid status transition from ${current} to ${next}`) + } +} + +const finalStatuses = [ + 'declined', + 'canceled', + 'aborted', + 'completed', + 'error', +] as const satisfies Array + +/** + * Returns true if the status is a final status, meaning that no further updates + * should be expected for the map share. + */ +function isFinalStatus( + status: MapShareStatus, +): status is (typeof finalStatuses)[number] { + return finalStatuses.includes(status as (typeof finalStatuses)[number]) +} + +function noop() {} diff --git a/src/lib/react-query/maps.ts b/src/lib/react-query/maps.ts index 39dab2d..7e1e1d2 100644 --- a/src/lib/react-query/maps.ts +++ b/src/lib/react-query/maps.ts @@ -1,40 +1,207 @@ -import type { MapeoClientApi } from '@comapeo/ipc' with { - 'resolution-mode': 'import', +import { CUSTOM_MAP_ID, DEFAULT_MAP_ID } from '@comapeo/map-server/constants.js' +import { + queryOptions, + type QueryClient, + type UseMutationOptions, +} from '@tanstack/react-query' + +import type { MapServerApi } from '../../contexts/MapServer.js' +import type { + ReceivedMapSharesStore, + SentMapSharesStore, +} from '../map-shares-stores.js' +import { + baseMutationOptions, + baseQueryOptions, + ROOT_QUERY_KEY, +} from './shared.js' + +// Expo's file-system File type is close to the standard File type, so for our +// import function we accept an object with the compatible properties and +// methods, and for the expo File, which can represent a file that does not yet +// exists, we type the `exists` property so that we can check that. +type CompatFile = Omit +type ExpoFileDuckType = CompatFile & { + exists: boolean } -import { queryOptions } from '@tanstack/react-query' -import { baseQueryOptions, ROOT_QUERY_KEY } from './shared.js' +// ============================================ +// QUERY KEYS +// ============================================ + +const MAPS_ROOT_QUERY_KEY = [ROOT_QUERY_KEY, 'maps'] as const -export function getMapsQueryKey() { - return [ROOT_QUERY_KEY, 'maps'] as const +export function getMapQueryKey({ mapId }: { mapId: string }) { + return [...MAPS_ROOT_QUERY_KEY, mapId] as const } -export function getStyleJsonUrlQueryKey({ - refreshToken, -}: { - refreshToken?: string -}) { - return [ROOT_QUERY_KEY, 'maps', 'stylejson_url', { refreshToken }] as const +export function getStyleJsonUrlQueryKey({ mapId }: { mapId: string }) { + return [...getMapQueryKey({ mapId }), 'stylejson_url'] as const } +// ============================================ +// QUERY OPTIONS +// ============================================ + export function mapStyleJsonUrlQueryOptions({ - clientApi, - refreshToken, + mapServerApi, + mapId = DEFAULT_MAP_ID, }: { - clientApi: MapeoClientApi - refreshToken?: string + mapServerApi: MapServerApi + mapId?: string }) { + if (mapId !== DEFAULT_MAP_ID) { + throw new Error('Custom map IDs are not supported yet') + } + return queryOptions({ ...baseQueryOptions(), - queryKey: getStyleJsonUrlQueryKey({ refreshToken }), + queryKey: getStyleJsonUrlQueryKey({ mapId }), queryFn: async () => { - const result = await clientApi.getMapStyleJsonUrl() - - if (!refreshToken) return result - + const result = await mapServerApi.getMapStyleJsonUrl(mapId) const u = new URL(result) - u.searchParams.set('refresh_token', refreshToken) + // This ensures that every time this query is refetched, it will have a different search param, forcing the map to reload. + u.searchParams.set('refresh_token', Date.now().toString()) return u.href }, + // Keep this cached until the cache is manually invalidated by a map upload + staleTime: Infinity, + gcTime: Infinity, + }) +} + +export function mapInfoQueryOptions({ + mapServerApi, + mapId = DEFAULT_MAP_ID, +}: { + mapServerApi: MapServerApi + mapId?: string +}) { + if (mapId !== CUSTOM_MAP_ID) { + throw new Error('Only custom map ID is currently supported') + } + return queryOptions({ + ...baseQueryOptions(), + queryKey: [...getMapQueryKey({ mapId }), 'info'] as const, + queryFn: async () => { + return mapServerApi.get(`maps/${mapId}/info`).json() + }, + // Keep this cached until the cache is manually invalidated by a map upload + staleTime: Infinity, + gcTime: Infinity, }) } + +// ============================================ +// MUTATION OPTIONS +// ============================================ + +export function mapImportMutationOptions({ + mapServerApi, + queryClient, +}: { + mapServerApi: MapServerApi + queryClient: QueryClient +}) { + // TODO: Support importing to custom map IDs, to support multiple maps. + const mapId = CUSTOM_MAP_ID + return { + ...baseMutationOptions(), + mutationFn: async ({ file }: { file: File | ExpoFileDuckType }) => { + if ('exists' in file && !file.exists) { + throw new Error('File does not exist or is not accessible') + } + return mapServerApi.put(`maps/${mapId}`, { + body: file, + headers: { + 'Content-Type': 'application/octet-stream', + }, + }) + }, + onSuccess: async () => { + // Invalidate queries for this map and the default map (which internally + // redirects to custom) so that they will be refetched with the new map data. + await Promise.all([ + queryClient.invalidateQueries({ + queryKey: getMapQueryKey({ mapId }), + }), + queryClient.invalidateQueries({ + queryKey: getMapQueryKey({ mapId: DEFAULT_MAP_ID }), + }), + ]) + }, + } +} + +export function mapRemoveMutationOptions({ + mapServerApi, + queryClient, +}: { + mapServerApi: MapServerApi + queryClient: QueryClient +}) { + // TODO: Support removing from custom map IDs, to support multiple maps. + const mapId = CUSTOM_MAP_ID + return { + ...baseMutationOptions(), + mutationFn: async () => { + return mapServerApi.delete(`maps/${mapId}`) + }, + onSuccess: async () => { + // Invalidate queries for this map and the default map (which internally + // redirects to custom) so that they will be refetched with the new map data. + await Promise.all([ + queryClient.invalidateQueries({ + queryKey: getMapQueryKey({ mapId }), + }), + queryClient.invalidateQueries({ + queryKey: getMapQueryKey({ mapId: DEFAULT_MAP_ID }), + }), + ]) + }, + } +} + +/** + * Mutation options for actions on sent map shares + */ +export function mapSharesMutationOptions< + TAction extends + | SentMapSharesStore['actions'][keyof SentMapSharesStore['actions']] + | keyof ReceivedMapSharesStore['actions'][keyof ReceivedMapSharesStore['actions']], +>( + options: + | { + action: Exclude + } + | { + action: SentMapSharesStore['actions']['createAndSend'] + projectId: string + }, +): UseMutationOptions< + ReturnType, + Error, + TAction extends SentMapSharesStore['actions']['createAndSend'] + ? Parameters[0] + : Omit[0], 'projectId'> +> { + return { + ...baseMutationOptions(), + mutationFn: async ( + variables: TAction extends SentMapSharesStore['actions']['createAndSend'] + ? Parameters[0] + : Omit[0], 'projectId'>, + ) => { + // For consistency with other hooks, we use `projectId` as a parameter of + // the hook, rather than a parameter of the mutate function. + const actionOptions = + 'projectId' in options + ? { ...variables, projectId: options.projectId } + : variables + return options.action( + // @ts-expect-error - TS can't help us here + actionOptions, + ) as ReturnType + }, + } +} diff --git a/src/lib/react-query/mutation-result.ts b/src/lib/react-query/mutation-result.ts new file mode 100644 index 0000000..efb684c --- /dev/null +++ b/src/lib/react-query/mutation-result.ts @@ -0,0 +1,29 @@ +import type { UseMutationResult } from '@tanstack/react-query' +import type { DistributedPick } from 'type-fest' + +const PICKED_MUTATION_RESULT_KEYS = [ + 'error', + 'mutate', + 'mutateAsync', + 'reset', + 'status', +] as const satisfies ReadonlyArray + +/** + * Filters a `UseMutationResult` to only include a subset of its keys, and uses + * `DistributedPick` to preserve the discriminated union types of the mutation + * result based on the `status` property. + */ +export function filterMutationResult< + TResult extends // eslint-disable-next-line @typescript-eslint/no-explicit-any + UseMutationResult, +>(mutationResult: TResult) { + const filteredResult = {} as DistributedPick< + TResult, + (typeof PICKED_MUTATION_RESULT_KEYS)[number] + > + for (const key of PICKED_MUTATION_RESULT_KEYS) { + filteredResult[key] = mutationResult[key] + } + return filteredResult +} diff --git a/test/fixtures/demotiles-z2.smp b/test/fixtures/demotiles-z2.smp new file mode 100644 index 0000000..24e2bc1 Binary files /dev/null and b/test/fixtures/demotiles-z2.smp differ diff --git a/test/fixtures/osm-bright-z6.smp b/test/fixtures/osm-bright-z6.smp new file mode 100644 index 0000000..45f6a1b Binary files /dev/null and b/test/fixtures/osm-bright-z6.smp differ diff --git a/test/helpers/jsdom-setup.ts b/test/helpers/jsdom-setup.ts new file mode 100644 index 0000000..a09fc2f --- /dev/null +++ b/test/helpers/jsdom-setup.ts @@ -0,0 +1,20 @@ +/** + * Sets up minimal DOM globals needed for React rendering in + * `@vitest-environment node` test files. + * + * Import as a side-effect: `import '../helpers/jsdom-setup.js'` + */ +import { JSDOM } from 'jsdom' + +const dom = new JSDOM('', { + url: 'http://localhost', + pretendToBeVisual: true, +}) +globalThis.document = dom.window.document +globalThis.window = dom.window as unknown as Window & typeof globalThis +// navigator is a getter-only property in newer Node.js versions, so use defineProperty +Object.defineProperty(globalThis, 'navigator', { + value: dom.window.navigator, + writable: true, + configurable: true, +}) diff --git a/test/helpers/map-server.ts b/test/helpers/map-server.ts new file mode 100644 index 0000000..a093b41 --- /dev/null +++ b/test/helpers/map-server.ts @@ -0,0 +1,202 @@ +import fs from 'node:fs/promises' +import os from 'node:os' +import path from 'node:path' +import { fileURLToPath } from 'node:url' +import { createServer, type MapShareState } from '@comapeo/map-server' +import ky from 'ky' +import { Agent as SecretStreamAgent } from 'secret-stream-http' +import type { TestContext } from 'vitest' +// @ts-expect-error - z32 does not have type declarations +import z32 from 'z32' + +// Fixtures from the map-server-tests directory +const MAP_SERVER_TESTS_DIR = path.join( + path.dirname(fileURLToPath(import.meta.url)), + '../../map-server-tests/fixtures', +) +export const OSM_BRIGHT_Z6 = path.join( + MAP_SERVER_TESTS_DIR, + 'osm-bright-z6.smp', +) +export const DEMOTILES_Z2 = path.join(MAP_SERVER_TESTS_DIR, 'demotiles-z2.smp') +export const ONLINE_STYLE_URL = 'https://demotiles.maplibre.org/style.json' + +function noop() {} + +export type ServerInstance = { + /** ky instance for making HTTP requests */ + get: (typeof ky)['get'] + post: (typeof ky)['post'] + put: (typeof ky)['put'] + delete: (typeof ky)['delete'] + localBaseUrl: string + localPort: number + keyPair: ReturnType + deviceId: string +} + +export type SenderInstance = ServerInstance & { + remotePort: number + eventsPath: (id: string) => string +} + +export type ReceiverInstance = ServerInstance & { + customMapPath: string + eventsPath: (id: string) => string +} + +let tmpCounter = 0 + +/** + * Start a single map server for testing. + */ +export async function startMapServer( + t: TestContext, + options?: { + customMapPath?: string + keyPair?: ReturnType + }, +) { + const tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'map-server-test-')) + const tmpCustomMapPath = path.join( + tmpDir, + `custom-map-path-${tmpCounter++}.smp`, + ) + + // Copy the fixture to a temp location to avoid mutations during tests + try { + await fs.copyFile(options?.customMapPath ?? OSM_BRIGHT_Z6, tmpCustomMapPath) + } catch (err) { + // @ts-expect-error - checking error code + if (err.code !== 'ENOENT') { + throw err + } + } + + const keyPair = options?.keyPair ?? SecretStreamAgent.keyPair() + const server = createServer({ + defaultOnlineStyleUrl: ONLINE_STYLE_URL, + fallbackMapPath: DEMOTILES_Z2, + customMapPath: tmpCustomMapPath, + keyPair, + }) + + t.onTestFinished(async () => { + await fs.unlink(tmpCustomMapPath).catch(noop) + await fs.rm(tmpDir, { recursive: true, force: true }).catch(noop) + await server.close() + }) + + const { localPort, remotePort } = await server.listen() + + return { + server, + localPort, + remotePort, + localBaseUrl: `http://127.0.0.1:${localPort}`, + keyPair, + customMapPath: tmpCustomMapPath, + } +} + +/** + * Start sender and receiver map servers for testing map sharing. + */ +export async function startMapServers( + t: TestContext, + options?: { + senderOptions?: { + customMapPath?: string + keyPair?: ReturnType + } + receiverOptions?: { + customMapPath?: string + keyPair?: ReturnType + } + }, +) { + // Deterministic key pairs for sender and receiver + const senderKeyPair = + options?.senderOptions?.keyPair ?? + SecretStreamAgent.keyPair(Buffer.alloc(32, 0)) + const receiverKeyPair = + options?.receiverOptions?.keyPair ?? + SecretStreamAgent.keyPair(Buffer.alloc(32, 1)) + + const [sender, receiver] = await Promise.all([ + startMapServer(t, { + customMapPath: options?.senderOptions?.customMapPath ?? OSM_BRIGHT_Z6, + keyPair: senderKeyPair, + }), + startMapServer(t, { + customMapPath: options?.receiverOptions?.customMapPath ?? DEMOTILES_Z2, + keyPair: receiverKeyPair, + }), + ]) + + const kyDefaults = ky.create({ retry: 0, throwHttpErrors: false }) + const senderKy = kyDefaults.extend({ prefixUrl: sender.localBaseUrl }) + const receiverKy = kyDefaults.extend({ prefixUrl: receiver.localBaseUrl }) + + const senderInstance: SenderInstance = { + get: senderKy.get.bind(senderKy), + post: senderKy.post.bind(senderKy), + put: senderKy.put.bind(senderKy), + delete: senderKy.delete.bind(senderKy), + localBaseUrl: sender.localBaseUrl, + localPort: sender.localPort, + remotePort: sender.remotePort, + keyPair: senderKeyPair, + deviceId: z32.encode(senderKeyPair.publicKey), + eventsPath: (id: string) => `/mapShares/${id}/events`, + } + + const receiverInstance: ReceiverInstance = { + get: receiverKy.get.bind(receiverKy), + post: receiverKy.post.bind(receiverKy), + put: receiverKy.put.bind(receiverKy), + delete: receiverKy.delete.bind(receiverKy), + localBaseUrl: receiver.localBaseUrl, + localPort: receiver.localPort, + keyPair: receiverKeyPair, + deviceId: z32.encode(receiverKeyPair.publicKey), + customMapPath: receiver.customMapPath, + eventsPath: (id: string) => `/downloads/${id}/events`, + } + + /** + * Create a map share on the sender's server + */ + const createShare = () => + senderKy.post('mapShares', { + json: { + mapId: 'custom', + receiverDeviceId: receiverInstance.deviceId, + }, + }) + + /** + * Create a download on the receiver's server + */ + const createDownload = ( + share: Pick< + MapShareState, + 'shareId' | 'mapShareUrls' | 'estimatedSizeBytes' + >, + ) => + receiverKy.post('downloads', { + json: { + senderDeviceId: senderInstance.deviceId, + shareId: share.shareId, + mapShareUrls: share.mapShareUrls, + estimatedSizeBytes: share.estimatedSizeBytes, + }, + }) + + return { + sender: senderInstance, + receiver: receiverInstance, + createShare, + createDownload, + } +} diff --git a/test/hooks/map-shares.test.tsx b/test/hooks/map-shares.test.tsx new file mode 100644 index 0000000..ffea9f4 --- /dev/null +++ b/test/hooks/map-shares.test.tsx @@ -0,0 +1,1002 @@ +/** + * @vitest-environment node + * + * We use node environment because: + * - happy-dom provides its own fetch with CORS restrictions that break real HTTP requests + * - jsdom has its own Uint8Array that breaks compatibility with native Node modules + * - Node environment uses native fetch which works with real servers + * - renderHook from @testing-library/react can work in node with global-jsdom + */ +import type { MapeoClientApi } from '@comapeo/ipc' +import { errors } from '@comapeo/map-server' +import { QueryClient, QueryClientProvider } from '@tanstack/react-query' +import { act, renderHook, waitFor } from '@testing-library/react' +import { useEffect, useRef, useState, type PropsWithChildren } from 'react' +import { beforeEach, describe, expect, it } from 'vitest' + +// Set up minimal DOM globals needed for React rendering in this test file +import '../helpers/jsdom-setup.js' + +import { + ClientApiProvider, + MapServerProvider, + useAbortReceivedMapShareDownload, + useCancelSentMapShare, + useDeclineReceivedMapShare, + useDownloadReceivedMapShare, + useManyReceivedMapShares, + useSendMapShare, + useSingleReceivedMapShare, + useSingleSentMapShare, + type SentMapShareState, +} from '../../src/index.js' +import { + createMockClientApi, + startTestServers, + type MockClientApi, + type ServerInstance, +} from '../lib/map-shares-test-utils.js' + +// ============================================ +// HELPERS +// ============================================ + +/** + * Creates a share using the sender's hooks and returns the share data. + * This helper uses a separate render for the sender context. + */ +async function createShareWithHook({ + senderWrapper, + receiverDeviceId, +}: { + senderWrapper: ReturnType + receiverDeviceId: string +}): Promise { + const { result } = renderHook( + () => useSendMapShare({ projectId: 'test-project-id' }), + { wrapper: senderWrapper }, + ) + + let createdShare: Awaited< + ReturnType + > | null = null + + await act(async () => { + createdShare = await result.current.mutateAsync({ + projectId: 'test-project-id', + receiverDeviceId, + mapId: 'custom', + }) + }) + + if (!createdShare) { + throw new Error('Failed to create share') + } + + return createdShare +} + +// ============================================ +// TEST WRAPPER +// ============================================ + +function createMapSharesWrapper({ + mockClientApi, + getBaseUrl, + queryClient, +}: { + mockClientApi: MockClientApi + getBaseUrl: () => Promise + queryClient?: QueryClient +}) { + const qc = + queryClient ?? + new QueryClient({ + defaultOptions: { + queries: { retry: false }, + mutations: { retry: false }, + }, + }) + + return function Wrapper({ children }: PropsWithChildren) { + return ( + + + + {children} + + + + ) + } +} + +// Create a stateful wrapper that only renders children once a share exists. +// This allows useSingleReceivedMapShare to be tested without throwing. +function WaitForShareWrapper({ children }: PropsWithChildren) { + const shares = useManyReceivedMapShares() + return <>{shares.length > 0 ? children : null} +} + +// ============================================ +// RECEIVED MAP SHARES HOOKS +// ============================================ + +describe('Received Map Shares Hooks', () => { + let mockClientApi: MockClientApi + let sender: ServerInstance + let receiver: ServerInstance + let receiverWrapper: ReturnType + let senderWrapper: ReturnType + + beforeEach(async (t) => { + mockClientApi = createMockClientApi() + const servers = await startTestServers(t) + sender = servers.sender + receiver = servers.receiver + + // Receiver wrapper - for testing received hooks + receiverWrapper = createMapSharesWrapper({ + mockClientApi, + getBaseUrl: async () => new URL(receiver.localBaseUrl), + }) + + // Sender wrapper - for creating shares via hooks + senderWrapper = createMapSharesWrapper({ + mockClientApi: createMockClientApi(), // separate mock for sender + getBaseUrl: async () => new URL(sender.localBaseUrl), + }) + }) + + // Helper to create shares and convert to MapShare format for receiver + const createShare = async () => { + const serverShare = await createShareWithHook({ + senderWrapper, + receiverDeviceId: receiver.deviceId, + }) + // Convert to MapShare format (what receiver gets via 'map-share' event) + return { + ...serverShare, + mapShareReceivedAt: Date.now(), + senderDeviceId: sender.deviceId, + senderDeviceName: 'Test Sender', + } + } + + describe('useManyReceivedMapShares', () => { + it('should return empty array initially', () => { + const { result } = renderHook(() => useManyReceivedMapShares(), { + wrapper: receiverWrapper, + }) + + expect(result.current).toEqual([]) + }) + + it('should return all received map shares when shares are added', async () => { + const { result } = renderHook(() => useManyReceivedMapShares(), { + wrapper: receiverWrapper, + }) + + const mapShare = await createShare() + + act(() => { + mockClientApi.emit('map-share', mapShare) + }) + + await waitFor(() => { + expect(result.current).toHaveLength(1) + }) + + expect(result.current[0]).toMatchObject({ + shareId: mapShare.shareId, + senderDeviceId: sender.deviceId, + status: 'pending', + }) + }) + + it('should update when multiple map shares are received', async () => { + const { result } = renderHook(() => useManyReceivedMapShares(), { + wrapper: receiverWrapper, + }) + + const mapShare1 = await createShare() + const mapShare2 = await createShare() + + act(() => { + mockClientApi.emit('map-share', mapShare1) + mockClientApi.emit('map-share', mapShare2) + }) + + await waitFor(() => { + expect(result.current).toHaveLength(2) + }) + }) + }) + + describe('useSingleReceivedMapShare', () => { + it('should throw when shareId is not found', () => { + expect(() => { + renderHook( + () => useSingleReceivedMapShare({ shareId: 'non-existent' }), + { wrapper: receiverWrapper }, + ) + }).toThrow('Map share with id non-existent not found') + }) + + it('should return the specific map share', async () => { + const mapShare = await createShare() + + // Combine the base wrapper with our stateful wrapper + function CombinedWrapper({ children }: PropsWithChildren) { + const BaseWrapper = receiverWrapper + return ( + + {children} + + ) + } + + // Render the hook - it won't run until share is available + const { result } = renderHook( + () => useSingleReceivedMapShare({ shareId: mapShare.shareId }), + { wrapper: CombinedWrapper }, + ) + + // Emit the share event to trigger the store update + act(() => { + mockClientApi.emit('map-share', mapShare) + }) + + // Wait for the hook to render with data + await waitFor(() => { + expect(result.current).toBeDefined() + }) + + // Now verify useSingleReceivedMapShare returns the correct share + expect(result.current.shareId).toBe(mapShare.shareId) + expect(result.current.status).toBe('pending') + expect(result.current.senderDeviceId).toBe(sender.deviceId) + }) + }) + + describe('useDownloadReceivedMapShare', () => { + it('should show download progress during download', async () => { + // Capture all render states to verify progress updates + const capturedStates: Array<{ + status: string + bytesDownloaded?: number + }> = [] + + function Tracker() { + const share = useSingleReceivedMapShare({ shareId: mapShare.shareId }) + capturedStates.push({ + status: share.status, + // @ts-expect-error no need to type this precisely for the test + bytesDownloaded: share.bytesDownloaded, + }) + return null + } + + function CombinedWrapper({ children }: PropsWithChildren) { + const BaseWrapper = receiverWrapper + + return ( + + + + {children} + + + ) + } + + // Create the share before we render, so we have the shareId for the wrappers + const mapShare = await createShare() + + const { result } = renderHook( + () => ({ + download: useDownloadReceivedMapShare(), + shares: useManyReceivedMapShares(), + }), + { wrapper: CombinedWrapper }, + ) + + // Emit the share AFTER the store is listening + act(() => { + mockClientApi.emit('map-share', mapShare) + }) + + // Wait for share to appear in store + await waitFor(() => { + expect(result.current.shares).toHaveLength(1) + }) + + // Now trigger the download + act(() => { + result.current.download.mutate({ shareId: mapShare.shareId }) + }) + + await waitFor(() => { + expect(result.current.download.status).toBe('success') + }) + + // Wait for download to complete + await waitFor(() => { + expect(result.current.shares[0]?.status).toBe('completed') + }) + + // Verify we saw downloading states with progress before completion + const downloadingStates = capturedStates.filter( + (s) => s.status === 'downloading' && s.bytesDownloaded! > 0, + ) + expect(downloadingStates.length).toBeGreaterThan(7) + }) + + it('should not re-render useManyReceivedMapShares during download progress updates', async () => { + // Track renders of useManyReceivedMapShares to verify it only re-renders + // on status changes, not on download progress updates + const capturedStates: Array<{ + status: string + bytesDownloaded?: number + }> = [] + + function ManySharesTracker() { + const shares = useManyReceivedMapShares() + const share = shares.find((s) => s.shareId === mapShare.shareId) + if (share) { + capturedStates.push({ + status: share.status, + // @ts-expect-error no need to type this precisely for the test + bytesDownloaded: share.bytesDownloaded, + }) + } + return null + } + + function CombinedWrapper({ children }: PropsWithChildren) { + const BaseWrapper = receiverWrapper + + return ( + + + {children} + + ) + } + + // Create the share before we render, so we have the shareId for the wrappers + const mapShare = await createShare() + + const { result } = renderHook( + () => ({ + download: useDownloadReceivedMapShare(), + shares: useManyReceivedMapShares(), + }), + { wrapper: CombinedWrapper }, + ) + + // Emit the share AFTER the store is listening + act(() => { + mockClientApi.emit('map-share', mapShare) + }) + + // Wait for share to appear in store + await waitFor(() => { + expect(result.current.shares).toHaveLength(1) + }) + + // Now trigger the download + act(() => { + result.current.download.mutate({ shareId: mapShare.shareId }) + }) + + await waitFor(() => { + expect(result.current.download.status).toBe('success') + }) + + // Wait for download to complete + await waitFor(() => { + expect(result.current.shares[0]?.status).toBe('completed') + }) + + // Get unique statuses captured (ignoring bytesDownloaded changes) + const uniqueStatuses = [...new Set(capturedStates.map((s) => s.status))] + + // Should have seen: pending, downloading, completed + expect(uniqueStatuses).toContain('pending') + expect(uniqueStatuses).toContain('downloading') + expect(uniqueStatuses).toContain('completed') + + // The key assertion: useManyReceivedMapShares should NOT re-render + // during download progress updates. It should only re-render on status + // changes. So we should see at most a few renders per status, not many + // renders with different bytesDownloaded values. + const downloadingStates = capturedStates.filter( + (s) => s.status === 'downloading', + ) + const uniqueBytesDownloaded = [ + ...new Set(downloadingStates.map((s) => s.bytesDownloaded)), + ] + + // With the optimization working, we should only see one unique + // bytesDownloaded value during downloading (the initial value when status + // changes to downloading), not many different values as progress updates + // come in. + expect(uniqueBytesDownloaded.length).toBe(1) + expect(uniqueBytesDownloaded[0]).toBe(0) // should be the initial value when status changes to downloading + }) + + it('should throw for non-existent shareId', async () => { + const { result } = renderHook(() => useDownloadReceivedMapShare(), { + wrapper: receiverWrapper, + }) + + act(() => { + result.current.mutate({ shareId: 'non-existent' }) + }) + + await waitFor(() => { + expect(result.current.status).toBe('error') + }) + + expect(result.current.error).toHaveProperty('code', 'MAP_SHARE_NOT_FOUND') + }) + }) + + describe('useDeclineReceivedMapShare', () => { + it('should have idle status initially', () => { + const { result } = renderHook(() => useDeclineReceivedMapShare(), { + wrapper: receiverWrapper, + }) + + expect(result.current.status).toBe('idle') + }) + + it('should throw for non-existent shareId', async () => { + const { result } = renderHook(() => useDeclineReceivedMapShare(), { + wrapper: receiverWrapper, + }) + + act(() => { + result.current.mutate({ + shareId: 'non-existent', + reason: 'user_rejected', + }) + }) + + await waitFor(() => { + expect(result.current.status).toBe('error') + }) + + expect(result.current.error).toHaveProperty('code', 'MAP_SHARE_NOT_FOUND') + }) + + it('should decline a pending share', async () => { + // First render the hook to set up the store + const { result } = renderHook( + () => ({ + decline: useDeclineReceivedMapShare(), + shares: useManyReceivedMapShares(), + }), + { wrapper: receiverWrapper }, + ) + + // Create and emit the share AFTER the store is listening + const mapShare = await createShare() + act(() => { + mockClientApi.emit('map-share', mapShare) + }) + + // Wait for share to appear in store + await waitFor(() => { + expect(result.current.shares).toHaveLength(1) + }) + + // Now decline the share + act(() => { + result.current.decline.mutate({ + shareId: mapShare.shareId, + reason: 'user_rejected', + }) + }) + + await waitFor(() => { + expect(result.current.decline.status).toBe('success') + }) + + expect(result.current.shares[0]).toHaveProperty('status', 'declined') + expect(result.current.shares[0]).toHaveProperty('reason', 'user_rejected') + }) + }) + + describe('useAbortReceivedMapShareDownload', () => { + it('should have idle status initially', () => { + const { result } = renderHook(() => useAbortReceivedMapShareDownload(), { + wrapper: receiverWrapper, + }) + + expect(result.current.status).toBe('idle') + }) + + it('should throw for non-existent shareId', async () => { + const { result } = renderHook(() => useAbortReceivedMapShareDownload(), { + wrapper: receiverWrapper, + }) + + act(() => { + result.current.mutate({ shareId: 'non-existent' }) + }) + + await waitFor(() => { + expect(result.current.status).toBe('error') + }) + + expect(result.current.error).toHaveProperty('code', 'MAP_SHARE_NOT_FOUND') + }) + + it('should abort an in-progress download', async () => { + // First render the hook to set up the store + const { result } = renderHook( + () => ({ + download: useDownloadReceivedMapShare(), + abort: useAbortReceivedMapShareDownload(), + shares: useManyReceivedMapShares(), + }), + { wrapper: receiverWrapper }, + ) + + // Create and emit the share AFTER the store is listening + const mapShare = await createShare() + act(() => { + mockClientApi.emit('map-share', mapShare) + }) + + // Wait for share to appear in store + await waitFor(() => { + expect(result.current.shares).toHaveLength(1) + }) + + // Start download and immediately abort to minimize race condition + await act(async () => { + result.current.download.mutate({ shareId: mapShare.shareId }) + // Small delay to let the store update to 'downloading' + await new Promise((resolve) => setTimeout(resolve, 10)) + result.current.abort.mutate({ shareId: mapShare.shareId }) + }) + + await waitFor(() => { + expect(result.current.abort.status).toBe('success') + }) + + expect(result.current.shares[0]).toHaveProperty('status', 'aborted') + }) + + it('should throw for invalid status transition (pending -> aborted)', async () => { + // First render the hook to set up the store + const { result } = renderHook( + () => ({ + abort: useAbortReceivedMapShareDownload(), + shares: useManyReceivedMapShares(), + }), + { wrapper: receiverWrapper }, + ) + + // Create and emit the share AFTER the store is listening + const mapShare = await createShare() + act(() => { + mockClientApi.emit('map-share', mapShare) + }) + + // Wait for share to appear in store + await waitFor(() => { + expect(result.current.shares).toHaveLength(1) + }) + + // Try to abort without downloading first (pending -> aborted is invalid) + act(() => { + result.current.abort.mutate({ shareId: mapShare.shareId }) + }) + + await waitFor(() => { + expect(result.current.abort.status).toBe('error') + }) + + expect(result.current.abort.error?.message).toContain( + 'Invalid status transition', + ) + }) + }) + + describe('invalid status transitions', () => { + it('should not allow download after decline', async () => { + const { result } = renderHook( + () => ({ + download: useDownloadReceivedMapShare(), + decline: useDeclineReceivedMapShare(), + shares: useManyReceivedMapShares(), + }), + { wrapper: receiverWrapper }, + ) + + const mapShare = await createShare() + act(() => { + mockClientApi.emit('map-share', mapShare) + }) + + await waitFor(() => { + expect(result.current.shares).toHaveLength(1) + }) + + // Decline the share first + act(() => { + result.current.decline.mutate({ + shareId: mapShare.shareId, + reason: 'user_rejected', + }) + }) + + await waitFor(() => { + expect(result.current.decline.status).toBe('success') + }) + + expect(result.current.shares[0]).toHaveProperty('status', 'declined') + + // Now try to download - should fail + act(() => { + result.current.download.mutate({ shareId: mapShare.shareId }) + }) + + await waitFor(() => { + expect(result.current.download.status).toBe('error') + }) + + expect(result.current.download.error?.message).toContain( + 'Invalid status transition', + ) + }) + + it('should not allow decline after download starts', async () => { + const { result } = renderHook( + () => ({ + download: useDownloadReceivedMapShare(), + decline: useDeclineReceivedMapShare(), + shares: useManyReceivedMapShares(), + }), + { wrapper: receiverWrapper }, + ) + + const mapShare = await createShare() + act(() => { + mockClientApi.emit('map-share', mapShare) + }) + + await waitFor(() => { + expect(result.current.shares).toHaveLength(1) + }) + + // Start download and immediately try to decline to minimize race condition + await act(async () => { + result.current.download.mutate({ shareId: mapShare.shareId }) + // Small delay to let the store update to 'downloading' + await new Promise((resolve) => setTimeout(resolve, 10)) + result.current.decline.mutate({ + shareId: mapShare.shareId, + reason: 'user_rejected', + }) + }) + + await waitFor(() => { + expect(result.current.decline.status).toBe('error') + }) + + expect(result.current.decline.error?.message).toContain( + 'Invalid status transition', + ) + }) + + it('should not allow any action after completion', async () => { + const { result } = renderHook( + () => ({ + download: useDownloadReceivedMapShare(), + decline: useDeclineReceivedMapShare(), + abort: useAbortReceivedMapShareDownload(), + shares: useManyReceivedMapShares(), + }), + { wrapper: receiverWrapper }, + ) + + const mapShare = await createShare() + act(() => { + mockClientApi.emit('map-share', mapShare) + }) + + await waitFor(() => { + expect(result.current.shares).toHaveLength(1) + }) + + // Download and wait for completion + act(() => { + result.current.download.mutate({ shareId: mapShare.shareId }) + }) + + await waitFor(() => { + expect(result.current.shares[0]?.status).toBe('completed') + }) + + // Reset the download mutation to test again + act(() => { + result.current.download.reset() + }) + + // Try to download again - should fail + act(() => { + result.current.download.mutate({ shareId: mapShare.shareId }) + }) + + await waitFor(() => { + expect(result.current.download.status).toBe('error') + }) + + expect(result.current.download.error?.message).toContain( + 'Invalid status transition', + ) + + // Try to decline - should fail + act(() => { + result.current.decline.mutate({ + shareId: mapShare.shareId, + reason: 'user_rejected', + }) + }) + + await waitFor(() => { + expect(result.current.decline.status).toBe('error') + }) + + expect(result.current.decline.error?.message).toContain( + 'Invalid status transition', + ) + + // Try to abort - should fail + act(() => { + result.current.abort.mutate({ shareId: mapShare.shareId }) + }) + + await waitFor(() => { + expect(result.current.abort.status).toBe('error') + }) + + expect(result.current.abort.error?.message).toContain( + 'Invalid status transition', + ) + }) + }) +}) + +// ============================================ +// SENT MAP SHARES HOOKS +// ============================================ + +describe('Sent Map Shares Hooks', () => { + let mockClientApi: MockClientApi + let sender: ServerInstance + let receiver: ServerInstance + let wrapper: ReturnType + + beforeEach(async (t) => { + mockClientApi = createMockClientApi() + const servers = await startTestServers(t) + sender = servers.sender + receiver = servers.receiver + + // For sent hooks, we use the sender's map server + wrapper = createMapSharesWrapper({ + mockClientApi, + getBaseUrl: async () => new URL(sender.localBaseUrl), + }) + }) + + describe('useSendMapShare', () => { + it('should have idle status initially', () => { + const { result } = renderHook( + () => useSendMapShare({ projectId: 'test-project-id' }), + { wrapper }, + ) + + expect(result.current.status).toBe('idle') + }) + + it('should create and send a map share', async () => { + const { result } = renderHook( + () => useSendMapShare({ projectId: 'test-project-id' }), + { wrapper }, + ) + + let createdShare: Awaited< + ReturnType + > | null = null + + await act(async () => { + createdShare = await result.current.mutateAsync({ + projectId: 'test-project-id', + receiverDeviceId: receiver.deviceId, + mapId: 'custom', + }) + }) + + // Wait for mutation status to update + await waitFor(() => { + expect(result.current.status).toBe('success') + }) + + expect(createdShare).toMatchObject({ + mapId: 'custom', + status: 'pending', + }) + expect(createdShare).toHaveProperty('shareId') + }) + + it('should call clientApi.getProject and $sendMapShare', async () => { + const { result } = renderHook( + () => useSendMapShare({ projectId: 'test-project-id' }), + { wrapper }, + ) + + act(() => { + result.current.mutate({ + projectId: 'test-project-id', + receiverDeviceId: receiver.deviceId, + mapId: 'custom', + }) + }) + + await waitFor(() => { + expect(result.current.status).toBe('success') + }) + + expect(mockClientApi.getProject).toHaveBeenCalledWith('test-project-id') + expect(mockClientApi.$sendMapShare).toHaveBeenCalled() + }) + }) + + describe('useCancelSentMapShare', () => { + it('should have idle status initially', () => { + const { result } = renderHook(() => useCancelSentMapShare(), { wrapper }) + + expect(result.current.status).toBe('idle') + }) + + it('should cancel a pending sent share', async () => { + const { result } = renderHook( + () => ({ + send: useSendMapShare({ projectId: 'test-project-id' }), + cancel: useCancelSentMapShare(), + }), + { wrapper }, + ) + + let createdShare: Awaited< + ReturnType + > | null = null + + // First create a share + await act(async () => { + createdShare = await result.current.send.mutateAsync({ + projectId: 'test-project-id', + receiverDeviceId: receiver.deviceId, + mapId: 'custom', + }) + }) + + // Wait for send to complete + await waitFor(() => { + expect(result.current.send.status).toBe('success') + }) + + // Now cancel + act(() => { + result.current.cancel.mutate({ shareId: createdShare!.shareId }) + }) + + await waitFor(() => { + expect(result.current.cancel.status).toBe('success') + }) + }) + + it('should throw for non-existent shareId', async () => { + const { result } = renderHook(() => useCancelSentMapShare(), { wrapper }) + + act(() => { + result.current.mutate({ shareId: 'non-existent' }) + }) + + await waitFor(() => { + expect(result.current.status).toBe('error') + }) + + expect(result.current.error).toHaveProperty('code', 'MAP_SHARE_NOT_FOUND') + }) + }) + + describe('useSingleSentMapShare', () => { + it('should throw MAP_SHARE_NOT_FOUND error when shareId is not found', () => { + let caughtError: unknown + + try { + renderHook(() => useSingleSentMapShare({ shareId: 'non-existent' }), { + wrapper, + }) + } catch (e) { + caughtError = e + } + + expect(caughtError).toBeInstanceOf(errors.MAP_SHARE_NOT_FOUND) + }) + + it('should return the specific sent map share', async () => { + // Track shareId from wrapper to use in hook and assertions + let wrapperShareId: string | null = null + + // Stateful wrapper that creates a share and only renders children + // once the share exists in the store + function WaitForShareWrapper({ children }: PropsWithChildren) { + const send = useSendMapShare({ projectId: 'test-project-id' }) + const [localShareId, setLocalShareId] = useState(null) + const mutationStarted = useRef(false) + + // Use useEffect to trigger mutation on mount (only once) + useEffect(() => { + if (send.status === 'idle' && !mutationStarted.current) { + mutationStarted.current = true + send + .mutateAsync({ + projectId: 'test-project-id', + receiverDeviceId: receiver.deviceId, + mapId: 'custom', + }) + // mutateAsync returns Promise> because the action returns a Promise + .then(async (sharePromise) => { + const share = await sharePromise + wrapperShareId = share.shareId + setLocalShareId(share.shareId) + }) + } + }, [send]) + + return <>{localShareId ? children : null} + } + + function CombinedWrapper({ children }: PropsWithChildren) { + const BaseWrapper = wrapper + return ( + + {children} + + ) + } + + const { result } = renderHook( + () => { + // wrapperShareId is set before children render + return useSingleSentMapShare({ shareId: wrapperShareId! }) + }, + { wrapper: CombinedWrapper }, + ) + + // Wait for the hook to render with data (increase timeout for async mutation) + await waitFor( + () => { + expect(result.current).not.toBeNull() + }, + { timeout: 10000, interval: 100 }, + ) + + // Verify useSingleSentMapShare returns the correct share + expect(result.current.shareId).toBe(wrapperShareId) + expect(result.current.status).toBe('pending') + expect(result.current.mapId).toBe('custom') + }) + }) +}) diff --git a/test/hooks/maps.test.tsx b/test/hooks/maps.test.tsx index 57944fb..bc6acdc 100644 --- a/test/hooks/maps.test.tsx +++ b/test/hooks/maps.test.tsx @@ -1,60 +1,342 @@ -import { QueryClient } from '@tanstack/react-query' -import { act, renderHook } from '@testing-library/react' -import { afterAll, assert, beforeAll, test, vi } from 'vitest' +/** + * @vitest-environment node + * + * We use node environment because: + * - happy-dom provides its own fetch with CORS restrictions that break real HTTP requests + * - Node environment uses native fetch which works with real servers + * - renderHook from @testing-library/react can work in node with global-jsdom + */ +import fs from 'node:fs' +import type { MapeoClientApi } from '@comapeo/ipc' +import { QueryClient, QueryClientProvider } from '@tanstack/react-query' +import { act, renderHook, waitFor } from '@testing-library/react' +import { Suspense, type PropsWithChildren } from 'react' +import { describe, expect, it, vi } from 'vitest' -import { useMapStyleUrl } from '../../src/index.js' -import { setupCoreIpc } from '../helpers/ipc.js' -import { createClientApiWrapper } from '../helpers/react.js' +// Set up minimal DOM globals needed for React rendering in this test file +import '../helpers/jsdom-setup.js' -beforeAll(() => { - vi.useFakeTimers({ shouldAdvanceTime: true }) -}) +import { + useGetCustomMapInfo, + useImportCustomMapFile, + useMapStyleUrl, + useRemoveCustomMapFile, +} from '../../src/hooks/maps.js' +import { ClientApiProvider, MapServerProvider } from '../../src/index.js' +import { HTTPError } from '../../src/lib/http.js' +import { + createMockClientApi, + DEMOTILES_Z2, + OSM_BRIGHT_Z6, + startTestServer, +} from '../lib/map-shares-test-utils.js' -afterAll(() => { - vi.useRealTimers() -}) +// ============================================ +// HELPERS +// ============================================ + +function createWrapper({ getBaseUrl }: { getBaseUrl: () => Promise }) { + const queryClient = new QueryClient({ + defaultOptions: { + queries: { retry: false }, + mutations: { retry: false }, + }, + }) + const mockClientApi = createMockClientApi() as unknown as MapeoClientApi -test('basic read works', async (t) => { - const { client, cleanup, fastifyController } = setupCoreIpc() + function Wrapper({ children }: PropsWithChildren) { + return ( + + + + {children} + + + + ) + } - fastifyController.start() + return { Wrapper, queryClient } +} - t.onTestFinished(() => { - return cleanup() +function readFixtureAsFile(fixturePath: string, filename: string): File { + const buffer = fs.readFileSync(fixturePath) + return new File([buffer], filename, { + type: 'application/octet-stream', }) +} + +// ============================================ +// TESTS +// ============================================ + +describe('Map Hooks', () => { + describe('useMapStyleUrl', () => { + it('returns a valid style URL', async (t) => { + const server = await startTestServer(t, OSM_BRIGHT_Z6, 0) + const { Wrapper } = createWrapper({ + getBaseUrl: async () => new URL(server.localBaseUrl), + }) + + const { result } = renderHook(() => useMapStyleUrl(), { + wrapper: Wrapper, + }) + + await waitFor(() => { + expect(result.current.data).toBeDefined() + }) + + const url = new URL(result.current.data) + expect(url.pathname).toBe('/maps/default/style.json') + expect(url.searchParams.has('refresh_token')).toBe(true) + }) + + it('re-mounting returns the same cached URL', async (t) => { + const server = await startTestServer(t, OSM_BRIGHT_Z6, 0) + const { Wrapper } = createWrapper({ + getBaseUrl: async () => new URL(server.localBaseUrl), + }) + + const first = renderHook(() => useMapStyleUrl(), { + wrapper: Wrapper, + }) + + await waitFor(() => { + expect(first.result.current.data).toBeDefined() + }) + + const firstUrl = first.result.current.data + + // This test would always pass regardless of our cache settings because + // react query garbage collection runs after a 1000ms delay in tests. With + // this test we actually want to test that our cache settings are caching + // the style URL returned, so that without any map change, it is always + // returning the same value (e.g. same refresh_token). Advancing the fake + // timers allows us to test re-render after 5000ms without needing to wait + // for that time in the tests. You can validate this works by testing that + // this test fails if you set gcTime and staleTime to `0` in the hook + // query options. + vi.useFakeTimers() + first.unmount() + await vi.advanceTimersByTimeAsync(5000) + vi.useRealTimers() - const queryClient = new QueryClient() + const second = renderHook(() => useMapStyleUrl(), { + wrapper: Wrapper, + }) - const wrapper = createClientApiWrapper({ clientApi: client, queryClient }) + await waitFor(() => { + expect(second.result.current.data).toBeDefined() + }) - const mapStyleUrlHook = renderHook< - ReturnType, - Parameters[0] - >(({ refreshToken } = {}) => useMapStyleUrl({ refreshToken }), { - wrapper, + expect(second.result.current.data).toBe(firstUrl) + }) }) - await act(() => vi.advanceTimersByTimeAsync(10)) + describe('useImportCustomMapFile', () => { + it('importing a map updates the style URL', async (t) => { + const server = await startTestServer(t, OSM_BRIGHT_Z6, 0) + const { Wrapper } = createWrapper({ + getBaseUrl: async () => new URL(server.localBaseUrl), + }) - const url1 = new URL(mapStyleUrlHook.result.current.data) + const { result } = renderHook( + () => ({ + styleUrl: useMapStyleUrl(), + importMap: useImportCustomMapFile(), + }), + { wrapper: Wrapper }, + ) - assert(url1, 'map style url hook returns valid URL') + await waitFor(() => { + expect(result.current.styleUrl.data).toBeDefined() + }) - mapStyleUrlHook.rerender({ refreshToken: 'abc_123' }) + const urlBefore = result.current.styleUrl.data + + const file = readFixtureAsFile(DEMOTILES_Z2, 'demotiles-z2.smp') + + await act(async () => { + await result.current.importMap.mutateAsync({ file }) + }) + + await waitFor(() => + expect(result.current.styleUrl.data).not.toBe(urlBefore), + ) + + expect(result.current.styleUrl.data).not.toBe(urlBefore) + }) + + it('style json content changes after map import', async (t) => { + const server = await startTestServer(t, OSM_BRIGHT_Z6, 0) + const { Wrapper } = createWrapper({ + getBaseUrl: async () => new URL(server.localBaseUrl), + }) + + const { result } = renderHook( + () => ({ + styleUrl: useMapStyleUrl(), + importMap: useImportCustomMapFile(), + }), + { wrapper: Wrapper }, + ) + + await waitFor(() => { + expect(result.current.styleUrl.data).toBeDefined() + }) + + const responseBefore = await fetch(result.current.styleUrl.data) + const styleBefore = (await responseBefore.json()) as { name: string } + + const file = readFixtureAsFile(DEMOTILES_Z2, 'demotiles-z2.smp') + + await act(async () => { + await result.current.importMap.mutateAsync({ file }) + }) + + const responseAfter = await fetch(result.current.styleUrl.data) + const styleAfter = (await responseAfter.json()) as { name: string } + + expect(styleAfter.name).not.toBe(styleBefore.name) + }) + }) - await act(() => vi.advanceTimersByTimeAsync(10)) + describe('useRemoveCustomMapFile', () => { + it('removing a map updates the style URL', async (t) => { + const server = await startTestServer(t, OSM_BRIGHT_Z6, 0) + const { Wrapper } = createWrapper({ + getBaseUrl: async () => new URL(server.localBaseUrl), + }) - const url2 = new URL(mapStyleUrlHook.result.current.data) + const { result } = renderHook( + () => ({ + styleUrl: useMapStyleUrl(), + removeMap: useRemoveCustomMapFile(), + }), + { wrapper: Wrapper }, + ) - assert.notStrictEqual( - url2.href, - url1.href, - 'map style url hook updates after changing refresh token option', - ) + await waitFor(() => { + expect(result.current.styleUrl.data).toBeDefined() + }) - assert.strictEqual( - url2.searchParams.get('refresh_token'), - 'abc_123', - 'map style url has search param containing refresh token', - ) + const urlBefore = result.current.styleUrl.data + + await act(async () => { + await result.current.removeMap.mutateAsync() + }) + + await waitFor(() => + expect(result.current.styleUrl.data).not.toBe(urlBefore), + ) + + expect(result.current.styleUrl.data).not.toBe(urlBefore) + }) + }) + + describe('useGetCustomMapInfo', () => { + it('returns map info for the custom map', async (t) => { + const server = await startTestServer(t, OSM_BRIGHT_Z6, 0) + const expectedSize = fs.statSync(OSM_BRIGHT_Z6).size + const { Wrapper } = createWrapper({ + getBaseUrl: async () => new URL(server.localBaseUrl), + }) + + const { result } = renderHook(() => useGetCustomMapInfo(), { + wrapper: Wrapper, + }) + + await waitFor(() => { + expect(result.current.data).toBeDefined() + }) + expect(result.current.data).toHaveProperty('name') + expect(result.current.data).toHaveProperty('size', expectedSize) + }) + + it('returns a 404 HTTPError when no custom map exists', async (t) => { + const server = await startTestServer(t) + const { Wrapper } = createWrapper({ + getBaseUrl: async () => new URL(server.localBaseUrl), + }) + + const { result } = renderHook(() => useGetCustomMapInfo(), { + wrapper: Wrapper, + }) + + await waitFor(() => { + expect(result.current.error).not.toBeNull() + }) + + expect(result.current.error).toBeInstanceOf(HTTPError) + expect(result.current.error).toHaveProperty('status', 404) + expect(result.current.error).toHaveProperty('code', 'MAP_NOT_FOUND') + }) + + it('returns a 404 HTTPError after the custom map is removed', async (t) => { + const server = await startTestServer(t, OSM_BRIGHT_Z6, 0) + const { Wrapper } = createWrapper({ + getBaseUrl: async () => new URL(server.localBaseUrl), + }) + + const { result } = renderHook( + () => ({ + mapInfo: useGetCustomMapInfo(), + removeMap: useRemoveCustomMapFile(), + }), + { wrapper: Wrapper }, + ) + + await waitFor(() => { + expect(result.current.mapInfo.data).toBeDefined() + }) + + await act(async () => { + await result.current.removeMap.mutateAsync() + }) + + await waitFor(() => { + expect(result.current.mapInfo.error).not.toBeNull() + }) + + expect(result.current.mapInfo.error).toBeInstanceOf(HTTPError) + expect(result.current.mapInfo.error).toHaveProperty('status', 404) + expect(result.current.mapInfo.error).toHaveProperty( + 'code', + 'MAP_NOT_FOUND', + ) + }) + + it('map info updates after importing a new custom map', async (t) => { + const server = await startTestServer(t, OSM_BRIGHT_Z6, 0) + const { Wrapper } = createWrapper({ + getBaseUrl: async () => new URL(server.localBaseUrl), + }) + + const { result } = renderHook( + () => ({ + mapInfo: useGetCustomMapInfo(), + importMap: useImportCustomMapFile(), + }), + { wrapper: Wrapper }, + ) + + await waitFor(() => { + expect(result.current.mapInfo.data).toBeDefined() + }) + + const infoBefore = result.current.mapInfo.data + + const file = readFixtureAsFile(DEMOTILES_Z2, 'demotiles-z2.smp') + + await act(async () => { + await result.current.importMap.mutateAsync({ file }) + }) + + await waitFor(() => + expect(result.current.mapInfo.data).not.toEqual(infoBefore), + ) + + expect(result.current.mapInfo.data).not.toEqual(infoBefore) + }) + }) }) diff --git a/test/lib/http.test.ts b/test/lib/http.test.ts new file mode 100644 index 0000000..681717c --- /dev/null +++ b/test/lib/http.test.ts @@ -0,0 +1,80 @@ +/** + * @vitest-environment node + */ +import { describe, expect, it } from 'vitest' + +import { createHttp, HTTPError } from '../../src/lib/http.js' + +function mockFetch(status: number, body: unknown, headers?: HeadersInit) { + return async () => + new Response(body === null ? null : JSON.stringify(body), { + status, + headers: { 'Content-Type': 'application/json', ...headers }, + }) +} + +describe('createHttp .json()', () => { + it('returns parsed JSON for 200 OK responses', async () => { + const http = createHttp(mockFetch(200, { foo: 'bar' })) + const result = await http.get('http://example.com').json() + expect(result).toEqual({ foo: 'bar' }) + }) + + it('returns empty string for 204 No Content', async () => { + const http = createHttp(async () => new Response(null, { status: 204 })) + const result = await http.get('http://example.com').json() + expect(result).toBe('') + }) + + it('throws a HTTPError for 404 responses', async () => { + const errorBody = { message: 'Not found' } + const http = createHttp(mockFetch(404, errorBody)) + + await expect(http.get('http://example.com').json()).rejects.toThrow( + HTTPError, + ) + }) + + it('includes status code and body in the thrown HTTPError', async () => { + const errorBody = { message: 'Map not found' } + const http = createHttp(mockFetch(404, errorBody)) + + let thrownError: unknown + try { + await http.get('http://example.com').json() + } catch (e) { + thrownError = e + } + + expect(thrownError).toBeInstanceOf(HTTPError) + expect(thrownError).toHaveProperty('status', 404) + expect(thrownError).toHaveProperty('message', 'Map not found') + }) + + it('throws a HTTPError for 500 responses', async () => { + const http = createHttp( + mockFetch(500, { message: 'Internal server error' }), + ) + + let thrownError: unknown + try { + await http.get('http://example.com').json() + } catch (e) { + thrownError = e + } + + expect(thrownError).toBeInstanceOf(HTTPError) + expect(thrownError).toHaveProperty('status', 500) + }) + + it('rethrows non-HTTP errors (e.g. network errors)', async () => { + const networkError = new TypeError('Failed to fetch') + const http = createHttp(async () => { + throw networkError + }) + + await expect(http.get('http://example.com').json()).rejects.toBe( + networkError, + ) + }) +}) diff --git a/test/lib/map-shares-test-utils.ts b/test/lib/map-shares-test-utils.ts new file mode 100644 index 0000000..ffc853d --- /dev/null +++ b/test/lib/map-shares-test-utils.ts @@ -0,0 +1,233 @@ +/** + * Shared test utilities for map shares store tests. + */ +import fs from 'node:fs/promises' +import os from 'node:os' +import path from 'node:path' +import { fileURLToPath } from 'node:url' +import type { MapShare } from '@comapeo/core' +import { + createServer, + type MapShareState as ServerMapShareState, +} from '@comapeo/map-server' +import ky from 'ky' +import { Agent as SecretStreamAgent } from 'secret-stream-http' +import { uint8ArrayToHex } from 'uint8array-extras' +import { vi } from 'vitest' + +import { + createMapServerApi, + type MapServerApi, +} from '../../src/contexts/MapServer.js' + +const __dirname = path.dirname(fileURLToPath(import.meta.url)) +const FIXTURES_DIR = path.join(__dirname, '../fixtures') +export const OSM_BRIGHT_Z6 = path.join(FIXTURES_DIR, 'osm-bright-z6.smp') +export const DEMOTILES_Z2 = path.join(FIXTURES_DIR, 'demotiles-z2.smp') +export const ONLINE_STYLE_URL = 'https://demotiles.maplibre.org/style.json' + +export type ServerInstance = { + get: (typeof ky)['get'] + post: (typeof ky)['post'] + localBaseUrl: string + remotePort: number + deviceId: string + eventsPath: (id: string) => string + mapServerApi: MapServerApi +} + +let tmpCounter = 0 + +export async function startTestServer( + t: { onTestFinished: (fn: () => Promise) => void }, + customMapPath?: string, + seed = 0, +) { + const tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'map-server-test-')) + const tmpCustomMapPath = path.join(tmpDir, `custom-map-${tmpCounter++}.smp`) + + if (customMapPath) { + await fs.copyFile(customMapPath, tmpCustomMapPath) + } + + const keyPair = SecretStreamAgent.keyPair(Buffer.alloc(32, seed)) + const server = createServer({ + defaultOnlineStyleUrl: ONLINE_STYLE_URL, + fallbackMapPath: DEMOTILES_Z2, + customMapPath: tmpCustomMapPath, + keyPair, + }) + + t.onTestFinished(async () => { + await fs.unlink(tmpCustomMapPath).catch(() => {}) + await fs.rm(tmpDir, { recursive: true, force: true }).catch(() => {}) + await server.close() + }) + + const { localPort, remotePort } = await server.listen() + const localBaseUrl = `http://127.0.0.1:${localPort}` + + return { + localPort, + remotePort, + localBaseUrl, + keyPair, + deviceId: uint8ArrayToHex(keyPair.publicKey), + } +} + +export async function startTestServers(t: { + onTestFinished: (fn: () => Promise) => void +}) { + const [sender, receiver] = await Promise.all([ + startTestServer(t, OSM_BRIGHT_Z6, 0), + startTestServer(t, DEMOTILES_Z2, 1), + ]) + + const kyDefaults = ky.create({ retry: 0, throwHttpErrors: false }) + const senderKy = kyDefaults.extend({ prefixUrl: sender.localBaseUrl }) + const receiverKy = kyDefaults.extend({ prefixUrl: receiver.localBaseUrl }) + + const senderInstance: ServerInstance = { + get: senderKy.get.bind(senderKy), + post: senderKy.post.bind(senderKy), + localBaseUrl: sender.localBaseUrl, + remotePort: sender.remotePort, + deviceId: sender.deviceId, + eventsPath: (id: string) => `/mapShares/${id}/events`, + mapServerApi: createMapServerApi({ + getBaseUrl: async () => new URL(sender.localBaseUrl), + }), + } + + const receiverInstance: ServerInstance = { + get: receiverKy.get.bind(receiverKy), + post: receiverKy.post.bind(receiverKy), + localBaseUrl: receiver.localBaseUrl, + remotePort: receiver.remotePort, + deviceId: receiver.deviceId, + eventsPath: (id: string) => `/downloads/${id}/events`, + mapServerApi: createMapServerApi({ + getBaseUrl: async () => new URL(receiver.localBaseUrl), + }), + } + + const createShare = () => + senderKy + .post('mapShares', { + json: { + mapId: 'custom', + receiverDeviceId: receiverInstance.deviceId, + }, + }) + .json() + + return { + sender: senderInstance, + receiver: receiverInstance, + createShare, + } +} + +export type MockClientApi = { + on: ReturnType + off: ReturnType + emit: (event: string, data: unknown) => void + listeners: Map void>> + getProject: ReturnType + $sendMapShare: ReturnType + invite: { + addListener: ReturnType + removeListener: ReturnType + } +} + +export function createMockClientApi(): MockClientApi { + const listeners = new Map void>>() + + const on = vi.fn((event: string, listener: (data: unknown) => void) => { + if (!listeners.has(event)) { + listeners.set(event, []) + } + listeners.get(event)!.push(listener) + }) + + const off = vi.fn((event: string, listener: (data: unknown) => void) => { + const eventListeners = listeners.get(event) + if (eventListeners) { + const index = eventListeners.indexOf(listener) + if (index > -1) { + eventListeners.splice(index, 1) + } + } + }) + + const emit = (event: string, data: unknown) => { + const eventListeners = listeners.get(event) + if (eventListeners) { + for (const listener of eventListeners) { + listener(data) + } + } + } + + const $sendMapShare = vi.fn().mockResolvedValue(undefined) + const getProject = vi.fn().mockResolvedValue({ $sendMapShare }) + + const invite = { + addListener: vi.fn(), + removeListener: vi.fn(), + } + + return { on, off, emit, listeners, getProject, $sendMapShare, invite } +} + +/** + * Creates a MapShare object from the server-side share state. + * This simulates what the client would receive from the map-share event. + */ +export function createMapShareFromServerShare( + senderDeviceId: string, + serverShare: ServerMapShareState, +): MapShare { + return { + ...serverShare, + mapShareReceivedAt: Date.now(), + senderDeviceId, + senderDeviceName: 'Test Sender', + } +} + +/** + * Waits for a store state to match a predicate. + */ +export async function waitForStoreState( + store: { + getSnapshot: () => T + subscribe: (listener: () => void) => () => void + }, + predicate: (state: T) => boolean, + timeoutMs = 5000, +): Promise { + return new Promise((resolve, reject) => { + const timeout = setTimeout(() => { + unsubscribe() + reject(new Error(`Timed out waiting for store state`)) + }, timeoutMs) + + if (predicate(store.getSnapshot())) { + clearTimeout(timeout) + resolve() + return + } + + const unsubscribe = store.subscribe(() => { + const state = store.getSnapshot() + if (predicate(state)) { + clearTimeout(timeout) + unsubscribe() + resolve() + } + }) + }) +} diff --git a/test/lib/received-map-shares-store.test.ts b/test/lib/received-map-shares-store.test.ts new file mode 100644 index 0000000..331bd82 --- /dev/null +++ b/test/lib/received-map-shares-store.test.ts @@ -0,0 +1,611 @@ +/** + * @vitest-environment node + */ +import { setTimeout as delay } from 'node:timers/promises' +import type { MapShare } from '@comapeo/core' +import type { MapShareState as ServerMapShareState } from '@comapeo/map-server' +import { beforeEach, describe, expect, it, vi } from 'vitest' + +import { + createReceivedMapSharesStore, + createSentMapSharesStore, + type ReceivedMapSharesStore, + type SentMapSharesStore, +} from '../../src/lib/map-shares-stores.js' +import { + createMapShareFromServerShare, + createMockClientApi, + startTestServers, + waitForStoreState, + type MockClientApi, + type ServerInstance, +} from './map-shares-test-utils.js' + +describe('ReceivedMapSharesStore', () => { + let mockClientApi: MockClientApi + let sender: ServerInstance + let receiver: ServerInstance + let store: ReceivedMapSharesStore + let createShare: () => Promise + + beforeEach(async (t) => { + mockClientApi = createMockClientApi() + const servers = await startTestServers(t) + sender = servers.sender + receiver = servers.receiver + createShare = servers.createShare + + store = createReceivedMapSharesStore({ + // @ts-expect-error - We're only mocking what we need + clientApi: mockClientApi, + mapServerApi: receiver.mapServerApi, + }) + }) + + describe('initial state', () => { + it('should start with an empty array of map shares', () => { + expect(store.getSnapshot()).toEqual([]) + }) + + it('should register a listener for map-share events on clientApi', () => { + expect(mockClientApi.on).toHaveBeenCalledWith( + 'map-share', + expect.any(Function), + ) + }) + }) + + describe('map-share event handling', () => { + it('should add a new map share when map-share event is emitted', async () => { + const serverShare = await createShare() + const mapShare = createMapShareFromServerShare( + sender.deviceId, + serverShare, + ) + + const listener = vi.fn() + store.subscribe(listener) + + mockClientApi.emit('map-share', mapShare) + + expect(listener).toHaveBeenCalledTimes(1) + const snapshot = store.getSnapshot() + expect(snapshot).toHaveLength(1) + expect(snapshot[0]).toMatchObject({ + shareId: mapShare.shareId, + senderDeviceId: sender.deviceId, + status: 'pending', + }) + }) + + it('should handle multiple map shares', async () => { + const serverShare1 = await createShare() + const serverShare2 = await createShare() + + const mapShare1 = createMapShareFromServerShare( + sender.deviceId, + serverShare1, + ) + const mapShare2 = createMapShareFromServerShare( + sender.deviceId, + serverShare2, + ) + + mockClientApi.emit('map-share', mapShare1) + mockClientApi.emit('map-share', mapShare2) + + const snapshot = store.getSnapshot() + expect(snapshot).toHaveLength(2) + expect(snapshot[0]).toHaveProperty('shareId', mapShare1.shareId) + expect(snapshot[1]).toHaveProperty('shareId', mapShare2.shareId) + }) + }) + + describe('download', () => { + it('should complete the download and update status', async () => { + const serverShare = await createShare() + const mapShare = createMapShareFromServerShare( + sender.deviceId, + serverShare, + ) + + mockClientApi.emit('map-share', mapShare) + + const downloadPromise = store.actions.download({ + shareId: mapShare.shareId, + }) + + // synchronous store update to 'downloading' status + expect(store.getSnapshot()[0]).toHaveProperty('status', 'downloading') + + await expect(downloadPromise).resolves.toBeUndefined() + + await waitForStoreState( + store, + (state) => state[0]?.status === 'completed', + ) + + // Check that status is completed + const snapshot = store.getSnapshot() + expect(snapshot[0]).toHaveProperty('status', 'completed') + }) + + it('should throw when downloading a non-existent share', async () => { + await expect(() => + store.actions.download({ shareId: 'non-existent-share-id' }), + ).rejects.toThrow('Map share with id non-existent-share-id not found') + }) + }) + + describe('decline', () => { + it('should decline a share and update status', async () => { + const serverShare = await createShare() + const mapShare = createMapShareFromServerShare( + sender.deviceId, + serverShare, + ) + + mockClientApi.emit('map-share', mapShare) + + const listener = vi.fn() + store.subscribe(listener) + + const declinePromise = store.actions.decline({ + shareId: mapShare.shareId, + reason: 'user_rejected', + }) + + // Check that status is immediately set to declined + const snapshot = store.getSnapshot() + expect(snapshot[0]).toHaveProperty('status', 'declined') + expect(snapshot[0]).toHaveProperty('reason', 'user_rejected') + + await expect(declinePromise).resolves.toBeUndefined() + + // Check on the sender side that the share was declined + const senderShare = (await sender + .get(`mapShares/${serverShare.shareId}`) + .json()) as ServerMapShareState + expect(senderShare.status).toBe('declined') + expect(senderShare).toHaveProperty('reason', 'user_rejected') + }) + + it('should throw when declining a non-existent share', async () => { + await expect(() => + store.actions.decline({ + shareId: 'non-existent-share-id', + reason: 'user_rejected', + }), + ).rejects.toThrow('Map share with id non-existent-share-id not found') + }) + }) + + describe('abort', () => { + it('should abort a download and update status', async () => { + const serverShare = await createShare() + const mapShare = createMapShareFromServerShare( + sender.deviceId, + serverShare, + ) + + mockClientApi.emit('map-share', mapShare) + + // Start the download + await store.actions.download({ shareId: mapShare.shareId }) + + const abortPromise = store.actions.abort({ shareId: mapShare.shareId }) + const snapshot = store.getSnapshot() + expect(snapshot[0]?.status).toBe('aborted') + + await expect(abortPromise).resolves.toBeUndefined() + + // Check on the sender side that the map share was aborted + await delay(100) // Wait a bit for the abort to be processed on the server + const senderShare = (await sender + .get(`mapShares/${serverShare.shareId}`) + .json()) as ServerMapShareState + expect(senderShare.status).toBe('aborted') + }) + + it('should throw when aborting a non-existent share', async () => { + await expect(() => + store.actions.abort({ shareId: 'non-existent-share-id' }), + ).rejects.toThrow('Map share with id non-existent-share-id not found') + }) + }) + + describe('invalid status transitions', () => { + it('should not allow download or abort after decline', async () => { + const serverShare = await createShare() + const mapShare = createMapShareFromServerShare( + sender.deviceId, + serverShare, + ) + + mockClientApi.emit('map-share', mapShare) + + // Decline the share (status: pending -> declined) + await store.actions.decline({ + shareId: mapShare.shareId, + reason: 'user_rejected', + }) + + // Now trying to download should throw because declined -> downloading is not allowed + await expect(() => + store.actions.download({ shareId: mapShare.shareId }), + ).rejects.toThrow( + 'Invalid status transition from declined to downloading', + ) + // Trying to abort should also throw because declined -> aborted is not allowed + await expect(() => + store.actions.abort({ shareId: mapShare.shareId }), + ).rejects.toThrow('Invalid status transition from declined to aborted') + + const snapshot = store.getSnapshot() + expect(snapshot[0]?.status).toBe('declined') + }) + + it('should not allow abort before download starts', async () => { + const serverShare = await createShare() + const mapShare = createMapShareFromServerShare( + sender.deviceId, + serverShare, + ) + + mockClientApi.emit('map-share', mapShare) + + // Trying to abort before download should throw because pending -> aborted is not allowed + await expect(() => + store.actions.abort({ shareId: mapShare.shareId }), + ).rejects.toThrow('Invalid status transition from pending to aborted') + const snapshot = store.getSnapshot() + expect(snapshot[0]?.status).toBe('pending') + }) + + it('should not allow decline after download starts', async () => { + const serverShare = await createShare() + const mapShare = createMapShareFromServerShare( + sender.deviceId, + serverShare, + ) + + mockClientApi.emit('map-share', mapShare) + + // Start the download + await store.actions.download({ shareId: mapShare.shareId }) + + // Now trying to decline should throw because downloading -> declined is not allowed + await expect(() => + store.actions.decline({ + shareId: mapShare.shareId, + reason: 'user_rejected', + }), + ).rejects.toThrow( + 'Invalid status transition from downloading to declined', + ) + + const snapshot = store.getSnapshot() + expect(snapshot[0]?.status).toBe('downloading') + }) + + it('should not allow any action after completion', async () => { + const serverShare = await createShare() + const mapShare = createMapShareFromServerShare( + sender.deviceId, + serverShare, + ) + + mockClientApi.emit('map-share', mapShare) + + // Start the download and wait for completion + await store.actions.download({ shareId: mapShare.shareId }) + await waitForStoreState( + store, + (state) => state[0]?.status === 'completed', + ) + + // Now trying to decline should throw because completed -> declined is not allowed + await expect(() => + store.actions.decline({ + shareId: mapShare.shareId, + reason: 'user_rejected', + }), + ).rejects.toThrow('Invalid status transition from completed to declined') + + // Trying to abort should also throw because completed -> aborted is not allowed + await expect(() => + store.actions.abort({ shareId: mapShare.shareId }), + ).rejects.toThrow('Invalid status transition from completed to aborted') + + // Trying download again should also throw because completed -> downloading is not allowed + await expect(() => + store.actions.download({ shareId: mapShare.shareId }), + ).rejects.toThrow( + 'Invalid status transition from completed to downloading', + ) + + const snapshot = store.getSnapshot() + expect(snapshot[0]?.status).toBe('completed') + }) + }) + + describe('subscription', () => { + it('should notify all subscribers when state changes', async () => { + const serverShare = await createShare() + const mapShare = createMapShareFromServerShare( + sender.deviceId, + serverShare, + ) + + const listener1 = vi.fn() + const listener2 = vi.fn() + const listener3 = vi.fn() + + store.subscribe(listener1) + store.subscribe(listener2) + store.subscribe(listener3) + + mockClientApi.emit('map-share', mapShare) + + expect(listener1).toHaveBeenCalledTimes(1) + expect(listener2).toHaveBeenCalledTimes(1) + expect(listener3).toHaveBeenCalledTimes(1) + }) + + it('should stop notifying after unsubscribe', async () => { + const serverShare = await createShare() + const mapShare = createMapShareFromServerShare( + sender.deviceId, + serverShare, + ) + + const listener = vi.fn() + const unsubscribe = store.subscribe(listener) + + mockClientApi.emit('map-share', mapShare) + expect(listener).toHaveBeenCalledTimes(1) + + unsubscribe() + + // Create another share event + const serverShare2 = await createShare() + const mapShare2 = createMapShareFromServerShare( + sender.deviceId, + serverShare2, + ) + mockClientApi.emit('map-share', mapShare2) + + // Should still be 1 because we unsubscribed + expect(listener).toHaveBeenCalledTimes(1) + }) + }) + + describe('error handling', () => { + it('should update status to error when download fails', async () => { + const serverShare = await createShare() + + // Create a map share with invalid URLs to cause a download error + const mapShare: MapShare = { + ...createMapShareFromServerShare(sender.deviceId, serverShare), + mapShareUrls: ['http://127.0.0.1:80/invalid'] as const, + } + + mockClientApi.emit('map-share', mapShare) + + // Download only rejects if the local download action encounters an error. + // Errors communicating with the remote server are captured in state + // updates. + await store.actions.download({ shareId: mapShare.shareId }) + + await waitForStoreState(store, (state) => state[0]?.status === 'error') + + const snapshot = store.getSnapshot() + expect(snapshot[0]).toHaveProperty('status', 'error') + expect(snapshot[0]).toHaveProperty('error.code', 'DOWNLOAD_ERROR') + }) + }) + + describe('Object.is equality for useSyncExternalStore', () => { + it('should maintain array reference during download progress updates', async () => { + const serverShare = await createShare() + const mapShare = createMapShareFromServerShare( + sender.deviceId, + serverShare, + ) + + mockClientApi.emit('map-share', mapShare) + + // Start the download - synchronously updates status to 'downloading' + const downloadPromise = store.actions.download({ + shareId: mapShare.shareId, + }) + + // Capture the snapshot immediately after download starts + const snapshotAfterDownloadStart = store.getSnapshot() + expect(snapshotAfterDownloadStart[0]).toHaveProperty( + 'status', + 'downloading', + ) + + // Wait for at least one progress update (bytesDownloaded changes while status stays 'downloading') + await new Promise((resolve, reject) => { + const timeout = setTimeout(() => { + unsubscribe() + reject(new Error('Timeout waiting for progress update')) + }, 5000) + + const initialShare = snapshotAfterDownloadStart[0] + const initialBytesDownloaded = + initialShare?.status === 'downloading' + ? initialShare.bytesDownloaded + : 0 + + const unsubscribe = store.subscribe(() => { + const current = store.getSnapshot() + const currentShare = current[0] + if ( + currentShare?.status === 'downloading' && + currentShare.bytesDownloaded > initialBytesDownloaded + ) { + clearTimeout(timeout) + unsubscribe() + + // Array reference should be the same (Object.is equality) + // This is important for useSyncExternalStore - it means components + // listening to the raw array won't re-render on progress updates + // eslint-disable-next-line vitest/no-conditional-expect -- resolve() is also conditional, so test will fail if condition not met + expect(current).toBe(snapshotAfterDownloadStart) + + resolve() + } + }) + }) + + // Wait for download to complete + await downloadPromise + await waitForStoreState( + store, + (state) => state[0]?.status === 'completed', + ) + }) + + it('should update individual map share reference during download progress updates', async () => { + const serverShare = await createShare() + const mapShare = createMapShareFromServerShare( + sender.deviceId, + serverShare, + ) + + mockClientApi.emit('map-share', mapShare) + + // Start the download + const downloadPromise = store.actions.download({ + shareId: mapShare.shareId, + }) + + // Capture the initial map share reference + const initialMapShare = store.getSnapshot()[0] + expect(initialMapShare).toHaveProperty('status', 'downloading') + + // Wait for at least one progress update + await new Promise((resolve, reject) => { + const timeout = setTimeout(() => { + unsubscribe() + reject(new Error('Timeout waiting for progress update')) + }, 5000) + + const initialBytesDownloaded = + initialMapShare?.status === 'downloading' + ? initialMapShare.bytesDownloaded + : 0 + + const unsubscribe = store.subscribe(() => { + const currentShare = store.getSnapshot()[0] + if ( + currentShare?.status === 'downloading' && + currentShare.bytesDownloaded > initialBytesDownloaded + ) { + clearTimeout(timeout) + unsubscribe() + + // Individual map share should be a different object + // This means selectors that return individual map shares will + // correctly trigger re-renders on progress updates + // eslint-disable-next-line vitest/no-conditional-expect -- resolve() is also conditional, so test will fail if condition not met + expect(currentShare).not.toBe(initialMapShare) + + resolve() + } + }) + }) + + // Wait for download to complete + await downloadPromise + await waitForStoreState( + store, + (state) => state[0]?.status === 'completed', + ) + }) + + it('should change array reference for status changes (not progress updates)', async () => { + const serverShare = await createShare() + const mapShare = createMapShareFromServerShare( + sender.deviceId, + serverShare, + ) + + mockClientApi.emit('map-share', mapShare) + + // Capture snapshot before download + const snapshotBeforeDownload = store.getSnapshot() + expect(snapshotBeforeDownload[0]).toHaveProperty('status', 'pending') + + // Start the download + const downloadPromise = store.actions.download({ + shareId: mapShare.shareId, + }) + + // After status change to 'downloading', array reference should be different + const snapshotDuringDownload = store.getSnapshot() + expect(snapshotDuringDownload).not.toBe(snapshotBeforeDownload) + expect(snapshotDuringDownload[0]).toHaveProperty('status', 'downloading') + + // Wait for download to complete + await downloadPromise + await waitForStoreState( + store, + (state) => state[0]?.status === 'completed', + ) + + // After status change to 'completed', array reference should be different again + const snapshotAfterComplete = store.getSnapshot() + expect(snapshotAfterComplete).not.toBe(snapshotDuringDownload) + expect(snapshotAfterComplete[0]).toHaveProperty('status', 'completed') + }) + }) + + describe('event source monitoring', () => { + let senderMockClientApi: MockClientApi + let sentStore: SentMapSharesStore + + beforeEach(() => { + senderMockClientApi = createMockClientApi() + sentStore = createSentMapSharesStore({ + // @ts-expect-error - We're only mocking what we need + clientApi: senderMockClientApi, + mapServerApi: sender.mapServerApi, + }) + }) + + it('should update status when sender cancels during download', async () => { + // Sender creates a share + await sentStore.actions.createAndSend({ + projectId: 'test-project-id', + receiverDeviceId: receiver.deviceId, + mapId: 'custom', + }) + + const serverShare = sentStore.getSnapshot()[0]! + + // Simulate receiver getting the share (as if via comapeo-core event) + const mapShare = createMapShareFromServerShare( + sender.deviceId, + serverShare, + ) + mockClientApi.emit('map-share', mapShare) + + // Receiver starts downloading + await store.actions.download({ shareId: mapShare.shareId }) + expect(store.getSnapshot()[0]).toHaveProperty('status', 'downloading') + + // Sender cancels the share + await sentStore.actions.cancel({ shareId: mapShare.shareId }) + + // Receiver's store should see the status update via EventSource + await waitForStoreState(store, (state) => state[0]?.status === 'canceled') + + const snapshot = store.getSnapshot() + expect(snapshot[0]).toHaveProperty('status', 'canceled') + }) + }) +}) diff --git a/test/lib/sent-map-shares-store.test.ts b/test/lib/sent-map-shares-store.test.ts new file mode 100644 index 0000000..d78bac0 --- /dev/null +++ b/test/lib/sent-map-shares-store.test.ts @@ -0,0 +1,560 @@ +/** + * @vitest-environment node + */ +import type { MapShareState as ServerMapShareState } from '@comapeo/map-server' +import { beforeEach, describe, expect, it, vi } from 'vitest' + +import { + createReceivedMapSharesStore, + createSentMapSharesStore, + type ReceivedMapSharesStore, + type SentMapSharesStore, +} from '../../src/lib/map-shares-stores.js' +import { + createMapShareFromServerShare, + createMockClientApi, + startTestServers, + waitForStoreState, + type MockClientApi, + type ServerInstance, +} from './map-shares-test-utils.js' + +describe('SentMapSharesStore', () => { + let mockClientApi: MockClientApi + let sender: ServerInstance + let receiver: ServerInstance + let sentStore: SentMapSharesStore + + beforeEach(async (t) => { + mockClientApi = createMockClientApi() + const servers = await startTestServers(t) + sender = servers.sender + receiver = servers.receiver + + sentStore = createSentMapSharesStore({ + // @ts-expect-error - We're only mocking what we need + clientApi: mockClientApi, + mapServerApi: sender.mapServerApi, + }) + }) + + describe('initial state', () => { + it('should start with an empty array of map shares', () => { + expect(sentStore.getSnapshot()).toEqual([]) + }) + }) + + describe('create', () => { + it('should create a new map share and add it to the store', async () => { + const listener = vi.fn() + sentStore.subscribe(listener) + + await sentStore.actions.createAndSend({ + projectId: 'test-project-id', + receiverDeviceId: receiver.deviceId, + mapId: 'custom', + }) + + expect(listener).toHaveBeenCalled() + const snapshot = sentStore.getSnapshot() + expect(snapshot).toHaveLength(1) + expect(snapshot[0]).toMatchObject({ + mapId: 'custom', + status: 'pending', + }) + expect(snapshot[0]).toHaveProperty('shareId') + expect(snapshot[0]).toHaveProperty('mapShareUrls') + }) + + it('should call clientApi.getProject and $sendMapShare', async () => { + await sentStore.actions.createAndSend({ + projectId: 'test-project-id', + receiverDeviceId: receiver.deviceId, + mapId: 'custom', + }) + + expect(mockClientApi.getProject).toHaveBeenCalledWith('test-project-id') + expect(mockClientApi.$sendMapShare).toHaveBeenCalledWith( + expect.objectContaining({ + mapId: 'custom', + status: 'pending', + }), + ) + }) + + it('should handle multiple map shares', async () => { + await sentStore.actions.createAndSend({ + projectId: 'test-project-id', + receiverDeviceId: receiver.deviceId, + mapId: 'custom', + }) + + await sentStore.actions.createAndSend({ + projectId: 'test-project-id', + receiverDeviceId: receiver.deviceId, + mapId: 'custom', + }) + + const snapshot = sentStore.getSnapshot() + expect(snapshot).toHaveLength(2) + expect(snapshot[0]?.shareId).not.toBe(snapshot[1]?.shareId) + }) + + it('should create share on the server', async () => { + const { shareId } = await sentStore.actions.createAndSend({ + projectId: 'test-project-id', + receiverDeviceId: receiver.deviceId, + mapId: 'custom', + }) + + // Verify the share exists on the server + const serverShare = (await sender + .get(`mapShares/${shareId}`) + .json()) as ServerMapShareState + + expect(serverShare).toMatchObject({ + shareId, + mapId: 'custom', + status: 'pending', + }) + }) + + it('should cancel the map share on the server if $sendMapShare throws', async () => { + // Make $sendMapShare throw an error + const sendError = new Error('Failed to send map share') + mockClientApi.$sendMapShare.mockRejectedValueOnce(sendError) + + // createAndSend should throw + await expect( + sentStore.actions.createAndSend({ + projectId: 'test-project-id', + receiverDeviceId: receiver.deviceId, + mapId: 'custom', + }), + ).rejects.toThrow('Failed to send map share') + + // The store should be empty since createAndSend failed + expect(sentStore.getSnapshot()).toHaveLength(0) + + // Query the server to find the map share - it should exist and be canceled + const serverShares = (await sender + .get('mapShares') + .json()) as Array + + expect(serverShares).toHaveLength(1) + expect(serverShares[0]).toMatchObject({ + mapId: 'custom', + status: 'canceled', + }) + }) + }) + + describe('cancel', () => { + it('should update status to canceled immediately', async () => { + const { shareId } = await sentStore.actions.createAndSend({ + projectId: 'test-project-id', + receiverDeviceId: receiver.deviceId, + mapId: 'custom', + }) + + const cancelPromise = sentStore.actions.cancel({ shareId }) + + expect(sentStore.getSnapshot()[0]).toHaveProperty('status', 'canceled') + + // Verify the server was called to cancel the share + await expect(cancelPromise).resolves.toBeUndefined() + + expect(sentStore.getSnapshot()[0]).toHaveProperty('status', 'canceled') + }) + + it('should throw when canceling a non-existent share', async () => { + await expect(() => + sentStore.actions.cancel({ shareId: 'non-existent-share-id' }), + ).rejects.toThrow( + expect.objectContaining({ + code: 'MAP_SHARE_NOT_FOUND', + }), + ) + }) + }) + + describe('event source monitoring', () => { + let receiverMockClientApi: MockClientApi + let receivedStore: ReceivedMapSharesStore + + beforeEach(() => { + receiverMockClientApi = createMockClientApi() + receivedStore = createReceivedMapSharesStore({ + // @ts-expect-error - We're only mocking what we need + clientApi: receiverMockClientApi, + mapServerApi: receiver.mapServerApi, + }) + }) + + it('should update status when receiver declines the share', async () => { + // Sender creates a share + const serverShare = await sentStore.actions.createAndSend({ + projectId: 'test-project-id', + receiverDeviceId: receiver.deviceId, + mapId: 'custom', + }) + + // Simulate receiver getting the share (as if via comapeo-core event) + const mapShare = createMapShareFromServerShare( + sender.deviceId, + serverShare, + ) + receiverMockClientApi.emit('map-share', mapShare) + + // Receiver declines the share + await receivedStore.actions.decline({ + shareId: mapShare.shareId, + reason: 'user_rejected', + }) + + // Sender's store should see the status update via EventSource + await waitForStoreState( + sentStore, + (state) => state[0]?.status === 'declined', + ) + + const snapshot = sentStore.getSnapshot() + expect(snapshot[0]).toHaveProperty('status', 'declined') + expect(snapshot[0]).toHaveProperty('reason', 'user_rejected') + + // Also verify the sender's server state was updated + const senderServerShare = (await sender + .get(`mapShares/${serverShare.shareId}`) + .json()) as ServerMapShareState + expect(senderServerShare.status).toBe('declined') + expect(senderServerShare).toHaveProperty('reason', 'user_rejected') + }) + + it('should update status to completed when download finishes', async () => { + // Sender creates a share + const serverShare = await sentStore.actions.createAndSend({ + projectId: 'test-project-id', + receiverDeviceId: receiver.deviceId, + mapId: 'custom', + }) + + // Simulate receiver getting the share + const mapShare = createMapShareFromServerShare( + sender.deviceId, + serverShare, + ) + receiverMockClientApi.emit('map-share', mapShare) + + // Receiver downloads the share + await receivedStore.actions.download({ shareId: mapShare.shareId }) + + // Wait for receiver to complete (the download happens asynchronously) + await waitForStoreState( + receivedStore, + (state) => state[0]?.status === 'completed', + ) + + // Sender's store should see the status update via EventSource + await waitForStoreState( + sentStore, + (state) => state[0]?.status === 'completed', + ) + + const snapshot = sentStore.getSnapshot() + expect(snapshot[0]).toHaveProperty('status', 'completed') + }) + + it('should update status when receiver aborts download', async () => { + // Sender creates a share + const serverShare = await sentStore.actions.createAndSend({ + projectId: 'test-project-id', + receiverDeviceId: receiver.deviceId, + mapId: 'custom', + }) + + // Simulate receiver getting the share + const mapShare = createMapShareFromServerShare( + sender.deviceId, + serverShare, + ) + receiverMockClientApi.emit('map-share', mapShare) + + // Receiver starts the download + await receivedStore.actions.download({ shareId: mapShare.shareId }) + + // Receiver aborts (if still downloading) + const receiverSnapshot = receivedStore.getSnapshot() + expect(receiverSnapshot[0]).toHaveProperty('status', 'downloading') + await receivedStore.actions.abort({ shareId: mapShare.shareId }) + + // Sender's store should see the status update via EventSource + await waitForStoreState( + sentStore, + (state) => state[0]?.status === 'aborted', + ) + + const snapshot = sentStore.getSnapshot() + expect(snapshot[0]).toHaveProperty('status', 'aborted') + }) + + it('should maintain array reference during download progress updates (Object.is equality)', async () => { + // Sender creates a share + const serverShare = await sentStore.actions.createAndSend({ + projectId: 'test-project-id', + receiverDeviceId: receiver.deviceId, + mapId: 'custom', + }) + + // Simulate receiver getting the share + const mapShare = createMapShareFromServerShare( + sender.deviceId, + serverShare, + ) + receiverMockClientApi.emit('map-share', mapShare) + + // Receiver starts the download + await receivedStore.actions.download({ shareId: mapShare.shareId }) + + // Wait for sender to see the downloading status + await waitForStoreState( + sentStore, + (state) => state[0]?.status === 'downloading', + ) + + // Capture the snapshot when downloading starts + const snapshotDuringDownload = sentStore.getSnapshot() + expect(snapshotDuringDownload[0]).toHaveProperty('status', 'downloading') + + // Wait for a progress update (bytesDownloaded changes while status stays 'downloading') + await new Promise((resolve, reject) => { + const timeout = setTimeout(() => { + unsubscribe() + reject(new Error('Timeout waiting for progress update')) + }, 5000) + + const initialShare = snapshotDuringDownload[0] + const initialBytesDownloaded = + initialShare?.status === 'downloading' + ? initialShare.bytesDownloaded + : 0 + + const unsubscribe = sentStore.subscribe(() => { + const current = sentStore.getSnapshot() + const currentShare = current[0] + if ( + currentShare?.status === 'downloading' && + currentShare.bytesDownloaded > initialBytesDownloaded + ) { + clearTimeout(timeout) + unsubscribe() + + // Array reference should be the same (Object.is equality) + // This is important for useSyncExternalStore - components + // listening to the raw array won't re-render on progress updates + // eslint-disable-next-line vitest/no-conditional-expect -- resolve() is also conditional, so test will fail if condition not met + expect(current).toBe(snapshotDuringDownload) + + resolve() + } + }) + }) + + // Wait for download to complete + await waitForStoreState( + sentStore, + (state) => state[0]?.status === 'completed', + ) + }) + + it('should update individual map share reference during download progress updates', async () => { + // Sender creates a share + const serverShare = await sentStore.actions.createAndSend({ + projectId: 'test-project-id', + receiverDeviceId: receiver.deviceId, + mapId: 'custom', + }) + + // Simulate receiver getting the share + const mapShare = createMapShareFromServerShare( + sender.deviceId, + serverShare, + ) + receiverMockClientApi.emit('map-share', mapShare) + + // Receiver starts the download + await receivedStore.actions.download({ shareId: mapShare.shareId }) + + // Wait for sender to see the downloading status + await waitForStoreState( + sentStore, + (state) => state[0]?.status === 'downloading', + ) + + // Capture the initial map share reference + const initialMapShare = sentStore.getSnapshot()[0] + expect(initialMapShare).toHaveProperty('status', 'downloading') + + // Wait for a progress update + await new Promise((resolve, reject) => { + const timeout = setTimeout(() => { + unsubscribe() + reject(new Error('Timeout waiting for progress update')) + }, 5000) + + const initialBytesDownloaded = + initialMapShare?.status === 'downloading' + ? initialMapShare.bytesDownloaded + : 0 + + const unsubscribe = sentStore.subscribe(() => { + const currentShare = sentStore.getSnapshot()[0] + if ( + currentShare?.status === 'downloading' && + currentShare.bytesDownloaded > initialBytesDownloaded + ) { + clearTimeout(timeout) + unsubscribe() + + // Individual map share should be a different object + // This means selectors that return individual map shares will + // correctly trigger re-renders on progress updates + // eslint-disable-next-line vitest/no-conditional-expect -- resolve() is also conditional, so test will fail if condition not met + expect(currentShare).not.toBe(initialMapShare) + + resolve() + } + }) + }) + + // Wait for download to complete + await waitForStoreState( + sentStore, + (state) => state[0]?.status === 'completed', + ) + }) + }) + + describe('invalid status transitions', () => { + let receiverMockClientApi: MockClientApi + let receivedStore: ReceivedMapSharesStore + + beforeEach(() => { + receiverMockClientApi = createMockClientApi() + receivedStore = createReceivedMapSharesStore({ + // @ts-expect-error - We're only mocking what we need + clientApi: receiverMockClientApi, + mapServerApi: receiver.mapServerApi, + }) + }) + + it('should not allow cancel after decline', async () => { + const serverShare = await sentStore.actions.createAndSend({ + projectId: 'test-project-id', + receiverDeviceId: receiver.deviceId, + mapId: 'custom', + }) + + // Simulate receiver getting and declining the share + const mapShare = createMapShareFromServerShare( + sender.deviceId, + serverShare, + ) + receiverMockClientApi.emit('map-share', mapShare) + await receivedStore.actions.decline({ + shareId: mapShare.shareId, + reason: 'user_rejected', + }) + + // Wait for sender to see the decline + await waitForStoreState( + sentStore, + (state) => state[0]?.status === 'declined', + ) + + // Now trying to cancel should throw because declined -> canceled is not allowed + await expect(() => + sentStore.actions.cancel({ shareId: mapShare.shareId }), + ).rejects.toThrow('Invalid status transition from declined to canceled') + + const snapshot = sentStore.getSnapshot() + expect(snapshot[0]?.status).toBe('declined') + }) + + it('should not allow cancel after completion', async () => { + const serverShare = await sentStore.actions.createAndSend({ + projectId: 'test-project-id', + receiverDeviceId: receiver.deviceId, + mapId: 'custom', + }) + + // Simulate receiver getting and downloading the share + const mapShare = createMapShareFromServerShare( + sender.deviceId, + serverShare, + ) + receiverMockClientApi.emit('map-share', mapShare) + await receivedStore.actions.download({ shareId: mapShare.shareId }) + + // Wait for completion + await waitForStoreState( + sentStore, + (state) => state[0]?.status === 'completed', + ) + + // Now trying to cancel should throw because completed -> canceled is not allowed + await expect(() => + sentStore.actions.cancel({ shareId: mapShare.shareId }), + ).rejects.toThrow('Invalid status transition from completed to canceled') + + const snapshot = sentStore.getSnapshot() + expect(snapshot[0]?.status).toBe('completed') + }) + }) + + describe('subscription', () => { + it('should notify all subscribers when state changes', async () => { + const listener1 = vi.fn() + const listener2 = vi.fn() + const listener3 = vi.fn() + + sentStore.subscribe(listener1) + sentStore.subscribe(listener2) + sentStore.subscribe(listener3) + + await sentStore.actions.createAndSend({ + projectId: 'test-project-id', + receiverDeviceId: receiver.deviceId, + mapId: 'custom', + }) + + expect(listener1).toHaveBeenCalled() + expect(listener2).toHaveBeenCalled() + expect(listener3).toHaveBeenCalled() + }) + + it('should stop notifying after unsubscribe', async () => { + const listener = vi.fn() + const unsubscribe = sentStore.subscribe(listener) + + await sentStore.actions.createAndSend({ + projectId: 'test-project-id', + receiverDeviceId: receiver.deviceId, + mapId: 'custom', + }) + + const callCountAfterCreate = listener.mock.calls.length + + unsubscribe() + + // Create another share + await sentStore.actions.createAndSend({ + projectId: 'test-project-id', + receiverDeviceId: receiver.deviceId, + mapId: 'custom', + }) + + // Should still be the same count because we unsubscribed + expect(listener).toHaveBeenCalledTimes(callCountAfterCreate) + }) + }) +}) diff --git a/vitest.config.js b/vitest.config.js index a6ad64e..6c0026c 100644 --- a/vitest.config.js +++ b/vitest.config.js @@ -4,5 +4,6 @@ export default defineConfig({ test: { environment: 'happy-dom', setupFiles: ['./test/setup.ts'], + exclude: ['**/node_modules/**', '**/dist/**'], }, })