]> git.ipfire.org Git - thirdparty/vuejs/router.git/commitdiff
test: migrate to vitest
authorEduardo San Martin Morote <posva13@gmail.com>
Mon, 17 Jun 2024 12:53:12 +0000 (14:53 +0200)
committerEduardo San Martin Morote <posva13@gmail.com>
Mon, 17 Jun 2024 12:53:12 +0000 (14:53 +0200)
53 files changed:
packages/router/__tests__/RouterLink.spec.ts
packages/router/__tests__/RouterView.spec.ts
packages/router/__tests__/__snapshots__/RouterLink.spec.ts.snap
packages/router/__tests__/__snapshots__/RouterView.spec.ts.snap
packages/router/__tests__/encoding.spec.ts
packages/router/__tests__/errors.spec.ts
packages/router/__tests__/guards/afterEach.spec.ts
packages/router/__tests__/guards/beforeEach.spec.ts
packages/router/__tests__/guards/beforeEnter.spec.ts
packages/router/__tests__/guards/beforeResolve.spec.ts
packages/router/__tests__/guards/beforeRouteEnter.spec.ts
packages/router/__tests__/guards/beforeRouteEnterCallback.spec.ts
packages/router/__tests__/guards/beforeRouteLeave.spec.ts
packages/router/__tests__/guards/beforeRouteUpdate.spec.ts
packages/router/__tests__/guards/extractComponentsGuards.spec.ts
packages/router/__tests__/guards/guardToPromiseFn.spec.ts
packages/router/__tests__/guards/guardsContext.spec.ts
packages/router/__tests__/guards/loadRouteLocation.spec.ts
packages/router/__tests__/guards/navigatioGuardsInjections.spec.ts
packages/router/__tests__/guards/onBeforeRouteLeave.spec.ts
packages/router/__tests__/guards/onBeforeRouteUpdate.spec.ts
packages/router/__tests__/hash-manual-navigation.spec.ts
packages/router/__tests__/history/hash.spec.ts
packages/router/__tests__/history/html5.spec.ts
packages/router/__tests__/history/memory.spec.ts
packages/router/__tests__/initialNavigation.spec.ts
packages/router/__tests__/isReady.spec.ts
packages/router/__tests__/lazyLoading.spec.ts
packages/router/__tests__/location.spec.ts
packages/router/__tests__/matcher/__snapshots__/resolve.spec.ts.snap
packages/router/__tests__/matcher/addingRemoving.spec.ts
packages/router/__tests__/matcher/pathParser.spec.ts
packages/router/__tests__/matcher/pathRanking.spec.ts
packages/router/__tests__/matcher/records.spec.ts
packages/router/__tests__/matcher/resolve.spec.ts
packages/router/__tests__/multipleApps.spec.ts
packages/router/__tests__/parseQuery.spec.ts
packages/router/__tests__/router.spec.ts
packages/router/__tests__/scrollBehavior.spec.ts
packages/router/__tests__/ssr.spec.ts
packages/router/__tests__/stringifyQuery.spec.ts
packages/router/__tests__/urlEncoding.spec.ts
packages/router/__tests__/useApi.spec.ts
packages/router/__tests__/useLink.spec.ts
packages/router/__tests__/vitest-mock-warn.ts [new file with mode: 0644]
packages/router/__tests__/warnings.spec.ts
packages/router/jest.config.js [deleted file]
packages/router/package.json
packages/router/size-checks/webRouterAndVue.js
packages/router/tsconfig.json
packages/router/vitest.config.ts [new file with mode: 0644]
packages/router/vitest.workspace.js [new file with mode: 0644]
pnpm-lock.yaml

index 608c2e882c0f7863d39ab6f86d5488c150a3b97d..bf87c2de7261853edbd6bcd18264fba9bf167302 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * @jest-environment jsdom
+ * @vitest-environment jsdom
  */
 import { RouterLink } from '../src/RouterLink'
 import { RouteQueryAndHash, MatcherLocationRaw } from '../src/types'
@@ -16,6 +16,7 @@ import { RouteRecordNormalized } from '../src/matcher/types'
 import { routerKey } from '../src/injectionSymbols'
 import { tick } from './utils'
 import { mount } from '@vue/test-utils'
+import { vi, describe, expect, it } from 'vitest'
 
 const records = {
   home: {} as RouteRecordNormalized,
@@ -366,9 +367,9 @@ async function factory(
       return this.history.base + to.fullPath
     },
     options: {} as Partial<RouterOptions>,
-    resolve: jest.fn(),
-    push: jest.fn().mockResolvedValue(resolvedLocation),
-    replace: jest.fn().mockResolvedValue(resolvedLocation),
+    resolve: vi.fn(),
+    push: vi.fn().mockResolvedValue(resolvedLocation),
+    replace: vi.fn().mockResolvedValue(resolvedLocation),
   }
   router.resolve.mockReturnValueOnce(resolvedLocation)
 
@@ -800,7 +801,7 @@ describe('RouterLink', () => {
   })
 
   it('allows adding more click listeners', async () => {
-    const onClick = jest.fn()
+    const onClick = vi.fn()
     const { router, wrapper } = await factory(
       START_LOCATION_NORMALIZED,
       { to: locations.basic.string, onClick },
@@ -944,8 +945,8 @@ describe('RouterLink', () => {
             return this.history.base + to.fullPath
           },
           options: {} as Partial<RouterOptions>,
-          resolve: jest.fn(),
-          push: jest.fn().mockResolvedValue(resolvedLocation),
+          resolve: vi.fn(),
+          push: vi.fn().mockResolvedValue(resolvedLocation),
         }
         router.resolve.mockReturnValueOnce(resolvedLocation)
 
index c41084c151242d60ba420d1e11afbb9d116ea5ec..6f142b9f166877f0c806a9cbdf60297df1aee419 100644 (file)
@@ -1,14 +1,15 @@
 /**
- * @jest-environment jsdom
+ * @vitest-environment jsdom
  */
 import { RouterView } from '../src/RouterView'
 import { components, RouteLocationNormalizedLoose } from './utils'
 import { START_LOCATION_NORMALIZED } from '../src/location'
 import { markRaw } from 'vue'
 import { createMockedRoute } from './mount'
-import { mockWarn } from 'jest-mock-warn'
 import { mount } from '@vue/test-utils'
 import { RouteLocationNormalized } from '../src'
+import { describe, expect, it } from 'vitest'
+import { mockWarn } from './vitest-mock-warn'
 
 // to have autocompletion
 function createRoutes<T extends Record<string, RouteLocationNormalizedLoose>>(
index ad84946d93ae7716d5042da2babbbf3c6bb8c385..bdeda41b167fcd20f19952f1440874582c085627 100644 (file)
@@ -1,3 +1,3 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
 
-exports[`RouterLink v-slot provides information on v-slot 1`] = `"<a aria-current="page" href="/home" class="router-link-active router-link-exact-active"><span> route: {"href":"/home","fullPath":"/home","path":"/home","params":{},"meta":{},"query":{},"hash":"","matched":[{}],"name":"home"} href: "/home" isActive: "true" isExactActive: "true" </span></a>"`;
+exports[`RouterLink > v-slot > provides information on v-slot 1`] = `"<a aria-current="page" href="/home" class="router-link-active router-link-exact-active"><span> route: {"href":"/home","fullPath":"/home","path":"/home","params":{},"meta":{},"query":{},"hash":"","matched":[{}],"name":"home"} href: "/home" isActive: "true" isExactActive: "true" </span></a>"`;
index 49f60569b9c8f2f040eecbab46b82d9f9e9ca118..15c8bd2031b42b48b1f63862f4e0d2d78ad397b4 100644 (file)
@@ -1,6 +1,6 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
 
-exports[`RouterView displays deeply nested views 1`] = `
+exports[`RouterView displays deeply nested views 1`] = `
 "<div>
   <h2>Nested</h2>
   <div>
@@ -10,19 +10,19 @@ exports[`RouterView displays deeply nested views 1`] = `
 </div>"
 `;
 
-exports[`RouterView displays nested views 1`] = `
+exports[`RouterView displays nested views 1`] = `
 "<div>
   <h2>Nested</h2>
   <div>Foo</div>
 </div>"
 `;
 
-exports[`RouterView v-slot passes a Component and route 1`] = `
+exports[`RouterView > v-slot > passes a Component and route 1`] = `
 "<span>home</span>
 <div>Home</div>"
 `;
 
-exports[`RouterView warnings does not warn RouterView is wrapped 1`] = `
+exports[`RouterView > warnings > does not warn RouterView is wrapped 1`] = `
 "<div>
   <div>Home</div>
 </div>"
index d299ac3a81a0abf3c0d945d8d059b5c56463c715..e4aebb88dd7532b010d00dfce83a0bb8107c402e 100644 (file)
@@ -5,6 +5,7 @@ import {
   encodeQueryValue,
   // decode,
 } from '../src/encoding'
+import { describe, expect, it } from 'vitest'
 
 describe('Encoding', () => {
   // all ascii chars with a non ascii char at the beginning
index 952059ad436df514a8815322ce1613720d39c24b..5678bf43faa874b0280baa02a4b418d8b79da467 100644 (file)
@@ -13,8 +13,9 @@ import type {
   RouteLocationRaw,
   RouteLocationNormalized,
 } from '../src/typed-routes'
-import { mockWarn } from 'jest-mock-warn'
 import { START_LOCATION_NORMALIZED } from '../src/location'
+import { vi, describe, expect, it, beforeEach } from 'vitest'
+import { mockWarn } from './vitest-mock-warn'
 
 const routes: Readonly<RouteRecordRaw>[] = [
   { path: '/', component: components.Home },
@@ -25,8 +26,8 @@ const routes: Readonly<RouteRecordRaw>[] = [
   { path: '/async', component: () => Promise.reject('failed') },
 ]
 
-const onError = jest.fn()
-const afterEach = jest.fn()
+const onError = vi.fn()
+const afterEach = vi.fn()
 function createRouter() {
   const history = createMemoryHistory()
   const router = newRouter({
index d4200486030e7363906c576845e1f89fd80c7ef8..8709b76fc063f922adb6945e043c1eb7e3be8af8 100644 (file)
@@ -1,5 +1,6 @@
 import { createDom, newRouter as createRouter } from '../utils'
-import { RouteRecordRaw } from 'src/types'
+import { RouteRecordRaw } from '../../src/types'
+import { vi, describe, expect, it, beforeAll } from 'vitest'
 
 const Home = { template: `<div>Home</div>` }
 const Foo = { template: `<div>Foo</div>` }
@@ -24,7 +25,7 @@ describe('router.afterEach', () => {
   })
 
   it('calls afterEach guards on push', async () => {
-    const spy = jest.fn()
+    const spy = vi.fn()
     const router = createRouter({ routes })
     router.afterEach(spy)
     await router.push('/foo')
@@ -37,7 +38,7 @@ describe('router.afterEach', () => {
   })
 
   it('can be removed', async () => {
-    const spy = jest.fn()
+    const spy = vi.fn()
     const router = createRouter({ routes })
     const remove = router.afterEach(spy)
     remove()
@@ -46,7 +47,7 @@ describe('router.afterEach', () => {
   })
 
   it('calls afterEach guards on multiple push', async () => {
-    const spy = jest.fn()
+    const spy = vi.fn()
     const router = createRouter({ routes })
     await router.push('/nested')
     router.afterEach(spy)
@@ -67,8 +68,8 @@ describe('router.afterEach', () => {
   })
 
   it('removing an afterEach guard within one does not affect others', async () => {
-    const spy1 = jest.fn()
-    const spy2 = jest.fn()
+    const spy1 = vi.fn()
+    const spy2 = vi.fn()
     const router = createRouter({ routes })
     router.afterEach(spy1)
     const remove = router.afterEach(spy2)
index 579eb1f943a46af0eb928e38443f0e1fcf5345cb..b4e373606cffa1d1fd3552088f1df446c3fff19b 100644 (file)
@@ -2,6 +2,7 @@ import fakePromise from 'faked-promise'
 import { createDom, tick, noGuard, newRouter as createRouter } from '../utils'
 import { RouteRecordRaw } from '../../src/types'
 import { RouteLocationRaw } from '../../src'
+import { vi, describe, expect, it, beforeAll } from 'vitest'
 
 const Home = { template: `<div>Home</div>` }
 const Foo = { template: `<div>Foo</div>` }
@@ -32,7 +33,7 @@ describe('router.beforeEach', () => {
   })
 
   it('calls beforeEach guards on navigation', async () => {
-    const spy = jest.fn()
+    const spy = vi.fn()
     const router = createRouter({ routes })
     router.beforeEach(spy)
     spy.mockImplementationOnce(noGuard)
@@ -41,7 +42,7 @@ describe('router.beforeEach', () => {
   })
 
   it('can be removed', async () => {
-    const spy = jest.fn()
+    const spy = vi.fn()
     const router = createRouter({ routes })
     const remove = router.beforeEach(spy)
     remove()
@@ -51,7 +52,7 @@ describe('router.beforeEach', () => {
   })
 
   it('does not call beforeEach guard if we were already on the page', async () => {
-    const spy = jest.fn()
+    const spy = vi.fn()
     const router = createRouter({ routes })
     await router.push('/foo')
     router.beforeEach(spy)
@@ -61,7 +62,7 @@ describe('router.beforeEach', () => {
   })
 
   it('calls beforeEach guards on navigation between children routes', async () => {
-    const spy = jest.fn()
+    const spy = vi.fn()
     const router = createRouter({ routes })
     await router.push('/nested')
     router.beforeEach(spy)
@@ -83,7 +84,7 @@ describe('router.beforeEach', () => {
   })
 
   it('can redirect to a different location', async () => {
-    const spy = jest.fn()
+    const spy = vi.fn()
     const router = createRouter({ routes })
     await router.push('/foo')
     spy.mockImplementation((to, from, next) => {
@@ -125,7 +126,7 @@ describe('router.beforeEach', () => {
       return
     })
 
-    const spy = jest.spyOn(history, 'pushState')
+    const spy = vi.spyOn(history, 'pushState')
     await router.push({ path: '/', state: { a: 'a' } })
     expect(spy).toHaveBeenCalledTimes(1)
     // called before redirect
@@ -142,7 +143,7 @@ describe('router.beforeEach', () => {
     const router = createRouter({ routes })
     await router.push('/foo')
 
-    const spy = jest.spyOn(history, 'pushState')
+    const spy = vi.spyOn(history, 'pushState')
     await router.push({ path: '/redirect', state: { a: 'a' } })
     expect(spy).toHaveBeenCalledTimes(1)
     // called before redirect
@@ -156,7 +157,7 @@ describe('router.beforeEach', () => {
   })
 
   async function assertRedirect(redirectFn: (i: string) => RouteLocationRaw) {
-    const spy = jest.fn()
+    const spy = vi.fn()
     const router = createRouter({ routes })
     await router.push('/')
     spy.mockImplementation((to, from, next) => {
@@ -185,7 +186,7 @@ describe('router.beforeEach', () => {
   })
 
   it('is called when changing params', async () => {
-    const spy = jest.fn()
+    const spy = vi.fn()
     const router = createRouter({ routes: [...routes] })
     await router.push('/n/2')
     spy.mockImplementation(noGuard)
@@ -196,7 +197,7 @@ describe('router.beforeEach', () => {
   })
 
   it('is not called with same params', async () => {
-    const spy = jest.fn()
+    const spy = vi.fn()
     const router = createRouter({ routes: [...routes] })
     await router.push('/n/2')
     spy.mockImplementation(noGuard)
@@ -224,7 +225,7 @@ describe('router.beforeEach', () => {
     const [p1, r1] = fakePromise()
     const [p2, r2] = fakePromise()
     const router = createRouter({ routes })
-    const guard1 = jest.fn()
+    const guard1 = vi.fn()
     let order = 0
     guard1.mockImplementationOnce(async (to, from, next) => {
       expect(order++).toBe(0)
@@ -232,7 +233,7 @@ describe('router.beforeEach', () => {
       next()
     })
     router.beforeEach(guard1)
-    const guard2 = jest.fn()
+    const guard2 = vi.fn()
     guard2.mockImplementationOnce(async (to, from, next) => {
       expect(order++).toBe(1)
       await p2
@@ -256,7 +257,7 @@ describe('router.beforeEach', () => {
   })
 
   it('adds meta information', async () => {
-    const spy = jest.fn()
+    const spy = vi.fn()
     const router = createRouter({ routes })
     router.beforeEach(spy)
     spy.mockImplementationOnce(noGuard)
index 913b0d041f5e1055b3a7fb6cff41c2d0daeecc19..1df476eee3c2d9b62f6c7f06aebb6fcea8693d2e 100644 (file)
@@ -1,20 +1,21 @@
 import fakePromise from 'faked-promise'
 import { createDom, noGuard, tick, newRouter as createRouter } from '../utils'
 import { RouteRecordRaw } from '../../src/types'
+import { vi, describe, expect, it, beforeAll, beforeEach } from 'vitest'
 
 const Home = { template: `<div>Home</div>` }
 const Foo = { template: `<div>Foo</div>` }
 
-const beforeEnter = jest.fn()
-const beforeEnters = [jest.fn(), jest.fn()]
+const beforeEnter = vi.fn()
+const beforeEnters = [vi.fn(), vi.fn()]
 const nested = {
-  parent: jest.fn(),
-  nestedEmpty: jest.fn(),
-  nestedA: jest.fn(),
-  nestedAbs: jest.fn(),
-  nestedNested: jest.fn(),
-  nestedNestedFoo: jest.fn(),
-  nestedNestedParam: jest.fn(),
+  parent: vi.fn(),
+  nestedEmpty: vi.fn(),
+  nestedA: vi.fn(),
+  nestedAbs: vi.fn(),
+  nestedNested: vi.fn(),
+  nestedNestedFoo: vi.fn(),
+  nestedNestedParam: vi.fn(),
 }
 
 const routes: RouteRecordRaw[] = [
index a0dbeaed4d2c88397a860e1523e7ba7f925b2e82..9736b520e99340cfcc307c02f28e6d1385f327c3 100644 (file)
@@ -1,5 +1,6 @@
 import { createDom, noGuard, newRouter as createRouter } from '../utils'
 import { RouteRecordRaw } from '../../src/types'
+import { vi, describe, expect, it, beforeAll } from 'vitest'
 
 const Home = { template: `<div>Home</div>` }
 const Foo = { template: `<div>Foo</div>` }
@@ -15,7 +16,7 @@ describe('router.beforeEach', () => {
   })
 
   it('calls beforeEach guards on navigation', async () => {
-    const spy = jest.fn()
+    const spy = vi.fn()
     const router = createRouter({ routes })
     router.beforeResolve(spy)
     spy.mockImplementationOnce(noGuard)
index 0af22f070f0f9971843d3c7e1c741a9bd8c1454a..02c87ecd5bf1c10d79f94841a32eb24d75715dcb 100644 (file)
@@ -1,27 +1,28 @@
 import fakePromise from 'faked-promise'
 import { createDom, noGuard, newRouter as createRouter } from '../utils'
 import type { RouteRecordRaw, NavigationGuard } from '../../src'
+import { vi, describe, expect, it, beforeAll, beforeEach } from 'vitest'
 
 const Home = { template: `<div>Home</div>` }
 const Foo = { template: `<div>Foo</div>` }
 
-const beforeRouteEnter = jest.fn<
-  ReturnType<NavigationGuard>,
-  Parameters<NavigationGuard>
+const beforeRouteEnter = vi.fn<
+  Parameters<NavigationGuard>,
+  ReturnType<NavigationGuard>
 >()
 const named = {
-  default: jest.fn(),
-  other: jest.fn(),
+  default: vi.fn(),
+  other: vi.fn(),
 }
 
 const nested = {
-  parent: jest.fn(),
-  nestedEmpty: jest.fn(),
-  nestedA: jest.fn(),
-  nestedAbs: jest.fn(),
-  nestedNested: jest.fn(),
-  nestedNestedFoo: jest.fn(),
-  nestedNestedParam: jest.fn(),
+  parent: vi.fn(),
+  nestedEmpty: vi.fn(),
+  nestedA: vi.fn(),
+  nestedAbs: vi.fn(),
+  nestedNested: vi.fn(),
+  nestedNestedFoo: vi.fn(),
+  nestedNestedParam: vi.fn(),
 }
 
 const routes: RouteRecordRaw[] = [
@@ -123,7 +124,7 @@ describe('beforeRouteEnter', () => {
 
   it('does not call beforeRouteEnter guards on navigation between aliases', async () => {
     const router = createRouter({ routes })
-    const spy = jest.fn()
+    const spy = vi.fn()
     beforeRouteEnter.mockImplementation(spy)
     await router.push('/guard/valid')
     expect(beforeRouteEnter).toHaveBeenCalledTimes(1)
index b9918c48a83399c99264f5e5037a36ddb67c7ec7..d851c7c3f186ee2845ba30d02366d5b6256a460f 100644 (file)
@@ -1,13 +1,14 @@
 /**
- * @jest-environment jsdom
+ * @vitest-environment jsdom
  */
 import { defineComponent, h } from 'vue'
 import { mount } from '@vue/test-utils'
 import { createRouter, createMemoryHistory, RouterOptions } from '../../src'
+import { vi, describe, expect, it, beforeEach } from 'vitest'
 
 const nextCallbacks = {
-  Default: jest.fn(),
-  Other: jest.fn(),
+  Default: vi.fn(),
+  Other: vi.fn(),
 }
 const Default = defineComponent({
   beforeRouteEnter(to, from, next) {
index ff5618337002ad757ff45e74ac2135769e588777..57dd78158f13e8fd8f85151ccc31dc1c87e0dbbf 100644 (file)
@@ -1,20 +1,21 @@
 import { createDom, noGuard, newRouter as createRouter } from '../utils'
 import { RouteRecordRaw } from '../../src/types'
+import { vi, describe, expect, it, beforeAll, beforeEach } from 'vitest'
 
 const Home = { template: `<div>Home</div>` }
 const Foo = { template: `<div>Foo</div>` }
 
 const nested = {
-  parent: jest.fn(),
-  nestedEmpty: jest.fn(),
-  nestedA: jest.fn(),
-  nestedB: jest.fn(),
-  nestedAbs: jest.fn(),
-  nestedNested: jest.fn(),
-  nestedNestedFoo: jest.fn(),
-  nestedNestedParam: jest.fn(),
+  parent: vi.fn(),
+  nestedEmpty: vi.fn(),
+  nestedA: vi.fn(),
+  nestedB: vi.fn(),
+  nestedAbs: vi.fn(),
+  nestedNested: vi.fn(),
+  nestedNestedFoo: vi.fn(),
+  nestedNestedParam: vi.fn(),
 }
-const beforeRouteLeave = jest.fn()
+const beforeRouteLeave = vi.fn()
 
 const routes: RouteRecordRaw[] = [
   { path: '/', component: Home },
index 5d98f21e57a63c9dd310c97ae05a4e2b1966dd6d..d4cbf98eb9626a2bd1e175076bec06d0f7db5e55 100644 (file)
@@ -1,11 +1,12 @@
 import fakePromise from 'faked-promise'
 import { createDom, noGuard, newRouter as createRouter } from '../utils'
 import { RouteRecordRaw } from '../../src/types'
+import { vi, describe, expect, it, beforeAll, beforeEach } from 'vitest'
 
 const Home = { template: `<div>Home</div>` }
 const Foo = { template: `<div>Foo</div>` }
 
-const beforeRouteUpdate = jest.fn()
+const beforeRouteUpdate = vi.fn()
 const routes: RouteRecordRaw[] = [
   { path: '/', component: Home },
   { path: '/foo', component: Foo },
index dee5c7587f4b638a208f64e5c062a8943e8ffb7b..1d11c6e7122653f41b7385b1f2b4936ade54b585 100644 (file)
@@ -3,9 +3,10 @@ import type { RouteRecordRaw, RouteRecordNormalized } from '../../src'
 import { START_LOCATION_NORMALIZED } from '../../src/location'
 import { components } from '../utils'
 import { normalizeRouteRecord } from '../../src/matcher'
-import { mockWarn } from 'jest-mock-warn'
+import { mockWarn } from '../vitest-mock-warn'
+import { vi, describe, expect, it, beforeEach } from 'vitest'
 
-const beforeRouteEnter = jest.fn()
+const beforeRouteEnter = vi.fn()
 
 // stub those two
 const to = START_LOCATION_NORMALIZED
index b95d47c71692c0808948836f3feb038d8c276524..d192677935e115160d2cdec8be6147207a5c8bff 100644 (file)
@@ -1,7 +1,8 @@
 import { guardToPromiseFn } from '../../src/navigationGuards'
 import { START_LOCATION_NORMALIZED } from '../../src/location'
 import { ErrorTypes } from '../../src/errors'
-import { mockWarn } from 'jest-mock-warn'
+import { mockWarn } from '../vitest-mock-warn'
+import { vi, describe, expect, it } from 'vitest'
 
 // stub those two
 const to = START_LOCATION_NORMALIZED
@@ -15,7 +16,7 @@ describe('guardToPromiseFn', () => {
   mockWarn()
   it('calls the guard with to, from and, next', async () => {
     expect.assertions(2)
-    const spy = jest.fn((to, from, next) => next())
+    const spy = vi.fn((to, from, next) => next())
     await expect(guardToPromiseFn(spy, to, from)()).resolves.toEqual(undefined)
     expect(spy).toHaveBeenCalledWith(to, from, expect.any(Function))
   })
index 7900f9f3b5c7bfeaf2a9df2085a2e73aae24b8dd..9eb59b80b1779e9f1f8e02e71a146e56d83a828b 100644 (file)
@@ -1,8 +1,9 @@
 /**
- * @jest-environment jsdom
+ * @vitest-environment jsdom
  */
 import { createRouter, createMemoryHistory } from '../../src'
 import { createApp, defineComponent } from 'vue'
+import { vi, describe, expect, it } from 'vitest'
 
 const component = {
   template: '<div>Generic</div>',
@@ -11,7 +12,7 @@ const component = {
 describe('beforeRouteLeave', () => {
   it('invokes with the component context', async () => {
     expect.assertions(2)
-    const spy = jest
+    const spy = vi
       .fn()
       .mockImplementationOnce(function (this: any, to, from, next) {
         expect(typeof this.counter).toBe('number')
@@ -53,7 +54,7 @@ describe('beforeRouteLeave', () => {
       template: `text`,
       // we use data to check if the context is the right one because saving `this` in a variable logs a few warnings
       data: () => ({ counter: 0 }),
-      beforeRouteLeave: jest
+      beforeRouteLeave: vi
         .fn()
         .mockImplementationOnce(function (this: any, to, from, next) {
           expect(typeof this.counter).toBe('number')
@@ -64,7 +65,7 @@ describe('beforeRouteLeave', () => {
       template: `text`,
       // we use data to check if the context is the right one because saving `this` in a variable logs a few warnings
       data: () => ({ counter: 0 }),
-      beforeRouteLeave: jest
+      beforeRouteLeave: vi
         .fn()
         .mockImplementationOnce(function (this: any, to, from, next) {
           expect(typeof this.counter).toBe('number')
@@ -107,7 +108,7 @@ describe('beforeRouteLeave', () => {
       template: `<router-view/>`,
       // we use data to check if the context is the right one because saving `this` in a variable logs a few warnings
       data: () => ({ counter: 0 }),
-      beforeRouteLeave: jest
+      beforeRouteLeave: vi
         .fn()
         .mockImplementationOnce(function (this: any, to, from, next) {
           expect(typeof this.counter).toBe('number')
@@ -118,7 +119,7 @@ describe('beforeRouteLeave', () => {
       template: `text`,
       // we use data to check if the context is the right one because saving `this` in a variable logs a few warnings
       data: () => ({ counter: 0 }),
-      beforeRouteLeave: jest
+      beforeRouteLeave: vi
         .fn()
         .mockImplementationOnce(function (this: any, to, from, next) {
           expect(typeof this.counter).toBe('number')
@@ -166,7 +167,7 @@ describe('beforeRouteLeave', () => {
       `,
       // we use data to check if the context is the right one because saving `this` in a variable logs a few warnings
       data: () => ({ counter: 0 }),
-      beforeRouteLeave: jest
+      beforeRouteLeave: vi
         .fn()
         .mockImplementationOnce(function (this: any, to, from, next) {
           expect(typeof this.counter).toBe('number')
@@ -177,7 +178,7 @@ describe('beforeRouteLeave', () => {
       template: `text`,
       // we use data to check if the context is the right one because saving `this` in a variable logs a few warnings
       data: () => ({ counter: 0 }),
-      beforeRouteLeave: jest
+      beforeRouteLeave: vi
         .fn()
         .mockImplementationOnce(function (this: any, to, from, next) {
           expect(typeof this.counter).toBe('number')
@@ -188,7 +189,7 @@ describe('beforeRouteLeave', () => {
       template: `text`,
       // we use data to check if the context is the right one because saving `this` in a variable logs a few warnings
       data: () => ({ counter: 0 }),
-      beforeRouteLeave: jest
+      beforeRouteLeave: vi
         .fn()
         .mockImplementationOnce(function (this: any, to, from, next) {
           expect(typeof this.counter).toBe('number')
@@ -234,7 +235,7 @@ describe('beforeRouteLeave', () => {
 describe('beforeRouteUpdate', () => {
   it('invokes with the component context', async () => {
     expect.assertions(2)
-    const spy = jest
+    const spy = vi
       .fn()
       .mockImplementationOnce(function (this: any, to, from, next) {
         expect(typeof this.counter).toBe('number')
index 6e6b5e7debac1aef0e5d5ee9609f7c2cabd8c270..e4d98612b9a02958f3b961570c8d1950f239f71a 100644 (file)
@@ -3,6 +3,7 @@ import { RouteRecordRaw } from '../../src/types'
 import { components } from '../utils'
 import { RouteLocationRaw, createMemoryHistory, createRouter } from '../../src'
 import { FunctionalComponent } from 'vue'
+import { describe, expect, it } from 'vitest'
 
 const FunctionalHome: FunctionalComponent = () => null
 FunctionalHome.displayName = 'Home'
@@ -93,7 +94,7 @@ describe('loadRouteLocation', () => {
 
   it('works with nested routes with redirect', async () => {
     expect.assertions(2)
-    testLoadRoute(
+    await testLoadRoute(
       [
         {
           path: '/',
@@ -105,7 +106,7 @@ describe('loadRouteLocation', () => {
       ],
       '/foo'
     )
-    testLoadRoute(
+    await testLoadRoute(
       [
         {
           path: '/',
index fe20236bec3f633f375ab06a33ff2d5bd7149e2e..f6a0e52aa30134bcdbc1dc4d9afae7495a0320b6 100644 (file)
@@ -1,11 +1,12 @@
 /**
- * @jest-environment jsdom
+ * @vitest-environment jsdom
  */
 import { createDom, newRouter as createRouter } from '../utils'
 import { mount } from '@vue/test-utils'
 import { inject } from 'vue'
-import { mockWarn } from 'jest-mock-warn'
+import { mockWarn } from '../vitest-mock-warn'
 import type { Router } from '../../src'
+import { describe, expect, it, beforeAll } from 'vitest'
 
 describe('inject() within navigation guards', () => {
   mockWarn()
index 7fd60c632c140e0e51a8dc600b9bec09f9e2ef39..a244874f9d9ebfe9b87d56a5976dc410f4349639 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * @jest-environment jsdom
+ * @vitest-environment jsdom
  */
 import {
   createRouter,
@@ -7,6 +7,7 @@ import {
   onBeforeRouteLeave,
 } from '../../src'
 import { createApp, defineComponent } from 'vue'
+import { vi, describe, expect, it } from 'vitest'
 
 const component = {
   template: '<div>Generic</div>',
@@ -14,7 +15,7 @@ const component = {
 
 describe('onBeforeRouteLeave', () => {
   it('removes guards when leaving the route', async () => {
-    const spy = jest.fn()
+    const spy = vi.fn()
     const WithLeave = defineComponent({
       template: `text`,
       setup() {
index af11c91a21cde10b055be64d2a498733e53236bf..f2d278e86c5385362beb64fdb26df56bf36f1e14 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * @jest-environment jsdom
+ * @vitest-environment jsdom
  */
 import {
   createRouter,
@@ -11,13 +11,14 @@ import {
 import { defineComponent, h, ComponentOptions, FunctionalComponent } from 'vue'
 import { mount } from '@vue/test-utils'
 import { delay } from '../utils'
+import { vi, describe, expect, it } from 'vitest'
 
 const component = {
   template: '<div>Generic</div>',
 }
 
 function withSpy(name?: string, isAsync = false) {
-  const spy = jest.fn()
+  const spy = vi.fn()
   const Component = defineComponent({
     name,
     template: `<p>${name || 'No Name'}</p>`,
index a465bb30929041d7354485028a5ee9eb003e7a18..9a0887c43e003de1adf3e1938ffe23719cdaae49 100644 (file)
@@ -1,5 +1,6 @@
 import { createMemoryHistory, createRouter, RouterHistory } from '../src'
 import { tick } from './utils'
+import { describe, expect, it } from 'vitest'
 
 const component = {}
 
@@ -34,7 +35,7 @@ describe('hash history edge cases', () => {
       return
     })
 
-    // const spy = jest.spyOn(history, 'go')
+    // const spy = vi.spyOn(history, 'go')
 
     history.changeURL('/')
     await tick()
@@ -71,7 +72,7 @@ describe('hash history edge cases', () => {
       return
     })
 
-    // const spy = jest.spyOn(history, 'go')
+    // const spy = vi.spyOn(history, 'go')
 
     history.changeURL('/')
     await tick()
index 43a299c15c84435bbfef05f35229385e544923d4..65cc6dfddc30942743cb2326a7c201be595c6af4 100644 (file)
@@ -2,12 +2,23 @@ import { JSDOM } from 'jsdom'
 import { createWebHashHistory } from '../../src/history/hash'
 import { createWebHistory } from '../../src/history/html5'
 import { createDom } from '../utils'
-import { mockWarn } from 'jest-mock-warn'
-
-jest.mock('../../src/history/html5')
+import { mockWarn } from '../vitest-mock-warn'
+import {
+  vi,
+  describe,
+  expect,
+  it,
+  beforeAll,
+  beforeEach,
+  Mock,
+  afterAll,
+  afterEach,
+} from 'vitest'
+
+vi.mock('../../src/history/html5')
 // override the value of isBrowser because the variable is created before JSDOM
 // is created
-jest.mock('../../src/utils/env', () => ({
+vi.mock('../../src/utils/env', () => ({
   isBrowser: true,
 }))
 
@@ -19,7 +30,7 @@ describe('History Hash', () => {
   mockWarn()
 
   beforeEach(() => {
-    ;(createWebHistory as jest.Mock).mockClear()
+    ;(createWebHistory as Mock).mockClear()
   })
 
   afterAll(() => {
index 4eb446a3677c6ee7fe27c40822eab0d8aa2b8d17..88bc12f6502d96fc07a66bc9163a89c511a1e50f 100644 (file)
@@ -1,10 +1,20 @@
 import { JSDOM } from 'jsdom'
 import { createWebHistory } from '../../src/history/html5'
 import { createDom } from '../utils'
+import {
+  vi,
+  describe,
+  expect,
+  it,
+  beforeAll,
+  beforeEach,
+  afterAll,
+  afterEach,
+} from 'vitest'
 
 // override the value of isBrowser because the variable is created before JSDOM
 // is created
-jest.mock('../../src/utils/env', () => ({
+vi.mock('../../src/utils/env', () => ({
   isBrowser: true,
 }))
 
@@ -89,7 +99,7 @@ describe('History HTMl5', () => {
 
   it('prepends the host to support // urls', () => {
     let history = createWebHistory()
-    let spy = jest.spyOn(window.history, 'pushState')
+    let spy = vi.spyOn(window.history, 'pushState')
     history.push('/foo')
     expect(spy).toHaveBeenCalledWith(
       expect.anything(),
@@ -108,7 +118,7 @@ describe('History HTMl5', () => {
   describe('specific to base containing a hash', () => {
     it('calls push with hash part of the url with a base', () => {
       dom.reconfigure({ url: 'file:///usr/etc/index.html' })
-      let initialSpy = jest.spyOn(window.history, 'replaceState')
+      let initialSpy = vi.spyOn(window.history, 'replaceState')
       let history = createWebHistory('#')
       // initial navigation
       expect(initialSpy).toHaveBeenCalledWith(
@@ -116,7 +126,7 @@ describe('History HTMl5', () => {
         expect.any(String),
         '#/'
       )
-      let spy = jest.spyOn(window.history, 'pushState')
+      let spy = vi.spyOn(window.history, 'pushState')
       history.push('/foo')
       expect(spy).toHaveBeenCalledWith(
         expect.anything(),
@@ -129,7 +139,7 @@ describe('History HTMl5', () => {
 
     it('works with something after the hash in the base', () => {
       dom.reconfigure({ url: 'file:///usr/etc/index.html' })
-      let initialSpy = jest.spyOn(window.history, 'replaceState')
+      let initialSpy = vi.spyOn(window.history, 'replaceState')
       let history = createWebHistory('#something')
       // initial navigation
       expect(initialSpy).toHaveBeenCalledWith(
@@ -137,7 +147,7 @@ describe('History HTMl5', () => {
         expect.any(String),
         '#something/'
       )
-      let spy = jest.spyOn(window.history, 'pushState')
+      let spy = vi.spyOn(window.history, 'pushState')
       history.push('/foo')
       expect(spy).toHaveBeenCalledWith(
         expect.anything(),
@@ -150,7 +160,7 @@ describe('History HTMl5', () => {
 
     it('works with #! and on a file with initial location', () => {
       dom.reconfigure({ url: 'file:///usr/etc/index.html#!/foo' })
-      let spy = jest.spyOn(window.history, 'replaceState')
+      let spy = vi.spyOn(window.history, 'replaceState')
       createWebHistory('#!')
       expect(spy).toHaveBeenCalledWith(
         expect.anything(),
@@ -162,7 +172,7 @@ describe('History HTMl5', () => {
 
     it('works with #other', () => {
       dom.reconfigure({ url: 'file:///usr/etc/index.html' })
-      let spy = jest.spyOn(window.history, 'replaceState')
+      let spy = vi.spyOn(window.history, 'replaceState')
       createWebHistory('#other')
       expect(spy).toHaveBeenCalledWith(
         expect.anything(),
@@ -174,7 +184,7 @@ describe('History HTMl5', () => {
 
     it('works with custom#other in domain', () => {
       dom.reconfigure({ url: 'https://esm.dev/custom' })
-      let spy = jest.spyOn(window.history, 'replaceState')
+      let spy = vi.spyOn(window.history, 'replaceState')
       createWebHistory('custom#other')
       expect(spy).toHaveBeenCalledWith(
         expect.anything(),
@@ -186,7 +196,7 @@ describe('History HTMl5', () => {
 
     it('works with #! and a host with initial location', () => {
       dom.reconfigure({ url: 'https://esm.dev/#!/foo' })
-      let spy = jest.spyOn(window.history, 'replaceState')
+      let spy = vi.spyOn(window.history, 'replaceState')
       createWebHistory('/#!')
       expect(spy).toHaveBeenCalledWith(
         expect.anything(),
index a1fab235114ffc6d030070547ea0d5c545d5792e..6a6b19d25302fd06cfbdd278c9e0c998f8063748 100644 (file)
@@ -1,5 +1,6 @@
 import { createMemoryHistory } from '../../src/history/memory'
 import { START, HistoryLocation } from '../../src/history/common'
+import { vi, describe, expect, it } from 'vitest'
 
 const loc: HistoryLocation = '/foo'
 
@@ -26,7 +27,7 @@ describe('Memory history', () => {
 
   it('does not trigger listeners with push', () => {
     const history = createMemoryHistory()
-    const spy = jest.fn()
+    const spy = vi.fn()
     history.listen(spy)
     history.push(loc)
     expect(spy).not.toHaveBeenCalled()
@@ -34,7 +35,7 @@ describe('Memory history', () => {
 
   it('does not trigger listeners with replace', () => {
     const history = createMemoryHistory()
-    const spy = jest.fn()
+    const spy = vi.fn()
     history.listen(spy)
     history.replace(loc)
     expect(spy).not.toHaveBeenCalled()
@@ -91,7 +92,7 @@ describe('Memory history', () => {
 
   it('can listen to navigations', () => {
     const history = createMemoryHistory()
-    const spy = jest.fn()
+    const spy = vi.fn()
     history.listen(spy)
     history.push(loc)
     history.go(-1)
@@ -112,8 +113,8 @@ describe('Memory history', () => {
 
   it('can stop listening to navigation', () => {
     const history = createMemoryHistory()
-    const spy = jest.fn()
-    const spy2 = jest.fn()
+    const spy = vi.fn()
+    const spy2 = vi.fn()
     // remove right away
     history.listen(spy)()
     const remove = history.listen(spy2)
@@ -129,8 +130,8 @@ describe('Memory history', () => {
 
   it('removing the same listener is a noop', () => {
     const history = createMemoryHistory()
-    const spy = jest.fn()
-    const spy2 = jest.fn()
+    const spy = vi.fn()
+    const spy2 = vi.fn()
     const rem = history.listen(spy)
     const rem2 = history.listen(spy2)
     rem()
@@ -149,7 +150,7 @@ describe('Memory history', () => {
   it('removes all listeners with destroy', () => {
     const history = createMemoryHistory()
     history.push('/other')
-    const spy = jest.fn()
+    const spy = vi.fn()
     history.listen(spy)
     history.destroy()
     history.push('/2')
@@ -177,7 +178,7 @@ describe('Memory history', () => {
 
   it('can avoid listeners with back and forward', () => {
     const history = createMemoryHistory()
-    const spy = jest.fn()
+    const spy = vi.fn()
     history.listen(spy)
     history.push(loc)
     history.go(-1, false)
index 04ee5cbaabc0d2d59657eca94c7c0c9bb2f79810..c30d7fd3422608fe99b5f591dcfc439144ad59b0 100644 (file)
@@ -2,10 +2,11 @@ import { JSDOM } from 'jsdom'
 import { createRouter, createWebHistory } from '../src'
 import { createDom, components, nextNavigation } from './utils'
 import { RouteRecordRaw } from '../src/types'
+import { describe, expect, it, beforeAll, vi, afterAll } from 'vitest'
 
 // override the value of isBrowser because the variable is created before JSDOM
 // is created
-jest.mock('../src/utils/env', () => ({
+vi.mock('../src/utils/env', () => ({
   isBrowser: true,
 }))
 
index cad258a008c953637711d73d5db8d61b9ed3c21b..fb559e7e5881962b2c6372bc2ae6f51cbf834a60 100644 (file)
@@ -1,6 +1,7 @@
 import { createMemoryHistory, createRouter } from '../src'
 import { components } from './utils'
 import { RouteRecordRaw } from '../src/types'
+import { vi, describe, expect, it } from 'vitest'
 
 // generic component because we are not displaying anything so it doesn't matter
 const component = components.Home
@@ -49,7 +50,7 @@ describe('isReady', () => {
 
   it('rejects when an error is thrown in a navigation guard', async () => {
     const router = newRouter()
-    const errorSpy = jest.fn()
+    const errorSpy = vi.fn()
     const error = new Error('failed')
     router.onError(errorSpy)
     const remove = router.beforeEach(async () => {
@@ -75,7 +76,7 @@ describe('isReady', () => {
 
   it('rejects a cancelled navigation', async () => {
     const router = newRouter()
-    const errorSpy = jest.fn()
+    const errorSpy = vi.fn()
     router.onError(errorSpy)
     const remove = router.beforeEach(() => false)
     router.push('/foo').catch(() => {})
@@ -102,7 +103,7 @@ describe('isReady', () => {
 
   it('rejects failed lazy loading', async () => {
     const router = newRouter()
-    const errorSpy = jest.fn()
+    const errorSpy = vi.fn()
     router.onError(errorSpy)
     router.push('/fail-lazy').catch(() => {})
     await expect(router.isReady()).rejects.toEqual(expect.any(Error))
index 09e97b178553e2a25009510e6c6f4da60bcdeb89..03665566cd1d905b6b18217abc7c3e6907546fd4 100644 (file)
@@ -4,7 +4,16 @@ import { RouterOptions } from '../src/router'
 import { RouteComponent } from '../src/types'
 import { ticks } from './utils'
 import { FunctionalComponent, h } from 'vue'
-import { mockWarn } from 'jest-mock-warn'
+import { mockWarn } from './vitest-mock-warn'
+import {
+  vi,
+  describe,
+  expect,
+  it,
+  beforeEach,
+  MockInstance,
+  afterEach,
+} from 'vitest'
 
 function newRouter(options: Partial<RouterOptions> = {}) {
   let history = createMemoryHistory()
@@ -17,7 +26,7 @@ function createLazyComponent() {
   const [promise, resolve, reject] = fakePromise()
 
   return {
-    component: jest.fn(() => promise.then(() => ({} as RouteComponent))),
+    component: vi.fn(() => promise.then(() => ({} as RouteComponent))),
     promise,
     resolve,
     reject,
@@ -26,9 +35,9 @@ function createLazyComponent() {
 
 describe('Lazy Loading', () => {
   mockWarn()
-  let consoleErrorSpy: jest.SpyInstance
+  let consoleErrorSpy: MockInstance
   beforeEach(() => {
-    consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(() => {})
+    consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {})
   })
 
   afterEach(() => {
@@ -150,7 +159,7 @@ describe('Lazy Loading', () => {
 
   it('avoid fetching async component if navigation is cancelled through beforeEnter', async () => {
     const { component, resolve } = createLazyComponent()
-    const spy = jest.fn((to, from, next) => next(false))
+    const spy = vi.fn((to, from, next) => next(false))
     const { router } = newRouter({
       routes: [
         {
@@ -178,7 +187,7 @@ describe('Lazy Loading', () => {
       ],
     })
 
-    const spy = jest.fn((to, from, next) => next(false))
+    const spy = vi.fn((to, from, next) => next(false))
 
     router.beforeEach(spy)
 
@@ -190,8 +199,8 @@ describe('Lazy Loading', () => {
 
   it('invokes beforeRouteEnter after lazy loading the component', async () => {
     const { promise, resolve } = createLazyComponent()
-    const spy = jest.fn((to, from, next) => next())
-    const component = jest.fn(() =>
+    const spy = vi.fn((to, from, next) => next())
+    const component = vi.fn(() =>
       promise.then(() => ({ beforeRouteEnter: spy }))
     )
     const { router } = newRouter({
@@ -206,8 +215,8 @@ describe('Lazy Loading', () => {
 
   it('beforeRouteLeave works on a lazy loaded component', async () => {
     const { promise, resolve } = createLazyComponent()
-    const spy = jest.fn((to, from, next) => next())
-    const component = jest.fn(() =>
+    const spy = vi.fn((to, from, next) => next())
+    const component = vi.fn(() =>
       promise.then(() => ({ beforeRouteLeave: spy }))
     )
     const { router } = newRouter({
@@ -231,8 +240,8 @@ describe('Lazy Loading', () => {
 
   it('beforeRouteUpdate works on a lazy loaded component', async () => {
     const { promise, resolve } = createLazyComponent()
-    const spy = jest.fn((to, from, next) => next())
-    const component = jest.fn(() =>
+    const spy = vi.fn((to, from, next) => next())
+    const component = vi.fn(() =>
       promise.then(() => ({ beforeRouteUpdate: spy }))
     )
     const { router } = newRouter({
@@ -257,7 +266,7 @@ describe('Lazy Loading', () => {
       routes: [{ path: '/foo', component }],
     })
 
-    const spy = jest.fn()
+    const spy = vi.fn()
 
     const error = new Error('fail')
     reject(error)
@@ -279,7 +288,7 @@ describe('Lazy Loading', () => {
       routes: [{ path: '/foo', component }],
     })
 
-    const spy = jest.fn()
+    const spy = vi.fn()
 
     reject()
     await router.push('/foo').catch(spy)
@@ -306,7 +315,7 @@ describe('Lazy Loading', () => {
       ],
     })
 
-    const spy = jest.fn()
+    const spy = vi.fn()
 
     parent.resolve()
     const error = new Error()
index 08e111bff2fcf024e88d51cd069fbe4d9cc84744..8ccd8a4255755c0583c645581a76956662f4f4fe 100644 (file)
@@ -8,7 +8,8 @@ import {
   resolveRelativePath,
 } from '../src/location'
 import { RouteLocationNormalizedLoaded } from 'src'
-import { mockWarn } from 'jest-mock-warn'
+import { vi, describe, expect, it } from 'vitest'
+import { mockWarn } from './vitest-mock-warn'
 
 describe('parseURL', () => {
   let parseURL = originalParseURL.bind(null, parseQuery)
@@ -149,7 +150,7 @@ describe('parseURL', () => {
   })
 
   it('calls parseQuery', () => {
-    const parseQuery = jest.fn()
+    const parseQuery = vi.fn()
     originalParseURL(parseQuery, '/?é=é&é=a')
     expect(parseQuery).toHaveBeenCalledTimes(1)
     expect(parseQuery).toHaveBeenCalledWith('é=é&é=a')
@@ -214,7 +215,7 @@ describe('stringifyURL', () => {
   })
 
   it('calls stringifyQuery', () => {
-    const stringifyQuery = jest.fn()
+    const stringifyQuery = vi.fn()
     originalStringifyURL(stringifyQuery, {
       path: '/',
       query: { Ã©: 'é', b: 'a' },
index d2ffdb9c23bbbd90961458c41f22e8e316180b22..090cc8bc3de0ab132b994dc06f1fa4e86946c1d2 100644 (file)
@@ -1,11 +1,11 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
 
-exports[`RouterMatcher.resolve LocationAsName throws if the named route does not exists 1`] = `
+exports[`RouterMatcher.resolve > LocationAsName > throws if the named route does not exists 1`] = `
 [Error: No match for
  {"name":"Home"}]
 `;
 
-exports[`RouterMatcher.resolve LocationAsRelative throws if the current named route does not exists 1`] = `
+exports[`RouterMatcher.resolve > LocationAsRelative > throws if the current named route does not exists 1`] = `
 [Error: No match for
  {"params":{"a":"foo"}}
 while being at
index 33626210571eda9508ec311693fd43b8a3851d0c..5c48b867644881627345af3eb66a449ec6fa48bc 100644 (file)
@@ -1,6 +1,7 @@
 import { createRouterMatcher } from '../../src/matcher'
 import { MatcherLocation } from '../../src/types'
-import { mockWarn } from 'jest-mock-warn'
+import { mockWarn } from '../vitest-mock-warn'
+import { describe, expect, it } from 'vitest'
 
 const currentLocation = { path: '/' } as MatcherLocation
 // @ts-expect-error
index 6cff8d4ecf918b2adefe499d5466cdcddb55c25b..5ed7ed40667e779aea8c8c1f7040de01aeaa88b4 100644 (file)
@@ -1,5 +1,6 @@
 import { tokenizePath, TokenType } from '../../src/matcher/pathTokenizer'
 import { tokensToParser } from '../../src/matcher/pathParserRanker'
+import { describe, expect, it } from 'vitest'
 
 describe('Path parser', () => {
   describe('tokenizer', () => {
index a5d4d46a1e227ac164ad0eb487cade57f38bb695..230c3a182997c849089453cfc5357106c95c397d 100644 (file)
@@ -3,6 +3,7 @@ import {
   tokensToParser,
   comparePathParserScore,
 } from '../../src/matcher/pathParserRanker'
+import { describe, expect, it } from 'vitest'
 
 type PathParserOptions = Parameters<typeof tokensToParser>[1]
 
index 698edcdfb9597552cfbd11e63f20aa458b4e1a97..92d45908410614fb1a605a60b57b3d8f0c937e04 100644 (file)
@@ -1,4 +1,5 @@
 import { normalizeRouteRecord } from '../../src/matcher'
+import { vi, describe, expect, it } from 'vitest'
 
 describe('normalizeRouteRecord', () => {
   it('transforms a single view into multiple views', () => {
@@ -22,7 +23,7 @@ describe('normalizeRouteRecord', () => {
   })
 
   it('keeps original values in single view', () => {
-    const beforeEnter = jest.fn()
+    const beforeEnter = vi.fn()
     const record = normalizeRouteRecord({
       path: '/home',
       beforeEnter,
@@ -64,7 +65,7 @@ describe('normalizeRouteRecord', () => {
   })
 
   it('keeps original values in multiple views', () => {
-    const beforeEnter = jest.fn()
+    const beforeEnter = vi.fn()
     const record = normalizeRouteRecord({
       path: '/home',
       beforeEnter,
index 517c679bb7d50da05c5697e35db9e5264cf957d0..2b9c4e7ae7112ac7524ca2e04c7c3adc8fda25bb 100644 (file)
@@ -6,9 +6,10 @@ import {
   MatcherLocation,
 } from '../../src/types'
 import { MatcherLocationNormalizedLoose } from '../utils'
-import { mockWarn } from 'jest-mock-warn'
-import { defineComponent } from '@vue/runtime-core'
+import { defineComponent } from 'vue'
 import { START_LOCATION_NORMALIZED } from '../../src/location'
+import { mockWarn } from '../vitest-mock-warn'
+import { describe, expect, it } from 'vitest'
 
 const component: RouteComponent = defineComponent({})
 
index 1158048e898f5db9392f517319506619f668a589..664cd08afc2529ca0cef695242634c6795aac6ff 100644 (file)
@@ -1,7 +1,7 @@
 import { createRouter, createMemoryHistory } from '../src'
 import { h } from 'vue'
 import { createDom } from './utils'
-// import { mockWarn } from 'jest-mock-warn'
+import { vi, describe, expect, it, beforeAll } from 'vitest'
 
 const delay = (t: number) => new Promise(resolve => setTimeout(resolve, t))
 
@@ -34,7 +34,7 @@ describe('Multiple apps', () => {
   it('does not listen to url changes before being ready', async () => {
     const { router, history } = newRouter()
 
-    const spy = jest.fn((to, from, next) => {
+    const spy = vi.fn((to, from, next) => {
       next()
     })
     router.beforeEach(spy)
index b16c86245e3309843669915f19a28dd6aea649ce..031c3932c0de6a04d74e660ad4321c6884990859 100644 (file)
@@ -1,5 +1,6 @@
 import { parseQuery } from '../src/query'
-import { mockWarn } from 'jest-mock-warn'
+import { mockWarn } from './vitest-mock-warn'
+import { describe, expect, it } from 'vitest'
 
 describe('parseQuery', () => {
   mockWarn()
index 0d143fa7e439aaa0c204f61faf9e6786e95d0459..bf11f31bae4e03900f18d9740f73e85001764600 100644 (file)
@@ -10,8 +10,9 @@ import {
 import { NavigationFailureType } from '../src/errors'
 import { createDom, components, tick, nextNavigation } from './utils'
 import { RouteRecordRaw } from '../src/types'
-import { mockWarn } from 'jest-mock-warn'
 import { START_LOCATION_NORMALIZED } from '../src/location'
+import { vi, describe, expect, it, beforeAll } from 'vitest'
+import { mockWarn } from './vitest-mock-warn'
 
 declare var __DEV__: boolean
 
@@ -109,7 +110,7 @@ describe('Router', () => {
 
   it('calls history.push with router.push', async () => {
     const { router, history } = await newRouter()
-    jest.spyOn(history, 'push')
+    vi.spyOn(history, 'push')
     await router.push('/foo')
     expect(history.push).toHaveBeenCalledTimes(1)
     expect(history.push).toHaveBeenCalledWith('/foo', undefined)
@@ -118,7 +119,7 @@ describe('Router', () => {
   it('calls history.replace with router.replace', async () => {
     const history = createMemoryHistory()
     const { router } = await newRouter({ history })
-    jest.spyOn(history, 'replace')
+    vi.spyOn(history, 'replace')
     await router.replace('/foo')
     expect(history.replace).toHaveBeenCalledTimes(1)
     expect(history.replace).toHaveBeenCalledWith('/foo', expect.anything())
@@ -127,7 +128,7 @@ describe('Router', () => {
   it('parses query and hash with router.replace', async () => {
     const history = createMemoryHistory()
     const { router } = await newRouter({ history })
-    jest.spyOn(history, 'replace')
+    vi.spyOn(history, 'replace')
     await router.replace('/foo?q=2#a')
     expect(history.replace).toHaveBeenCalledTimes(1)
     expect(history.replace).toHaveBeenCalledWith(
@@ -141,8 +142,8 @@ describe('Router', () => {
     const { router } = await newRouter({ history })
     // move somewhere else
     await router.push('/search')
-    jest.spyOn(history, 'replace')
-    jest.spyOn(history, 'push')
+    vi.spyOn(history, 'replace')
+    vi.spyOn(history, 'push')
     await router.replace('/home-before')
     expect(history.push).toHaveBeenCalledTimes(0)
     expect(history.replace).toHaveBeenCalledTimes(1)
@@ -159,8 +160,8 @@ describe('Router', () => {
       }
       return // no warn
     })
-    jest.spyOn(history, 'replace')
-    jest.spyOn(history, 'push')
+    vi.spyOn(history, 'replace')
+    vi.spyOn(history, 'push')
     await router.push('/search')
     expect(history.location).toBe('/foo')
     expect(history.push).toHaveBeenCalledTimes(0)
@@ -169,7 +170,7 @@ describe('Router', () => {
   })
 
   it('allows to customize parseQuery', async () => {
-    const parseQuery = jest.fn(_ => ({}))
+    const parseQuery = vi.fn(_ => ({}))
     const { router } = await newRouter({ parseQuery })
     const to = router.resolve('/foo?bar=baz')
     expect(parseQuery).toHaveBeenCalledWith('bar=baz')
@@ -177,7 +178,7 @@ describe('Router', () => {
   })
 
   it('allows to customize stringifyQuery', async () => {
-    const stringifyQuery = jest.fn(_ => '')
+    const stringifyQuery = vi.fn(_ => '')
     const { router } = await newRouter({ stringifyQuery })
     const to = router.resolve({ query: { foo: 'bar' } })
     expect(stringifyQuery).toHaveBeenCalledWith({ foo: 'bar' })
@@ -186,7 +187,7 @@ describe('Router', () => {
   })
 
   it('creates an empty query with no query', async () => {
-    const stringifyQuery = jest.fn(_ => '')
+    const stringifyQuery = vi.fn(_ => '')
     const { router } = await newRouter({ stringifyQuery })
     const to = router.resolve({ hash: '#a' })
     expect(stringifyQuery).not.toHaveBeenCalled()
@@ -254,7 +255,7 @@ describe('Router', () => {
 
   it('can pass replace option to push', async () => {
     const { router, history } = await newRouter()
-    jest.spyOn(history, 'replace')
+    vi.spyOn(history, 'replace')
     await router.push({ path: '/foo', replace: true })
     expect(history.replace).toHaveBeenCalledTimes(1)
     expect(history.replace).toHaveBeenCalledWith('/foo', expect.anything())
@@ -262,7 +263,7 @@ describe('Router', () => {
 
   it('can replaces current location with a string location', async () => {
     const { router, history } = await newRouter()
-    jest.spyOn(history, 'replace')
+    vi.spyOn(history, 'replace')
     await router.replace('/foo')
     expect(history.replace).toHaveBeenCalledTimes(1)
     expect(history.replace).toHaveBeenCalledWith('/foo', expect.anything())
@@ -270,7 +271,7 @@ describe('Router', () => {
 
   it('can replaces current location with an object location', async () => {
     const { router, history } = await newRouter()
-    jest.spyOn(history, 'replace')
+    vi.spyOn(history, 'replace')
     await router.replace({ path: '/foo' })
     expect(history.replace).toHaveBeenCalledTimes(1)
     expect(history.replace).toHaveBeenCalledWith('/foo', expect.anything())
@@ -278,7 +279,7 @@ describe('Router', () => {
 
   it('navigates if the location does not exist', async () => {
     const { router } = await newRouter({ routes: [routes[0]] })
-    const spy = jest.fn((to, from, next) => next())
+    const spy = vi.fn((to, from, next) => next())
     router.beforeEach(spy)
     await router.push('/idontexist')
     expect(spy).toHaveBeenCalledTimes(1)
@@ -503,7 +504,7 @@ describe('Router', () => {
   describe('alias', () => {
     it('does not navigate to alias if already on original record', async () => {
       const { router } = await newRouter()
-      const spy = jest.fn((to, from, next) => next())
+      const spy = vi.fn((to, from, next) => next())
       await router.push('/basic')
       router.beforeEach(spy)
       await router.push('/basic-alias')
@@ -512,7 +513,7 @@ describe('Router', () => {
 
     it('does not navigate to alias with children if already on original record', async () => {
       const { router } = await newRouter()
-      const spy = jest.fn((to, from, next) => next())
+      const spy = vi.fn((to, from, next) => next())
       await router.push('/aliases')
       router.beforeEach(spy)
       await router.push('/aliases1')
@@ -523,7 +524,7 @@ describe('Router', () => {
 
     it('does not navigate to child alias if already on original record', async () => {
       const { router } = await newRouter()
-      const spy = jest.fn((to, from, next) => next())
+      const spy = vi.fn((to, from, next) => next())
       await router.push('/aliases/one')
       router.beforeEach(spy)
       await router.push('/aliases1/one')
@@ -698,7 +699,7 @@ describe('Router', () => {
     it('only triggers guards once with a redirect option', async () => {
       const history = createMemoryHistory()
       const router = createRouter({ history, routes })
-      const spy = jest.fn((to, from, next) => next())
+      const spy = vi.fn((to, from, next) => next())
       router.beforeEach(spy)
       await router.push('/to-foo')
       expect(spy).toHaveBeenCalledTimes(1)
index 3e1dd70ac7130352220e375636a69e68f66cbe5e..bdd42a3e56af9dcb74c49cd1a2b47a1666cc09c5 100644 (file)
@@ -1,20 +1,30 @@
 import { JSDOM } from 'jsdom'
 import { scrollToPosition } from '../src/scrollBehavior'
 import { createDom } from './utils'
-import { mockWarn } from 'jest-mock-warn'
+import { mockWarn } from './vitest-mock-warn'
+import {
+  vi,
+  describe,
+  expect,
+  it,
+  beforeEach,
+  afterAll,
+  beforeAll,
+  MockInstance,
+} from 'vitest'
 
 describe('scrollBehavior', () => {
   mockWarn()
   let dom: JSDOM
-  let scrollTo: jest.SpyInstance
-  let getElementById: jest.SpyInstance
-  let querySelector: jest.SpyInstance
+  let scrollTo: MockInstance
+  let getElementById: MockInstance
+  let querySelector: MockInstance
 
   beforeAll(() => {
     dom = createDom()
-    scrollTo = jest.spyOn(window, 'scrollTo').mockImplementation(() => {})
-    getElementById = jest.spyOn(document, 'getElementById')
-    querySelector = jest.spyOn(document, 'querySelector')
+    scrollTo = vi.spyOn(window, 'scrollTo').mockImplementation(() => {})
+    getElementById = vi.spyOn(document, 'getElementById')
+    querySelector = vi.spyOn(document, 'querySelector')
 
     // #text
     let el = document.createElement('div')
index 660c1ae0234f5c3e8523cf9534b9efdda5d69772..65091620f581e53ab31fcd8d37b91a8251e33ba2 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * @jest-environment node
+ * @vitest-environment node
  */
 import { createRouter, createMemoryHistory } from '../src'
 import { createSSRApp, resolveComponent, Component } from 'vue'
@@ -8,6 +8,7 @@ import {
   ssrInterpolate,
   ssrRenderComponent,
 } from '@vue/server-renderer'
+import { describe, expect, it } from 'vitest'
 
 const delay = (t: number) => new Promise(resolve => setTimeout(resolve, t))
 
index 64e774ee648e2775d7dc99dc9d4fd04a4f62f355..16a9703d457144afec3a0d716f37dc305b1ee9c8 100644 (file)
@@ -1,5 +1,6 @@
 import { stringifyQuery } from '../src/query'
-import { mockWarn } from 'jest-mock-warn'
+import { mockWarn } from './vitest-mock-warn'
+import { describe, expect, it } from 'vitest'
 
 describe('stringifyQuery', () => {
   mockWarn()
index 4102b73bd48a2b0a07dcaf190e9a69e936b30d79..fd83e1a07a5045db52bf36edc9178b15e64cd06b 100644 (file)
@@ -3,8 +3,9 @@ import { components } from './utils'
 import { RouteRecordRaw } from '../src/types'
 import { createMemoryHistory } from '../src'
 import * as encoding from '../src/encoding'
+import { vi, describe, expect, it, beforeEach } from 'vitest'
 
-jest.mock('../src/encoding')
+vi.mock('../src/encoding')
 
 const routes: RouteRecordRaw[] = [
   { path: '/', name: 'home', component: components.Home },
@@ -28,7 +29,7 @@ describe('URL Encoding', () => {
       // @ts-expect-error
       const value = encoding[key]
       // @ts-expect-error
-      if (typeof value === 'function') encoding[key] = jest.fn((v: string) => v)
+      if (typeof value === 'function') encoding[key] = vi.fn((v: string) => v)
       // @ts-expect-error
       else if (key === 'PLUS_RE') encoding[key] = /\+/g
     }
index e8e7be28f477fa2cd29cc0e2ab8c73cb107b69c8..b9d69ae961f6f80a9427688362b124bedc2e59b8 100644 (file)
@@ -1,9 +1,10 @@
 /**
- * @jest-environment jsdom
+ * @vitest-environment jsdom
  */
 import { mount } from '@vue/test-utils'
 import { computed } from 'vue'
 import { useRoute, createRouter, createMemoryHistory } from '../src'
+import { describe, expect, it } from 'vitest'
 
 describe('use apis', () => {
   it('unwraps useRoute()', async () => {
index 6f148bd26941fdcc4b01613b485669f7dacae221..094e837afce4724cfb95ba1c4ea08a3276aa1eff 100644 (file)
@@ -1,9 +1,9 @@
 /**
- * @jest-environment jsdom
+ * @vitest-environment jsdom
  */
 import { nextTick, ref } from 'vue'
 import { mount } from '@vue/test-utils'
-import { mockWarn } from 'jest-mock-warn'
+import { mockWarn } from './vitest-mock-warn'
 import {
   createMemoryHistory,
   createRouter,
@@ -11,6 +11,7 @@ import {
   useLink,
   UseLinkOptions,
 } from '../src'
+import { describe, expect, it } from 'vitest'
 
 async function callUseLink(args: UseLinkOptions) {
   const router = createRouter({
diff --git a/packages/router/__tests__/vitest-mock-warn.ts b/packages/router/__tests__/vitest-mock-warn.ts
new file mode 100644 (file)
index 0000000..8b22686
--- /dev/null
@@ -0,0 +1,125 @@
+// https://github.com/posva/jest-mock-warn/blob/master/src/index.js
+
+import { afterEach, beforeEach, expect, type MockInstance, vi } from 'vitest'
+
+export function mockWarn() {
+  expect.extend({
+    toHaveBeenWarned(received: string | RegExp) {
+      asserted.set(received.toString(), received)
+      const passed = warn.mock.calls.some(args =>
+        typeof received === 'string'
+          ? args[0].indexOf(received) > -1
+          : received.test(args[0])
+      )
+      if (passed) {
+        return {
+          pass: true,
+          message: () => `expected "${received}" not to have been warned.`,
+        }
+      } else {
+        const msgs = warn.mock.calls.map(args => args[0]).join('\n - ')
+        return {
+          pass: false,
+          message: () =>
+            `expected "${received}" to have been warned.\n\nActual messages:\n\n - ${msgs}`,
+        }
+      }
+    },
+
+    toHaveBeenWarnedLast(received: string | RegExp) {
+      asserted.set(received.toString(), received)
+      if (warn.mock.calls.length === 0) {
+        return {
+          pass: false,
+          message: () => 'expected console.warn to have been called.',
+        }
+      }
+      const lastCall = warn.mock.calls.at(-1)?.[0]
+      const passed =
+        typeof received === 'string'
+          ? lastCall.indexOf(received) > -1
+          : received.test(lastCall)
+      if (passed) {
+        return {
+          pass: true,
+          message: () => `expected "${received}" not to have been warned last.`,
+        }
+      } else {
+        const msgs = warn.mock.calls.map(args => args[0]).join('\n - ')
+        return {
+          pass: false,
+          message: () =>
+            `expected "${received}" to have been warned last.\n\nActual messages:\n\n - ${msgs}`,
+        }
+      }
+    },
+
+    toHaveBeenWarnedTimes(received: string | RegExp, n: number) {
+      asserted.set(received.toString(), received)
+      let found = 0
+      warn.mock.calls.forEach(args => {
+        const isFound =
+          typeof received === 'string'
+            ? args[0].indexOf(received) > -1
+            : received.test(args[0])
+        if (isFound) {
+          found++
+        }
+      })
+
+      if (found === n) {
+        return {
+          pass: true,
+          message: () =>
+            `expected "${received}" to have been warned ${n} times.`,
+        }
+      } else {
+        return {
+          pass: false,
+          message: () =>
+            `expected "${received}" to have been warned ${n} times but got ${found}.`,
+        }
+      }
+    },
+  })
+
+  let warn: MockInstance
+  const asserted = new Map<string, string | RegExp>()
+
+  beforeEach(() => {
+    asserted.clear()
+    warn = vi.spyOn(console, 'warn')
+    warn.mockImplementation(() => {})
+  })
+
+  afterEach(() => {
+    const assertedArray = Array.from(asserted)
+    const nonAssertedWarnings = warn.mock.calls
+      .map(args => args[0])
+      .filter(received => {
+        return !assertedArray.some(([_key, assertedMsg]) => {
+          return typeof assertedMsg === 'string'
+            ? received.indexOf(assertedMsg) > -1
+            : assertedMsg.test(received)
+        })
+      })
+    warn.mockRestore()
+    if (nonAssertedWarnings.length) {
+      nonAssertedWarnings.forEach(warning => {
+        console.warn(warning)
+      })
+      throw new Error(`test case threw unexpected warnings.`)
+    }
+  })
+}
+
+interface CustomMatchers<R = unknown> {
+  toHaveBeenWarned(): R
+  toHaveBeenWarnedLast(): R
+  toHaveBeenWarnedTimes(n: number): R
+}
+
+declare module 'vitest' {
+  interface Assertion<T = any> extends CustomMatchers<T> {}
+  interface AsymmetricMatchersContaining extends CustomMatchers {}
+}
index 82f6450d560c7119e85444b35daab47065d4a2e7..7d9d9274ee793443c093f67de674ba8569493fc0 100644 (file)
@@ -1,4 +1,3 @@
-import { mockWarn } from 'jest-mock-warn'
 import { createMemoryHistory, createRouter, createRouterMatcher } from '../src'
 import {
   defineAsyncComponent,
@@ -6,6 +5,8 @@ import {
   FunctionalComponent,
   h,
 } from 'vue'
+import { describe, expect, it } from 'vitest'
+import { mockWarn } from './vitest-mock-warn'
 
 let component = defineComponent({})
 
@@ -117,7 +118,7 @@ describe('warnings', () => {
     ).toHaveBeenWarned()
   })
 
-  it('warns if next is called multiple times in one navigation guard', done => {
+  it('warns if next is called multiple times in one navigation guard', async () => {
     expect.assertions(3)
     let router = createRouter({
       history: createMemoryHistory(),
@@ -134,10 +135,9 @@ describe('warnings', () => {
       expect('called more than once').toHaveBeenWarnedTimes(1)
       next()
       expect('called more than once').toHaveBeenWarnedTimes(1)
-      done()
     })
 
-    router.push('/b')
+    await router.push('/b')
   })
 
   it('warns if a non valid function is passed as a component', async () => {
diff --git a/packages/router/jest.config.js b/packages/router/jest.config.js
deleted file mode 100644 (file)
index 8059c12..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-module.exports = {
-  testEnvironment: 'node',
-  testEnvironmentOptions: {
-    customExportConditions: ['node', 'node-addons'],
-  },
-  globals: {
-    __DEV__: true,
-    __TEST__: true,
-    __BROWSER__: true,
-  },
-  setupFilesAfterEnv: ['<rootDir>/__tests__/setup.ts'],
-  coverageDirectory: 'coverage',
-  coverageReporters: ['html', 'lcov', 'text'],
-  collectCoverageFrom: ['src/**/*.ts'],
-  coveragePathIgnorePatterns: [
-    '/node_modules/',
-    'src/index.ts',
-    'src/entries',
-    'src/devtools.ts',
-  ],
-  transform: {
-    '^.+\\.tsx?$': '@sucrase/jest-plugin',
-  },
-  testMatch: ['<rootDir>/__tests__/**/*.spec.ts?(x)'],
-  watchPathIgnorePatterns: ['<rootDir>/node_modules'],
-}
index baca62945bfd15ac5f5b523373fa0c8bd97bb32d..9b39fac9ff9b10e2a881c7b25401746796481fd4 100644 (file)
@@ -88,7 +88,7 @@
     "README.md"
   ],
   "scripts": {
-    "dev": "jest --watch",
+    "dev": "vitest --ui",
     "changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 1",
     "build": "rimraf dist && rollup -c rollup.config.mjs",
     "build:dts": "api-extractor run --local --verbose && tail -n +10 src/globalExtensions.ts >> dist/vue-router.d.ts",
@@ -98,7 +98,7 @@
     "dev:e2e": "vite --config e2e/vite.config.mjs",
     "test:types": "tsc --build tsconfig.json",
     "test:dts": "tsc -p ./test-dts/tsconfig.json",
-    "test:unit": "jest --coverage",
+    "test:unit": "vitest --coverage",
     "test": "pnpm run test:types && pnpm run test:unit && pnpm run build && pnpm run build:dts && pnpm run test:e2e",
     "test:e2e": "pnpm run test:e2e:headless",
     "test:e2e:headless": "node e2e/runner.mjs --env chrome-headless",
     "@rollup/plugin-node-resolve": "^15.2.3",
     "@rollup/plugin-replace": "^5.0.5",
     "@rollup/plugin-terser": "^0.4.4",
-    "@sucrase/jest-plugin": "^3.0.0",
-    "@types/jest": "^29.5.12",
     "@types/jsdom": "^21.1.6",
     "@types/nightwatch": "^2.3.30",
     "@vitejs/plugin-vue": "^5.0.4",
+    "@vitest/coverage-v8": "^1.6.0",
+    "@vitest/ui": "^1.6.0",
     "@vue/compiler-sfc": "^3.4.23",
     "@vue/server-renderer": "^3.4.23",
     "@vue/test-utils": "^2.4.4",
     "dotenv": "^16.4.5",
     "faked-promise": "^2.2.2",
     "geckodriver": "^3.2.0",
-    "jest": "^29.7.0",
-    "jest-environment-jsdom": "^29.7.0",
-    "jest-mock-warn": "^1.1.0",
     "nightwatch": "^2.6.22",
     "nightwatch-helpers": "^1.2.0",
     "rimraf": "^5.0.5",
     "sucrase": "^3.34.0",
     "typescript": "~5.3.3",
     "vite": "^5.2.9",
+    "vitest": "^1.6.0",
     "vue": "^3.4.23"
   }
 }
index e22ed0a740e976465abf4b81f7158720e2563267..0c392949be7ec24f7903a4aa72d9f8692d6a4eff 100644 (file)
@@ -1,4 +1,4 @@
-import { h, createApp } from '@vue/runtime-dom'
+import { h, createApp } from 'vue'
 import { createRouter, createWebHistory } from '../dist/vue-router.esm-bundler'
 
 createRouter({
index 0a32fcb75d23a7a513557b03e0b6e04f5a36cb43..22219c6f01a5b6670ae20ddd64bb33c7b00deee4 100644 (file)
@@ -32,7 +32,6 @@
       "dom"
     ],
     "types": [
-      "jest",
       "node",
       "vite/client"
     ]
diff --git a/packages/router/vitest.config.ts b/packages/router/vitest.config.ts
new file mode 100644 (file)
index 0000000..bb42313
--- /dev/null
@@ -0,0 +1,40 @@
+import { defineConfig } from 'vitest/config'
+import Vue from '@vitejs/plugin-vue'
+import { fileURLToPath } from 'node:url'
+
+const __dirname = new URL('.', import.meta.url).pathname
+export default defineConfig({
+  resolve: {
+    alias: [],
+  },
+  define: {
+    __DEV__: true,
+    __TEST__: true,
+    __BROWSER__: true,
+  },
+  plugins: [Vue()],
+
+  test: {
+    // open: false,
+    coverage: {
+      include: ['src/**/*.ts'],
+      exclude: [
+        'src/**/*.d.ts',
+        'src/**/*.test-d.ts',
+        'src/**/*.spec.ts',
+        // '/node_modules/',
+        'src/index.ts',
+        'src/devtools.ts',
+      ],
+    },
+    typecheck: {
+      enabled: true,
+      checker: 'vue-tsc',
+      // only: true,
+      // by default it includes all specs too
+      include: ['**/*.test-d.ts'],
+
+      // tsconfig: './tsconfig.typecheck.json',
+    },
+  },
+})
diff --git a/packages/router/vitest.workspace.js b/packages/router/vitest.workspace.js
new file mode 100644 (file)
index 0000000..45759c0
--- /dev/null
@@ -0,0 +1,3 @@
+import { defineWorkspace } from 'vitest/config'
+
+export default defineWorkspace(['./vitest.config.ts'])
index 8e88c91d02679020267b42297101f98e7b0f981e..e5840010aa0430db49a45bbae50bf4aba563f41a 100644 (file)
@@ -121,12 +121,6 @@ importers:
       '@rollup/plugin-terser':
         specifier: ^0.4.4
         version: 0.4.4(rollup@3.29.4)
-      '@sucrase/jest-plugin':
-        specifier: ^3.0.0
-        version: 3.0.0(jest@29.7.0)(sucrase@3.34.0)
-      '@types/jest':
-        specifier: ^29.5.12
-        version: 29.5.12
       '@types/jsdom':
         specifier: ^21.1.6
         version: 21.1.6
@@ -136,6 +130,12 @@ importers:
       '@vitejs/plugin-vue':
         specifier: ^5.0.4
         version: 5.0.4(vite@5.2.9)(vue@3.4.23)
+      '@vitest/coverage-v8':
+        specifier: ^1.6.0
+        version: 1.6.0(vitest@1.6.0)
+      '@vitest/ui':
+        specifier: ^1.6.0
+        version: 1.6.0(vitest@1.6.0)
       '@vue/compiler-sfc':
         specifier: ^3.4.23
         version: 3.4.23
@@ -166,15 +166,6 @@ importers:
       geckodriver:
         specifier: ^3.2.0
         version: 3.2.0
-      jest:
-        specifier: ^29.7.0
-        version: 29.7.0
-      jest-environment-jsdom:
-        specifier: ^29.7.0
-        version: 29.7.0
-      jest-mock-warn:
-        specifier: ^1.1.0
-        version: 1.1.0
       nightwatch:
         specifier: ^2.6.22
         version: 2.6.24(chromedriver@121.0.2)(geckodriver@3.2.0)
@@ -202,6 +193,9 @@ importers:
       vite:
         specifier: ^5.2.9
         version: 5.2.9(@types/node@20.12.7)
+      vitest:
+        specifier: ^1.6.0
+        version: 1.6.0(@vitest/ui@1.6.0)
       vue:
         specifier: ^3.4.23
         version: 3.4.23(typescript@5.3.3)
@@ -374,115 +368,6 @@ packages:
       chalk: 2.4.2
     dev: true
 
-  /@babel/compat-data@7.22.9:
-    resolution: {integrity: sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ==}
-    engines: {node: '>=6.9.0'}
-    dev: true
-
-  /@babel/core@7.22.11:
-    resolution: {integrity: sha512-lh7RJrtPdhibbxndr6/xx0w8+CVlY5FJZiaSz908Fpy+G0xkBFTvwLcKJFF4PJxVfGhVWNebikpWGnOoC71juQ==}
-    engines: {node: '>=6.9.0'}
-    dependencies:
-      '@ampproject/remapping': 2.2.1
-      '@babel/code-frame': 7.22.10
-      '@babel/generator': 7.22.10
-      '@babel/helper-compilation-targets': 7.22.10
-      '@babel/helper-module-transforms': 7.22.9(@babel/core@7.22.11)
-      '@babel/helpers': 7.22.11
-      '@babel/parser': 7.24.4
-      '@babel/template': 7.22.5
-      '@babel/traverse': 7.22.11
-      '@babel/types': 7.24.0
-      convert-source-map: 1.9.0
-      debug: 4.3.4
-      gensync: 1.0.0-beta.2
-      json5: 2.2.3
-      semver: 6.3.1
-    transitivePeerDependencies:
-      - supports-color
-    dev: true
-
-  /@babel/generator@7.22.10:
-    resolution: {integrity: sha512-79KIf7YiWjjdZ81JnLujDRApWtl7BxTqWD88+FFdQEIOG8LJ0etDOM7CXuIgGJa55sGOwZVwuEsaLEm0PJ5/+A==}
-    engines: {node: '>=6.9.0'}
-    dependencies:
-      '@babel/types': 7.22.11
-      '@jridgewell/gen-mapping': 0.3.3
-      '@jridgewell/trace-mapping': 0.3.19
-      jsesc: 2.5.2
-    dev: true
-
-  /@babel/helper-compilation-targets@7.22.10:
-    resolution: {integrity: sha512-JMSwHD4J7SLod0idLq5PKgI+6g/hLD/iuWBq08ZX49xE14VpVEojJ5rHWptpirV2j020MvypRLAXAO50igCJ5Q==}
-    engines: {node: '>=6.9.0'}
-    dependencies:
-      '@babel/compat-data': 7.22.9
-      '@babel/helper-validator-option': 7.22.5
-      browserslist: 4.21.10
-      lru-cache: 5.1.1
-      semver: 6.3.1
-    dev: true
-
-  /@babel/helper-environment-visitor@7.22.5:
-    resolution: {integrity: sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==}
-    engines: {node: '>=6.9.0'}
-    dev: true
-
-  /@babel/helper-function-name@7.22.5:
-    resolution: {integrity: sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==}
-    engines: {node: '>=6.9.0'}
-    dependencies:
-      '@babel/template': 7.22.5
-      '@babel/types': 7.24.0
-    dev: true
-
-  /@babel/helper-hoist-variables@7.22.5:
-    resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==}
-    engines: {node: '>=6.9.0'}
-    dependencies:
-      '@babel/types': 7.24.0
-    dev: true
-
-  /@babel/helper-module-imports@7.22.5:
-    resolution: {integrity: sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==}
-    engines: {node: '>=6.9.0'}
-    dependencies:
-      '@babel/types': 7.24.0
-    dev: true
-
-  /@babel/helper-module-transforms@7.22.9(@babel/core@7.22.11):
-    resolution: {integrity: sha512-t+WA2Xn5K+rTeGtC8jCsdAH52bjggG5TKRuRrAGNM/mjIbO4GxvlLMFOEz9wXY5I2XQ60PMFsAG2WIcG82dQMQ==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0
-    dependencies:
-      '@babel/core': 7.22.11
-      '@babel/helper-environment-visitor': 7.22.5
-      '@babel/helper-module-imports': 7.22.5
-      '@babel/helper-simple-access': 7.22.5
-      '@babel/helper-split-export-declaration': 7.22.6
-      '@babel/helper-validator-identifier': 7.22.20
-    dev: true
-
-  /@babel/helper-plugin-utils@7.22.5:
-    resolution: {integrity: sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==}
-    engines: {node: '>=6.9.0'}
-    dev: true
-
-  /@babel/helper-simple-access@7.22.5:
-    resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==}
-    engines: {node: '>=6.9.0'}
-    dependencies:
-      '@babel/types': 7.24.0
-    dev: true
-
-  /@babel/helper-split-export-declaration@7.22.6:
-    resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==}
-    engines: {node: '>=6.9.0'}
-    dependencies:
-      '@babel/types': 7.24.0
-    dev: true
-
   /@babel/helper-string-parser@7.24.1:
     resolution: {integrity: sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==}
     engines: {node: '>=6.9.0'}
@@ -491,22 +376,6 @@ packages:
     resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==}
     engines: {node: '>=6.9.0'}
 
-  /@babel/helper-validator-option@7.22.5:
-    resolution: {integrity: sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==}
-    engines: {node: '>=6.9.0'}
-    dev: true
-
-  /@babel/helpers@7.22.11:
-    resolution: {integrity: sha512-vyOXC8PBWaGc5h7GMsNx68OH33cypkEDJCHvYVVgVbbxJDROYVtexSk0gK5iCF1xNjRIN2s8ai7hwkWDq5szWg==}
-    engines: {node: '>=6.9.0'}
-    dependencies:
-      '@babel/template': 7.22.5
-      '@babel/traverse': 7.22.11
-      '@babel/types': 7.24.0
-    transitivePeerDependencies:
-      - supports-color
-    dev: true
-
   /@babel/highlight@7.22.10:
     resolution: {integrity: sha512-78aUtVcT7MUscr0K5mIEnkwxPE0MaxkR5RxRwuHaQ+JuU5AmTPhY+do2mdzVTnIJJpyBglql2pehuBIWHug+WQ==}
     engines: {node: '>=6.9.0'}
@@ -523,171 +392,6 @@ packages:
     dependencies:
       '@babel/types': 7.24.0
 
-  /@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.22.11):
-    resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.22.11
-      '@babel/helper-plugin-utils': 7.22.5
-    dev: true
-
-  /@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.22.11):
-    resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.22.11
-      '@babel/helper-plugin-utils': 7.22.5
-    dev: true
-
-  /@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.22.11):
-    resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.22.11
-      '@babel/helper-plugin-utils': 7.22.5
-    dev: true
-
-  /@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.22.11):
-    resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.22.11
-      '@babel/helper-plugin-utils': 7.22.5
-    dev: true
-
-  /@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.22.11):
-    resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.22.11
-      '@babel/helper-plugin-utils': 7.22.5
-    dev: true
-
-  /@babel/plugin-syntax-jsx@7.22.5(@babel/core@7.22.11):
-    resolution: {integrity: sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.22.11
-      '@babel/helper-plugin-utils': 7.22.5
-    dev: true
-
-  /@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.22.11):
-    resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.22.11
-      '@babel/helper-plugin-utils': 7.22.5
-    dev: true
-
-  /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.22.11):
-    resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.22.11
-      '@babel/helper-plugin-utils': 7.22.5
-    dev: true
-
-  /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.22.11):
-    resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.22.11
-      '@babel/helper-plugin-utils': 7.22.5
-    dev: true
-
-  /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.22.11):
-    resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.22.11
-      '@babel/helper-plugin-utils': 7.22.5
-    dev: true
-
-  /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.22.11):
-    resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.22.11
-      '@babel/helper-plugin-utils': 7.22.5
-    dev: true
-
-  /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.22.11):
-    resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.22.11
-      '@babel/helper-plugin-utils': 7.22.5
-    dev: true
-
-  /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.22.11):
-    resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.22.11
-      '@babel/helper-plugin-utils': 7.22.5
-    dev: true
-
-  /@babel/plugin-syntax-typescript@7.22.5(@babel/core@7.22.11):
-    resolution: {integrity: sha512-1mS2o03i7t1c6VzH6fdQ3OA8tcEIxwG18zIPRp+UY1Ihv6W+XZzBCVxExF9upussPXJ0xE9XRHwMoNs1ep/nRQ==}
-    engines: {node: '>=6.9.0'}
-    peerDependencies:
-      '@babel/core': ^7.0.0-0
-    dependencies:
-      '@babel/core': 7.22.11
-      '@babel/helper-plugin-utils': 7.22.5
-    dev: true
-
-  /@babel/template@7.22.5:
-    resolution: {integrity: sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==}
-    engines: {node: '>=6.9.0'}
-    dependencies:
-      '@babel/code-frame': 7.22.10
-      '@babel/parser': 7.24.4
-      '@babel/types': 7.24.0
-    dev: true
-
-  /@babel/traverse@7.22.11:
-    resolution: {integrity: sha512-mzAenteTfomcB7mfPtyi+4oe5BZ6MXxWcn4CX+h4IRJ+OOGXBrWU6jDQavkQI9Vuc5P+donFabBfFCcmWka9lQ==}
-    engines: {node: '>=6.9.0'}
-    dependencies:
-      '@babel/code-frame': 7.22.10
-      '@babel/generator': 7.22.10
-      '@babel/helper-environment-visitor': 7.22.5
-      '@babel/helper-function-name': 7.22.5
-      '@babel/helper-hoist-variables': 7.22.5
-      '@babel/helper-split-export-declaration': 7.22.6
-      '@babel/parser': 7.24.4
-      '@babel/types': 7.24.0
-      debug: 4.3.4
-      globals: 11.12.0
-    transitivePeerDependencies:
-      - supports-color
-    dev: true
-
-  /@babel/types@7.22.11:
-    resolution: {integrity: sha512-siazHiGuZRz9aB9NpHy9GOs9xiQPKnMzgdr493iI1M67vRXpnEq8ZOOKzezC5q7zwuQ6sDhdSp4SD9ixKSqKZg==}
-    engines: {node: '>=6.9.0'}
-    dependencies:
-      '@babel/helper-string-parser': 7.24.1
-      '@babel/helper-validator-identifier': 7.22.20
-      to-fast-properties: 2.0.0
-    dev: true
-
   /@babel/types@7.24.0:
     resolution: {integrity: sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==}
     engines: {node: '>=6.9.0'}
@@ -951,292 +655,81 @@ packages:
       wrap-ansi-cjs: /wrap-ansi@7.0.0
     dev: true
 
-  /@istanbuljs/load-nyc-config@1.1.0:
-    resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==}
-    engines: {node: '>=8'}
-    dependencies:
-      camelcase: 5.3.1
-      find-up: 4.1.0
-      get-package-type: 0.1.0
-      js-yaml: 3.14.1
-      resolve-from: 5.0.0
-    dev: true
-
   /@istanbuljs/schema@0.1.3:
     resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==}
     engines: {node: '>=8'}
     dev: true
 
-  /@jest/console@29.7.0:
-    resolution: {integrity: sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==}
+  /@jest/schemas@29.6.3:
+    resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==}
     engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
     dependencies:
-      '@jest/types': 29.6.3
-      '@types/node': 20.12.7
-      chalk: 4.1.2
-      jest-message-util: 29.7.0
-      jest-util: 29.7.0
-      slash: 3.0.0
+      '@sinclair/typebox': 0.27.8
     dev: true
 
-  /@jest/core@29.7.0:
-    resolution: {integrity: sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==}
-    engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-    peerDependencies:
-      node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0
-    peerDependenciesMeta:
-      node-notifier:
-        optional: true
+  /@jridgewell/gen-mapping@0.3.3:
+    resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==}
+    engines: {node: '>=6.0.0'}
     dependencies:
-      '@jest/console': 29.7.0
-      '@jest/reporters': 29.7.0
-      '@jest/test-result': 29.7.0
-      '@jest/transform': 29.7.0
-      '@jest/types': 29.6.3
-      '@types/node': 20.12.7
-      ansi-escapes: 4.3.2
-      chalk: 4.1.2
-      ci-info: 3.8.0
-      exit: 0.1.2
-      graceful-fs: 4.2.11
-      jest-changed-files: 29.7.0
-      jest-config: 29.7.0(@types/node@20.12.7)
-      jest-haste-map: 29.7.0
-      jest-message-util: 29.7.0
-      jest-regex-util: 29.6.3
-      jest-resolve: 29.7.0
-      jest-resolve-dependencies: 29.7.0
-      jest-runner: 29.7.0
-      jest-runtime: 29.7.0
-      jest-snapshot: 29.7.0
-      jest-util: 29.7.0
-      jest-validate: 29.7.0
-      jest-watcher: 29.7.0
-      micromatch: 4.0.5
-      pretty-format: 29.7.0
-      slash: 3.0.0
-      strip-ansi: 6.0.1
-    transitivePeerDependencies:
-      - babel-plugin-macros
-      - supports-color
-      - ts-node
+      '@jridgewell/set-array': 1.1.2
+      '@jridgewell/sourcemap-codec': 1.4.15
+      '@jridgewell/trace-mapping': 0.3.19
     dev: true
 
-  /@jest/environment@29.7.0:
-    resolution: {integrity: sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==}
-    engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-    dependencies:
-      '@jest/fake-timers': 29.7.0
-      '@jest/types': 29.6.3
-      '@types/node': 20.11.19
-      jest-mock: 29.7.0
+  /@jridgewell/resolve-uri@3.1.1:
+    resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==}
+    engines: {node: '>=6.0.0'}
     dev: true
 
-  /@jest/expect-utils@29.7.0:
-    resolution: {integrity: sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==}
-    engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-    dependencies:
-      jest-get-type: 29.6.3
+  /@jridgewell/set-array@1.1.2:
+    resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==}
+    engines: {node: '>=6.0.0'}
     dev: true
 
-  /@jest/expect@29.7.0:
-    resolution: {integrity: sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==}
-    engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+  /@jridgewell/source-map@0.3.5:
+    resolution: {integrity: sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==}
     dependencies:
-      expect: 29.7.0
-      jest-snapshot: 29.7.0
-    transitivePeerDependencies:
-      - supports-color
+      '@jridgewell/gen-mapping': 0.3.3
+      '@jridgewell/trace-mapping': 0.3.19
     dev: true
 
-  /@jest/fake-timers@29.7.0:
-    resolution: {integrity: sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==}
-    engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+  /@jridgewell/sourcemap-codec@1.4.15:
+    resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==}
+
+  /@jridgewell/trace-mapping@0.3.19:
+    resolution: {integrity: sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==}
     dependencies:
-      '@jest/types': 29.6.3
-      '@sinonjs/fake-timers': 10.3.0
-      '@types/node': 20.11.19
-      jest-message-util: 29.7.0
-      jest-mock: 29.7.0
-      jest-util: 29.7.0
+      '@jridgewell/resolve-uri': 3.1.1
+      '@jridgewell/sourcemap-codec': 1.4.15
     dev: true
 
-  /@jest/globals@29.7.0:
-    resolution: {integrity: sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==}
-    engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+  /@jridgewell/trace-mapping@0.3.25:
+    resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==}
     dependencies:
-      '@jest/environment': 29.7.0
-      '@jest/expect': 29.7.0
-      '@jest/types': 29.6.3
-      jest-mock: 29.7.0
-    transitivePeerDependencies:
-      - supports-color
+      '@jridgewell/resolve-uri': 3.1.1
+      '@jridgewell/sourcemap-codec': 1.4.15
     dev: true
 
-  /@jest/reporters@29.7.0:
-    resolution: {integrity: sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==}
-    engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-    peerDependencies:
-      node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0
-    peerDependenciesMeta:
-      node-notifier:
-        optional: true
+  /@kwsites/file-exists@1.1.1:
+    resolution: {integrity: sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==}
     dependencies:
-      '@bcoe/v8-coverage': 0.2.3
-      '@jest/console': 29.7.0
-      '@jest/test-result': 29.7.0
-      '@jest/transform': 29.7.0
-      '@jest/types': 29.6.3
-      '@jridgewell/trace-mapping': 0.3.19
-      '@types/node': 20.12.7
-      chalk: 4.1.2
-      collect-v8-coverage: 1.0.2
-      exit: 0.1.2
-      glob: 7.2.3
-      graceful-fs: 4.2.11
-      istanbul-lib-coverage: 3.2.0
-      istanbul-lib-instrument: 6.0.0
-      istanbul-lib-report: 3.0.1
-      istanbul-lib-source-maps: 4.0.1
-      istanbul-reports: 3.1.6
-      jest-message-util: 29.7.0
-      jest-util: 29.7.0
-      jest-worker: 29.7.0
-      slash: 3.0.0
-      string-length: 4.0.2
-      strip-ansi: 6.0.1
-      v8-to-istanbul: 9.1.0
+      debug: 4.3.4
     transitivePeerDependencies:
       - supports-color
-    dev: true
+    dev: false
 
-  /@jest/schemas@29.6.3:
-    resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==}
-    engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+  /@kwsites/promise-deferred@1.1.1:
+    resolution: {integrity: sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==}
+    dev: false
+
+  /@microsoft/api-extractor-model@7.28.9:
+    resolution: {integrity: sha512-lM77dV+VO46MGp5lu4stUBnO3jyr+CrDzU+DtapcOQEZUqJxPYUoK5zjeD+gRZ9ckgGMZC94ch6FBkpmsjwQgw==}
     dependencies:
-      '@sinclair/typebox': 0.27.8
-    dev: true
-
-  /@jest/source-map@29.6.3:
-    resolution: {integrity: sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==}
-    engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-    dependencies:
-      '@jridgewell/trace-mapping': 0.3.19
-      callsites: 3.1.0
-      graceful-fs: 4.2.11
-    dev: true
-
-  /@jest/test-result@29.7.0:
-    resolution: {integrity: sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==}
-    engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-    dependencies:
-      '@jest/console': 29.7.0
-      '@jest/types': 29.6.3
-      '@types/istanbul-lib-coverage': 2.0.4
-      collect-v8-coverage: 1.0.2
-    dev: true
-
-  /@jest/test-sequencer@29.7.0:
-    resolution: {integrity: sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==}
-    engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-    dependencies:
-      '@jest/test-result': 29.7.0
-      graceful-fs: 4.2.11
-      jest-haste-map: 29.7.0
-      slash: 3.0.0
-    dev: true
-
-  /@jest/transform@29.7.0:
-    resolution: {integrity: sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==}
-    engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-    dependencies:
-      '@babel/core': 7.22.11
-      '@jest/types': 29.6.3
-      '@jridgewell/trace-mapping': 0.3.19
-      babel-plugin-istanbul: 6.1.1
-      chalk: 4.1.2
-      convert-source-map: 2.0.0
-      fast-json-stable-stringify: 2.1.0
-      graceful-fs: 4.2.11
-      jest-haste-map: 29.7.0
-      jest-regex-util: 29.6.3
-      jest-util: 29.7.0
-      micromatch: 4.0.5
-      pirates: 4.0.6
-      slash: 3.0.0
-      write-file-atomic: 4.0.2
-    transitivePeerDependencies:
-      - supports-color
-    dev: true
-
-  /@jest/types@29.6.3:
-    resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==}
-    engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-    dependencies:
-      '@jest/schemas': 29.6.3
-      '@types/istanbul-lib-coverage': 2.0.4
-      '@types/istanbul-reports': 3.0.1
-      '@types/node': 20.12.7
-      '@types/yargs': 17.0.24
-      chalk: 4.1.2
-    dev: true
-
-  /@jridgewell/gen-mapping@0.3.3:
-    resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==}
-    engines: {node: '>=6.0.0'}
-    dependencies:
-      '@jridgewell/set-array': 1.1.2
-      '@jridgewell/sourcemap-codec': 1.4.15
-      '@jridgewell/trace-mapping': 0.3.19
-    dev: true
-
-  /@jridgewell/resolve-uri@3.1.1:
-    resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==}
-    engines: {node: '>=6.0.0'}
-    dev: true
-
-  /@jridgewell/set-array@1.1.2:
-    resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==}
-    engines: {node: '>=6.0.0'}
-    dev: true
-
-  /@jridgewell/source-map@0.3.5:
-    resolution: {integrity: sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==}
-    dependencies:
-      '@jridgewell/gen-mapping': 0.3.3
-      '@jridgewell/trace-mapping': 0.3.19
-    dev: true
-
-  /@jridgewell/sourcemap-codec@1.4.15:
-    resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==}
-
-  /@jridgewell/trace-mapping@0.3.19:
-    resolution: {integrity: sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==}
-    dependencies:
-      '@jridgewell/resolve-uri': 3.1.1
-      '@jridgewell/sourcemap-codec': 1.4.15
-    dev: true
-
-  /@kwsites/file-exists@1.1.1:
-    resolution: {integrity: sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==}
-    dependencies:
-      debug: 4.3.4
-    transitivePeerDependencies:
-      - supports-color
-    dev: false
-
-  /@kwsites/promise-deferred@1.1.1:
-    resolution: {integrity: sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==}
-    dev: false
-
-  /@microsoft/api-extractor-model@7.28.9:
-    resolution: {integrity: sha512-lM77dV+VO46MGp5lu4stUBnO3jyr+CrDzU+DtapcOQEZUqJxPYUoK5zjeD+gRZ9ckgGMZC94ch6FBkpmsjwQgw==}
-    dependencies:
-      '@microsoft/tsdoc': 0.14.2
-      '@microsoft/tsdoc-config': 0.16.2
-      '@rushstack/node-core-library': 3.66.0
-    transitivePeerDependencies:
-      - '@types/node'
+      '@microsoft/tsdoc': 0.14.2
+      '@microsoft/tsdoc-config': 0.16.2
+      '@rushstack/node-core-library': 3.66.0
+    transitivePeerDependencies:
+      - '@types/node'
     dev: true
 
   /@microsoft/api-extractor@7.40.1:
@@ -1320,6 +813,10 @@ packages:
     dev: true
     optional: true
 
+  /@polka/url@1.0.0-next.25:
+    resolution: {integrity: sha512-j7P6Rgr3mmtdkeDGTe0E/aYyWEWVtc5yFXtHCRHs28/jptDEWfaVOc5T7cblqy1XKPPfCxJc/8DwQ5YgLOZOVQ==}
+    dev: true
+
   /@rollup/plugin-alias@5.1.0(rollup@3.29.4):
     resolution: {integrity: sha512-lpA3RZ9PdIG7qqhEfv79tBffNaoDuukFDrmhLqg9ifv99u/ehn+lOg30x2zmhf8AQqQUZaMk/B9fZraQ6/acDQ==}
     engines: {node: '>=14.0.0'}
@@ -1590,28 +1087,6 @@ packages:
     engines: {node: '>=18'}
     dev: true
 
-  /@sinonjs/commons@3.0.0:
-    resolution: {integrity: sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==}
-    dependencies:
-      type-detect: 4.0.8
-    dev: true
-
-  /@sinonjs/fake-timers@10.3.0:
-    resolution: {integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==}
-    dependencies:
-      '@sinonjs/commons': 3.0.0
-    dev: true
-
-  /@sucrase/jest-plugin@3.0.0(jest@29.7.0)(sucrase@3.34.0):
-    resolution: {integrity: sha512-VRY6YKYImVWiRg1H3Yu24hwB1UPJDSDR62R/n+lOHR3+yDrfHEIAoddJivblMYN6U3vD+ndfTSrecZ9Jl+iGNw==}
-    peerDependencies:
-      jest: '>=27'
-      sucrase: '>=3.25.0'
-    dependencies:
-      jest: 29.7.0
-      sucrase: 3.34.0
-    dev: true
-
   /@szmarczak/http-timer@4.0.6:
     resolution: {integrity: sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==}
     engines: {node: '>=10'}
@@ -1632,35 +1107,6 @@ packages:
     resolution: {integrity: sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==}
     dev: true
 
-  /@types/babel__core@7.20.1:
-    resolution: {integrity: sha512-aACu/U/omhdk15O4Nfb+fHgH/z3QsfQzpnvRZhYhThms83ZnAOZz7zZAWO7mn2yyNQaA4xTO8GLK3uqFU4bYYw==}
-    dependencies:
-      '@babel/parser': 7.24.4
-      '@babel/types': 7.24.0
-      '@types/babel__generator': 7.6.4
-      '@types/babel__template': 7.4.1
-      '@types/babel__traverse': 7.20.1
-    dev: true
-
-  /@types/babel__generator@7.6.4:
-    resolution: {integrity: sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==}
-    dependencies:
-      '@babel/types': 7.24.0
-    dev: true
-
-  /@types/babel__template@7.4.1:
-    resolution: {integrity: sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==}
-    dependencies:
-      '@babel/parser': 7.24.4
-      '@babel/types': 7.24.0
-    dev: true
-
-  /@types/babel__traverse@7.20.1:
-    resolution: {integrity: sha512-MitHFXnhtgwsGZWtT68URpOvLN4EREih1u3QtQiN4VdAxWKRVvGCSvw/Qth0M0Qq3pJpnGOu5JaM/ydK7OGbqg==}
-    dependencies:
-      '@babel/types': 7.24.0
-    dev: true
-
   /@types/cacheable-request@6.0.3:
     resolution: {integrity: sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==}
     dependencies:
@@ -1681,47 +1127,10 @@ packages:
   /@types/estree@1.0.5:
     resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==}
 
-  /@types/graceful-fs@4.1.6:
-    resolution: {integrity: sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==}
-    dependencies:
-      '@types/node': 20.12.7
-    dev: true
-
   /@types/http-cache-semantics@4.0.1:
     resolution: {integrity: sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==}
     dev: true
 
-  /@types/istanbul-lib-coverage@2.0.4:
-    resolution: {integrity: sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==}
-    dev: true
-
-  /@types/istanbul-lib-report@3.0.0:
-    resolution: {integrity: sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==}
-    dependencies:
-      '@types/istanbul-lib-coverage': 2.0.4
-    dev: true
-
-  /@types/istanbul-reports@3.0.1:
-    resolution: {integrity: sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==}
-    dependencies:
-      '@types/istanbul-lib-report': 3.0.0
-    dev: true
-
-  /@types/jest@29.5.12:
-    resolution: {integrity: sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw==}
-    dependencies:
-      expect: 29.7.0
-      pretty-format: 29.7.0
-    dev: true
-
-  /@types/jsdom@20.0.1:
-    resolution: {integrity: sha512-d0r18sZPmMQr1eG35u12FZfhIXNrnsPU/g5wvRKCUf/tOGilKKwYMYGqh33BNR6ba+2gkHw1EUiHoN3mn7E5IQ==}
-    dependencies:
-      '@types/node': 20.11.19
-      '@types/tough-cookie': 4.0.2
-      parse5: 7.1.2
-    dev: true
-
   /@types/jsdom@21.1.6:
     resolution: {integrity: sha512-/7kkMsC+/kMs7gAYmmBR9P0vGTnOoLhQhyhQJSlXGI5bzTHp6xdo0TtKWQAsz6pmSAeVqKSbqeyP6hytqr9FDw==}
     dependencies:
@@ -1794,10 +1203,6 @@ packages:
       '@types/ws': 8.5.5
     dev: true
 
-  /@types/stack-utils@2.0.1:
-    resolution: {integrity: sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==}
-    dev: true
-
   /@types/tough-cookie@4.0.2:
     resolution: {integrity: sha512-Q5vtl1W5ue16D+nIaW8JWebSSraJVlK+EthKn7e7UcD4KWsaSJ8BqGPXNaPghgtcn/fhvrN17Tv8ksUsQpiplw==}
     dev: true
@@ -1812,16 +1217,6 @@ packages:
       '@types/node': 20.12.7
     dev: true
 
-  /@types/yargs-parser@21.0.0:
-    resolution: {integrity: sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==}
-    dev: true
-
-  /@types/yargs@17.0.24:
-    resolution: {integrity: sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw==}
-    dependencies:
-      '@types/yargs-parser': 21.0.0
-    dev: true
-
   /@types/yauzl@2.10.3:
     resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==}
     requiresBuild: true
@@ -1844,6 +1239,83 @@ packages:
       vite: 5.2.9(@types/node@20.12.7)
       vue: 3.4.23(typescript@5.3.3)
 
+  /@vitest/coverage-v8@1.6.0(vitest@1.6.0):
+    resolution: {integrity: sha512-KvapcbMY/8GYIG0rlwwOKCVNRc0OL20rrhFkg/CHNzncV03TE2XWvO5w9uZYoxNiMEBacAJt3unSOiZ7svePew==}
+    peerDependencies:
+      vitest: 1.6.0
+    dependencies:
+      '@ampproject/remapping': 2.2.1
+      '@bcoe/v8-coverage': 0.2.3
+      debug: 4.3.4
+      istanbul-lib-coverage: 3.2.2
+      istanbul-lib-report: 3.0.1
+      istanbul-lib-source-maps: 5.0.4
+      istanbul-reports: 3.1.6
+      magic-string: 0.30.9
+      magicast: 0.3.4
+      picocolors: 1.0.0
+      std-env: 3.7.0
+      strip-literal: 2.1.0
+      test-exclude: 6.0.0
+      vitest: 1.6.0(@vitest/ui@1.6.0)
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
+  /@vitest/expect@1.6.0:
+    resolution: {integrity: sha512-ixEvFVQjycy/oNgHjqsL6AZCDduC+tflRluaHIzKIsdbzkLn2U/iBnVeJwB6HsIjQBdfMR8Z0tRxKUsvFJEeWQ==}
+    dependencies:
+      '@vitest/spy': 1.6.0
+      '@vitest/utils': 1.6.0
+      chai: 4.4.1
+    dev: true
+
+  /@vitest/runner@1.6.0:
+    resolution: {integrity: sha512-P4xgwPjwesuBiHisAVz/LSSZtDjOTPYZVmNAnpHHSR6ONrf8eCJOFRvUwdHn30F5M1fxhqtl7QZQUk2dprIXAg==}
+    dependencies:
+      '@vitest/utils': 1.6.0
+      p-limit: 5.0.0
+      pathe: 1.1.2
+    dev: true
+
+  /@vitest/snapshot@1.6.0:
+    resolution: {integrity: sha512-+Hx43f8Chus+DCmygqqfetcAZrDJwvTj0ymqjQq4CvmpKFSTVteEOBzCusu1x2tt4OJcvBflyHUE0DZSLgEMtQ==}
+    dependencies:
+      magic-string: 0.30.9
+      pathe: 1.1.2
+      pretty-format: 29.7.0
+    dev: true
+
+  /@vitest/spy@1.6.0:
+    resolution: {integrity: sha512-leUTap6B/cqi/bQkXUu6bQV5TZPx7pmMBKBQiI0rJA8c3pB56ZsaTbREnF7CJfmvAS4V2cXIBAh/3rVwrrCYgw==}
+    dependencies:
+      tinyspy: 2.2.1
+    dev: true
+
+  /@vitest/ui@1.6.0(vitest@1.6.0):
+    resolution: {integrity: sha512-k3Lyo+ONLOgylctiGovRKy7V4+dIN2yxstX3eY5cWFXH6WP+ooVX79YSyi0GagdTQzLmT43BF27T0s6dOIPBXA==}
+    peerDependencies:
+      vitest: 1.6.0
+    dependencies:
+      '@vitest/utils': 1.6.0
+      fast-glob: 3.3.2
+      fflate: 0.8.2
+      flatted: 3.3.1
+      pathe: 1.1.2
+      picocolors: 1.0.0
+      sirv: 2.0.4
+      vitest: 1.6.0(@vitest/ui@1.6.0)
+    dev: true
+
+  /@vitest/utils@1.6.0:
+    resolution: {integrity: sha512-21cPiuGMoMZwiOHa2i4LXkMkMkCGzA+MVFV70jRwHo95dL4x/ts5GZhML1QWuy7yfp3WzK3lRvZi3JnXTYqrBw==}
+    dependencies:
+      diff-sequences: 29.6.3
+      estree-walker: 3.0.3
+      loupe: 2.3.7
+      pretty-format: 29.7.0
+    dev: true
+
   /@volar/language-core@1.11.1:
     resolution: {integrity: sha512-dOcNn3i9GgZAcJt43wuaEykSluAuOkQgzni1cuxLxTV0nJKanQztp7FxyswdRILaKH+P2XZMPRp2S4MV/pElCw==}
     dependencies:
@@ -2097,21 +1569,16 @@ packages:
       acorn-walk: 7.2.0
     dev: true
 
-  /acorn-globals@7.0.1:
-    resolution: {integrity: sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==}
-    dependencies:
-      acorn: 8.10.0
-      acorn-walk: 8.2.0
-    dev: true
-
   /acorn-walk@7.2.0:
     resolution: {integrity: sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==}
     engines: {node: '>=0.4.0'}
     dev: true
 
-  /acorn-walk@8.2.0:
-    resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==}
+  /acorn-walk@8.3.3:
+    resolution: {integrity: sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==}
     engines: {node: '>=0.4.0'}
+    dependencies:
+      acorn: 8.12.0
     dev: true
 
   /acorn@7.4.1:
@@ -2126,6 +1593,12 @@ packages:
     hasBin: true
     dev: true
 
+  /acorn@8.12.0:
+    resolution: {integrity: sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw==}
+    engines: {node: '>=0.4.0'}
+    hasBin: true
+    dev: true
+
   /add-stream@1.0.0:
     resolution: {integrity: sha512-qQLMr+8o0WC4FZGQTcJiKBVC59JylcPSrTtk6usvmIDFUOCKegapy1VHQwRbFMOFyb/inzUVqHs+eMYKDM1YeQ==}
     dev: true
@@ -2189,13 +1662,6 @@ packages:
     engines: {node: '>=6'}
     dev: true
 
-  /ansi-escapes@4.3.2:
-    resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==}
-    engines: {node: '>=8'}
-    dependencies:
-      type-fest: 0.21.3
-    dev: true
-
   /ansi-escapes@6.2.0:
     resolution: {integrity: sha512-kzRaCqXnpzWs+3z5ABPQiVke+iq0KXkHo8xiWV4RPTi5Yli0l97BEQuhXV1s7+aSU/fu1kUuxgS4MsQ0fRuygw==}
     engines: {node: '>=14.16'}
@@ -2307,78 +1773,6 @@ packages:
       - debug
     dev: true
 
-  /babel-jest@29.7.0(@babel/core@7.22.11):
-    resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==}
-    engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-    peerDependencies:
-      '@babel/core': ^7.8.0
-    dependencies:
-      '@babel/core': 7.22.11
-      '@jest/transform': 29.7.0
-      '@types/babel__core': 7.20.1
-      babel-plugin-istanbul: 6.1.1
-      babel-preset-jest: 29.6.3(@babel/core@7.22.11)
-      chalk: 4.1.2
-      graceful-fs: 4.2.11
-      slash: 3.0.0
-    transitivePeerDependencies:
-      - supports-color
-    dev: true
-
-  /babel-plugin-istanbul@6.1.1:
-    resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==}
-    engines: {node: '>=8'}
-    dependencies:
-      '@babel/helper-plugin-utils': 7.22.5
-      '@istanbuljs/load-nyc-config': 1.1.0
-      '@istanbuljs/schema': 0.1.3
-      istanbul-lib-instrument: 5.2.1
-      test-exclude: 6.0.0
-    transitivePeerDependencies:
-      - supports-color
-    dev: true
-
-  /babel-plugin-jest-hoist@29.6.3:
-    resolution: {integrity: sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==}
-    engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-    dependencies:
-      '@babel/template': 7.22.5
-      '@babel/types': 7.24.0
-      '@types/babel__core': 7.20.1
-      '@types/babel__traverse': 7.20.1
-    dev: true
-
-  /babel-preset-current-node-syntax@1.0.1(@babel/core@7.22.11):
-    resolution: {integrity: sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==}
-    peerDependencies:
-      '@babel/core': ^7.0.0
-    dependencies:
-      '@babel/core': 7.22.11
-      '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.22.11)
-      '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.22.11)
-      '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.22.11)
-      '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.22.11)
-      '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.22.11)
-      '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.22.11)
-      '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.22.11)
-      '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.22.11)
-      '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.22.11)
-      '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.22.11)
-      '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.22.11)
-      '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.22.11)
-    dev: true
-
-  /babel-preset-jest@29.6.3(@babel/core@7.22.11):
-    resolution: {integrity: sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==}
-    engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-    peerDependencies:
-      '@babel/core': ^7.0.0
-    dependencies:
-      '@babel/core': 7.22.11
-      babel-plugin-jest-hoist: 29.6.3
-      babel-preset-current-node-syntax: 1.0.1(@babel/core@7.22.11)
-    dev: true
-
   /balanced-match@1.0.2:
     resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
     dev: true
@@ -2452,17 +1846,6 @@ packages:
     resolution: {integrity: sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==}
     dev: true
 
-  /browserslist@4.21.10:
-    resolution: {integrity: sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==}
-    engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
-    hasBin: true
-    dependencies:
-      caniuse-lite: 1.0.30001524
-      electron-to-chromium: 1.4.503
-      node-releases: 2.0.13
-      update-browserslist-db: 1.0.11(browserslist@4.21.10)
-    dev: true
-
   /browserstack-local@1.5.5:
     resolution: {integrity: sha512-jKne7yosrMcptj3hqxp36TP9k0ZW2sCqhyurX24rUL4G3eT7OLgv+CSQN8iq5dtkv5IK+g+v8fWvsiC/S9KxMg==}
     dependencies:
@@ -2475,12 +1858,6 @@ packages:
       - supports-color
     dev: true
 
-  /bser@2.1.1:
-    resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==}
-    dependencies:
-      node-int64: 0.4.0
-    dev: true
-
   /buffer-crc32@0.2.13:
     resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==}
     dev: true
@@ -2501,6 +1878,11 @@ packages:
     engines: {node: '>=6'}
     dev: true
 
+  /cac@6.7.14:
+    resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==}
+    engines: {node: '>=8'}
+    dev: true
+
   /cacheable-lookup@5.0.4:
     resolution: {integrity: sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==}
     engines: {node: '>=10.6.0'}
@@ -2519,11 +1901,6 @@ packages:
       responselike: 2.0.1
     dev: true
 
-  /callsites@3.1.0:
-    resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
-    engines: {node: '>=6'}
-    dev: true
-
   /camelcase-keys@6.2.2:
     resolution: {integrity: sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==}
     engines: {node: '>=8'}
@@ -2543,10 +1920,6 @@ packages:
     engines: {node: '>=10'}
     dev: true
 
-  /caniuse-lite@1.0.30001524:
-    resolution: {integrity: sha512-Jj917pJtYg9HSJBF95HVX3Cdr89JUyLT4IZ8SvM5aDRni95swKgYi3TgYLH5hnGfPE/U1dg6IfZ50UsIlLkwSA==}
-    dev: true
-
   /chai-nightwatch@0.5.3:
     resolution: {integrity: sha512-38ixH/mqpY6IwnZkz6xPqx8aB5/KVR+j6VPugcir3EGOsphnWXrPH/mUt8Jp+ninL6ghY0AaJDQ10hSfCPGy/g==}
     engines: {node: '>= 12.0.0'}
@@ -2554,6 +1927,19 @@ packages:
       assertion-error: 1.1.0
     dev: true
 
+  /chai@4.4.1:
+    resolution: {integrity: sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==}
+    engines: {node: '>=4'}
+    dependencies:
+      assertion-error: 1.1.0
+      check-error: 1.0.3
+      deep-eql: 4.1.4
+      get-func-name: 2.0.2
+      loupe: 2.3.7
+      pathval: 1.1.1
+      type-detect: 4.0.8
+    dev: true
+
   /chalk@2.4.2:
     resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==}
     engines: {node: '>=4'}
@@ -2576,16 +1962,17 @@ packages:
     engines: {node: ^12.17.0 || ^14.13 || >=16.0.0}
     dev: true
 
-  /char-regex@1.0.2:
-    resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==}
-    engines: {node: '>=10'}
-    dev: true
-
   /check-error@1.0.2:
     resolution: {integrity: sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==}
     dev: true
 
-  /chokidar@3.5.3:
+  /check-error@1.0.3:
+    resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==}
+    dependencies:
+      get-func-name: 2.0.2
+    dev: true
+
+  /chokidar@3.5.3:
     resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==}
     engines: {node: '>= 8.10.0'}
     dependencies:
@@ -2631,15 +2018,6 @@ packages:
     resolution: {integrity: sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw==}
     dev: true
 
-  /ci-info@3.8.0:
-    resolution: {integrity: sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==}
-    engines: {node: '>=8'}
-    dev: true
-
-  /cjs-module-lexer@1.2.3:
-    resolution: {integrity: sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==}
-    dev: true
-
   /cli-boxes@2.2.1:
     resolution: {integrity: sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==}
     engines: {node: '>=6'}
@@ -2689,15 +2067,6 @@ packages:
       wrap-ansi: 7.0.0
     dev: true
 
-  /cliui@8.0.1:
-    resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==}
-    engines: {node: '>=12'}
-    dependencies:
-      string-width: 4.2.3
-      strip-ansi: 6.0.1
-      wrap-ansi: 7.0.0
-    dev: true
-
   /clone-response@1.0.3:
     resolution: {integrity: sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==}
     dependencies:
@@ -2709,15 +2078,6 @@ packages:
     engines: {node: '>=0.8'}
     dev: true
 
-  /co@4.6.0:
-    resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==}
-    engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'}
-    dev: true
-
-  /collect-v8-coverage@1.0.2:
-    resolution: {integrity: sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==}
-    dev: true
-
   /color-convert@1.9.3:
     resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==}
     dependencies:
@@ -2804,6 +2164,10 @@ packages:
     resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
     dev: true
 
+  /confbox@0.1.7:
+    resolution: {integrity: sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==}
+    dev: true
+
   /config-chain@1.1.13:
     resolution: {integrity: sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==}
     dependencies:
@@ -2974,37 +2338,10 @@ packages:
       through2: 4.0.2
     dev: true
 
-  /convert-source-map@1.9.0:
-    resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==}
-    dev: true
-
-  /convert-source-map@2.0.0:
-    resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
-    dev: true
-
   /core-util-is@1.0.3:
     resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==}
     dev: true
 
-  /create-jest@29.7.0:
-    resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==}
-    engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-    hasBin: true
-    dependencies:
-      '@jest/types': 29.6.3
-      chalk: 4.1.2
-      exit: 0.1.2
-      graceful-fs: 4.2.11
-      jest-config: 29.7.0(@types/node@20.12.7)
-      jest-util: 29.7.0
-      prompts: 2.4.2
-    transitivePeerDependencies:
-      - '@types/node'
-      - babel-plugin-macros
-      - supports-color
-      - ts-node
-    dev: true
-
   /cross-spawn@5.1.0:
     resolution: {integrity: sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==}
     dependencies:
@@ -3127,15 +2464,6 @@ packages:
       mimic-response: 3.1.0
     dev: true
 
-  /dedent@1.5.1:
-    resolution: {integrity: sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg==}
-    peerDependencies:
-      babel-plugin-macros: ^3.1.0
-    peerDependenciesMeta:
-      babel-plugin-macros:
-        optional: true
-    dev: true
-
   /deep-eql@4.0.1:
     resolution: {integrity: sha512-D/Oxqobjr+kxaHsgiQBZq9b6iAWdEj5W/JdJm8deNduAPc9CwXQ3BJJCuEqlrPXcy45iOMkGPZ0T81Dnz7UDCA==}
     engines: {node: '>=6'}
@@ -3143,6 +2471,13 @@ packages:
       type-detect: 4.0.8
     dev: true
 
+  /deep-eql@4.1.4:
+    resolution: {integrity: sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==}
+    engines: {node: '>=6'}
+    dependencies:
+      type-detect: 4.0.8
+    dev: true
+
   /deep-is@0.1.4:
     resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
     dev: true
@@ -3173,11 +2508,6 @@ packages:
     engines: {node: '>=0.4.0'}
     dev: true
 
-  /detect-newline@3.1.0:
-    resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==}
-    engines: {node: '>=8'}
-    dev: true
-
   /devtools-protocol@0.0.1025565:
     resolution: {integrity: sha512-0s5sbGQR/EfYQhd8EpZgphpndsv+CufTlaeUyA6vYXCA0H5kMAsHCS/cHtUFWoKJCO125hpoKicQCfpxRj4oqw==}
     dev: true
@@ -3248,15 +2578,6 @@ packages:
       jake: 10.8.7
     dev: true
 
-  /electron-to-chromium@1.4.503:
-    resolution: {integrity: sha512-LF2IQit4B0VrUHFeQkWhZm97KuJSGF2WJqq1InpY+ECpFRkXd8yTIaTtJxsO0OKDmiBYwWqcrNaXOurn2T2wiA==}
-    dev: true
-
-  /emittery@0.13.1:
-    resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==}
-    engines: {node: '>=12'}
-    dev: true
-
   /emoji-regex@10.3.0:
     resolution: {integrity: sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==}
     dev: true
@@ -3343,11 +2664,6 @@ packages:
     engines: {node: '>=0.8.0'}
     dev: true
 
-  /escape-string-regexp@2.0.0:
-    resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==}
-    engines: {node: '>=8'}
-    dev: true
-
   /escape-string-regexp@4.0.0:
     resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
     engines: {node: '>=10'}
@@ -3379,6 +2695,12 @@ packages:
   /estree-walker@2.0.2:
     resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
 
+  /estree-walker@3.0.3:
+    resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==}
+    dependencies:
+      '@types/estree': 1.0.5
+    dev: true
+
   /esutils@2.0.3:
     resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
     engines: {node: '>=0.10.0'}
@@ -3413,21 +2735,6 @@ packages:
       strip-eof: 1.0.0
     dev: true
 
-  /execa@5.1.1:
-    resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==}
-    engines: {node: '>=10'}
-    dependencies:
-      cross-spawn: 7.0.3
-      get-stream: 6.0.1
-      human-signals: 2.1.0
-      is-stream: 2.0.1
-      merge-stream: 2.0.0
-      npm-run-path: 4.0.1
-      onetime: 5.1.2
-      signal-exit: 3.0.7
-      strip-final-newline: 2.0.0
-    dev: true
-
   /execa@8.0.1:
     resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==}
     engines: {node: '>=16.17'}
@@ -3443,22 +2750,6 @@ packages:
       strip-final-newline: 3.0.0
     dev: true
 
-  /exit@0.1.2:
-    resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==}
-    engines: {node: '>= 0.8.0'}
-    dev: true
-
-  /expect@29.7.0:
-    resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==}
-    engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-    dependencies:
-      '@jest/expect-utils': 29.7.0
-      jest-get-type: 29.6.3
-      jest-matcher-utils: 29.7.0
-      jest-message-util: 29.7.0
-      jest-util: 29.7.0
-    dev: true
-
   /extract-zip@2.0.1:
     resolution: {integrity: sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==}
     engines: {node: '>= 10.17.0'}
@@ -3502,18 +2793,16 @@ packages:
       reusify: 1.0.4
     dev: true
 
-  /fb-watchman@2.0.2:
-    resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==}
-    dependencies:
-      bser: 2.1.1
-    dev: true
-
   /fd-slicer@1.1.0:
     resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==}
     dependencies:
       pend: 1.2.0
     dev: true
 
+  /fflate@0.8.2:
+    resolution: {integrity: sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==}
+    dev: true
+
   /filelist@1.0.4:
     resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==}
     dependencies:
@@ -3564,6 +2853,10 @@ packages:
     hasBin: true
     dev: true
 
+  /flatted@3.3.1:
+    resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==}
+    dev: true
+
   /focus-trap@7.5.4:
     resolution: {integrity: sha512-N7kHdlgsO/v+iD/dMoJKtsSqs5Dz/dXZVebRgJw23LDk+jMi/974zyiOYDziY2JPp8xivq9BmUGwIJMiuSBi7w==}
     dependencies:
@@ -3660,11 +2953,6 @@ packages:
       - supports-color
     dev: true
 
-  /gensync@1.0.0-beta.2:
-    resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==}
-    engines: {node: '>=6.9.0'}
-    dev: true
-
   /get-caller-file@2.0.5:
     resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==}
     engines: {node: 6.* || 8.* || >= 10.*}
@@ -3679,9 +2967,8 @@ packages:
     resolution: {integrity: sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==}
     dev: true
 
-  /get-package-type@0.1.0:
-    resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==}
-    engines: {node: '>=8.0.0'}
+  /get-func-name@2.0.2:
+    resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==}
     dev: true
 
   /get-pkg-repo@4.2.1:
@@ -3707,11 +2994,6 @@ packages:
       pump: 3.0.0
     dev: true
 
-  /get-stream@6.0.1:
-    resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==}
-    engines: {node: '>=10'}
-    dev: true
-
   /get-stream@8.0.1:
     resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==}
     engines: {node: '>=16'}
@@ -3815,11 +3097,6 @@ packages:
       once: 1.4.0
     dev: true
 
-  /globals@11.12.0:
-    resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==}
-    engines: {node: '>=4'}
-    dev: true
-
   /globby@14.0.1:
     resolution: {integrity: sha512-jOMLD2Z7MAhyG8aJpNOpmziMOP4rPLcc95oQPKXBazW82z+CEgPFBQvEpRUa1KeIMUJo4Wsm+q6uzO/Q/4BksQ==}
     engines: {node: '>=18'}
@@ -3964,11 +3241,6 @@ packages:
       - supports-color
     dev: true
 
-  /human-signals@2.1.0:
-    resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==}
-    engines: {node: '>=10.17.0'}
-    dev: true
-
   /human-signals@5.0.0:
     resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==}
     engines: {node: '>=16.17.0'}
@@ -3999,20 +3271,6 @@ packages:
     engines: {node: '>=8'}
     dev: true
 
-  /import-local@3.1.0:
-    resolution: {integrity: sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==}
-    engines: {node: '>=8'}
-    hasBin: true
-    dependencies:
-      pkg-dir: 4.2.0
-      resolve-cwd: 3.0.0
-    dev: true
-
-  /imurmurhash@0.1.4:
-    resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
-    engines: {node: '>=0.8.19'}
-    dev: true
-
   /indent-string@4.0.0:
     resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==}
     engines: {node: '>=8'}
@@ -4103,11 +3361,6 @@ packages:
       get-east-asian-width: 1.2.0
     dev: true
 
-  /is-generator-fn@2.1.0:
-    resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==}
-    engines: {node: '>=6'}
-    dev: true
-
   /is-glob@4.0.3:
     resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
     engines: {node: '>=0.10.0'}
@@ -4163,11 +3416,6 @@ packages:
     engines: {node: '>=0.10.0'}
     dev: true
 
-  /is-stream@2.0.1:
-    resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==}
-    engines: {node: '>=8'}
-    dev: true
-
   /is-stream@3.0.0:
     resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==}
     engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
@@ -4213,53 +3461,27 @@ packages:
     resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
     dev: true
 
-  /istanbul-lib-coverage@3.2.0:
-    resolution: {integrity: sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==}
+  /istanbul-lib-coverage@3.2.2:
+    resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==}
     engines: {node: '>=8'}
     dev: true
 
-  /istanbul-lib-instrument@5.2.1:
-    resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==}
-    engines: {node: '>=8'}
-    dependencies:
-      '@babel/core': 7.22.11
-      '@babel/parser': 7.24.4
-      '@istanbuljs/schema': 0.1.3
-      istanbul-lib-coverage: 3.2.0
-      semver: 6.3.1
-    transitivePeerDependencies:
-      - supports-color
-    dev: true
-
-  /istanbul-lib-instrument@6.0.0:
-    resolution: {integrity: sha512-x58orMzEVfzPUKqlbLd1hXCnySCxKdDKa6Rjg97CwuLLRI4g3FHTdnExu1OqffVFay6zeMW+T6/DowFLndWnIw==}
-    engines: {node: '>=10'}
-    dependencies:
-      '@babel/core': 7.22.11
-      '@babel/parser': 7.24.4
-      '@istanbuljs/schema': 0.1.3
-      istanbul-lib-coverage: 3.2.0
-      semver: 7.6.0
-    transitivePeerDependencies:
-      - supports-color
-    dev: true
-
   /istanbul-lib-report@3.0.1:
     resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==}
     engines: {node: '>=10'}
     dependencies:
-      istanbul-lib-coverage: 3.2.0
+      istanbul-lib-coverage: 3.2.2
       make-dir: 4.0.0
       supports-color: 7.2.0
     dev: true
 
-  /istanbul-lib-source-maps@4.0.1:
-    resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==}
+  /istanbul-lib-source-maps@5.0.4:
+    resolution: {integrity: sha512-wHOoEsNJTVltaJp8eVkm8w+GVkVNHT2YDYo53YdzQEL2gWm1hBX5cGFR9hQJtuGLebidVX7et3+dmDZrmclduw==}
     engines: {node: '>=10'}
     dependencies:
+      '@jridgewell/trace-mapping': 0.3.25
       debug: 4.3.4
-      istanbul-lib-coverage: 3.2.0
-      source-map: 0.6.1
+      istanbul-lib-coverage: 3.2.2
     transitivePeerDependencies:
       - supports-color
     dev: true
@@ -4292,443 +3514,6 @@ packages:
       minimatch: 3.1.2
     dev: true
 
-  /jest-changed-files@29.7.0:
-    resolution: {integrity: sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==}
-    engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-    dependencies:
-      execa: 5.1.1
-      jest-util: 29.7.0
-      p-limit: 3.1.0
-    dev: true
-
-  /jest-circus@29.7.0:
-    resolution: {integrity: sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==}
-    engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-    dependencies:
-      '@jest/environment': 29.7.0
-      '@jest/expect': 29.7.0
-      '@jest/test-result': 29.7.0
-      '@jest/types': 29.6.3
-      '@types/node': 20.12.7
-      chalk: 4.1.2
-      co: 4.6.0
-      dedent: 1.5.1
-      is-generator-fn: 2.1.0
-      jest-each: 29.7.0
-      jest-matcher-utils: 29.7.0
-      jest-message-util: 29.7.0
-      jest-runtime: 29.7.0
-      jest-snapshot: 29.7.0
-      jest-util: 29.7.0
-      p-limit: 3.1.0
-      pretty-format: 29.7.0
-      pure-rand: 6.0.2
-      slash: 3.0.0
-      stack-utils: 2.0.6
-    transitivePeerDependencies:
-      - babel-plugin-macros
-      - supports-color
-    dev: true
-
-  /jest-cli@29.7.0:
-    resolution: {integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==}
-    engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-    hasBin: true
-    peerDependencies:
-      node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0
-    peerDependenciesMeta:
-      node-notifier:
-        optional: true
-    dependencies:
-      '@jest/core': 29.7.0
-      '@jest/test-result': 29.7.0
-      '@jest/types': 29.6.3
-      chalk: 4.1.2
-      create-jest: 29.7.0
-      exit: 0.1.2
-      import-local: 3.1.0
-      jest-config: 29.7.0(@types/node@20.12.7)
-      jest-util: 29.7.0
-      jest-validate: 29.7.0
-      yargs: 17.7.2
-    transitivePeerDependencies:
-      - '@types/node'
-      - babel-plugin-macros
-      - supports-color
-      - ts-node
-    dev: true
-
-  /jest-config@29.7.0(@types/node@20.12.7):
-    resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==}
-    engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-    peerDependencies:
-      '@types/node': '*'
-      ts-node: '>=9.0.0'
-    peerDependenciesMeta:
-      '@types/node':
-        optional: true
-      ts-node:
-        optional: true
-    dependencies:
-      '@babel/core': 7.22.11
-      '@jest/test-sequencer': 29.7.0
-      '@jest/types': 29.6.3
-      '@types/node': 20.12.7
-      babel-jest: 29.7.0(@babel/core@7.22.11)
-      chalk: 4.1.2
-      ci-info: 3.8.0
-      deepmerge: 4.3.1
-      glob: 7.2.3
-      graceful-fs: 4.2.11
-      jest-circus: 29.7.0
-      jest-environment-node: 29.7.0
-      jest-get-type: 29.6.3
-      jest-regex-util: 29.6.3
-      jest-resolve: 29.7.0
-      jest-runner: 29.7.0
-      jest-util: 29.7.0
-      jest-validate: 29.7.0
-      micromatch: 4.0.5
-      parse-json: 5.2.0
-      pretty-format: 29.7.0
-      slash: 3.0.0
-      strip-json-comments: 3.1.1
-    transitivePeerDependencies:
-      - babel-plugin-macros
-      - supports-color
-    dev: true
-
-  /jest-diff@29.7.0:
-    resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==}
-    engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-    dependencies:
-      chalk: 4.1.2
-      diff-sequences: 29.6.3
-      jest-get-type: 29.6.3
-      pretty-format: 29.7.0
-    dev: true
-
-  /jest-docblock@29.7.0:
-    resolution: {integrity: sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==}
-    engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-    dependencies:
-      detect-newline: 3.1.0
-    dev: true
-
-  /jest-each@29.7.0:
-    resolution: {integrity: sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==}
-    engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-    dependencies:
-      '@jest/types': 29.6.3
-      chalk: 4.1.2
-      jest-get-type: 29.6.3
-      jest-util: 29.7.0
-      pretty-format: 29.7.0
-    dev: true
-
-  /jest-environment-jsdom@29.7.0:
-    resolution: {integrity: sha512-k9iQbsf9OyOfdzWH8HDmrRT0gSIcX+FLNW7IQq94tFX0gynPwqDTW0Ho6iMVNjGz/nb+l/vW3dWM2bbLLpkbXA==}
-    engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-    peerDependencies:
-      canvas: ^2.5.0
-    peerDependenciesMeta:
-      canvas:
-        optional: true
-    dependencies:
-      '@jest/environment': 29.7.0
-      '@jest/fake-timers': 29.7.0
-      '@jest/types': 29.6.3
-      '@types/jsdom': 20.0.1
-      '@types/node': 20.11.19
-      jest-mock: 29.7.0
-      jest-util: 29.7.0
-      jsdom: 20.0.3
-    transitivePeerDependencies:
-      - bufferutil
-      - supports-color
-      - utf-8-validate
-    dev: true
-
-  /jest-environment-node@29.7.0:
-    resolution: {integrity: sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==}
-    engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-    dependencies:
-      '@jest/environment': 29.7.0
-      '@jest/fake-timers': 29.7.0
-      '@jest/types': 29.6.3
-      '@types/node': 20.12.7
-      jest-mock: 29.7.0
-      jest-util: 29.7.0
-    dev: true
-
-  /jest-get-type@29.6.3:
-    resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==}
-    engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-    dev: true
-
-  /jest-haste-map@29.7.0:
-    resolution: {integrity: sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==}
-    engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-    dependencies:
-      '@jest/types': 29.6.3
-      '@types/graceful-fs': 4.1.6
-      '@types/node': 20.12.7
-      anymatch: 3.1.3
-      fb-watchman: 2.0.2
-      graceful-fs: 4.2.11
-      jest-regex-util: 29.6.3
-      jest-util: 29.7.0
-      jest-worker: 29.7.0
-      micromatch: 4.0.5
-      walker: 1.0.8
-    optionalDependencies:
-      fsevents: 2.3.3
-    dev: true
-
-  /jest-leak-detector@29.7.0:
-    resolution: {integrity: sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==}
-    engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-    dependencies:
-      jest-get-type: 29.6.3
-      pretty-format: 29.7.0
-    dev: true
-
-  /jest-matcher-utils@29.7.0:
-    resolution: {integrity: sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==}
-    engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-    dependencies:
-      chalk: 4.1.2
-      jest-diff: 29.7.0
-      jest-get-type: 29.6.3
-      pretty-format: 29.7.0
-    dev: true
-
-  /jest-message-util@29.7.0:
-    resolution: {integrity: sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==}
-    engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-    dependencies:
-      '@babel/code-frame': 7.22.10
-      '@jest/types': 29.6.3
-      '@types/stack-utils': 2.0.1
-      chalk: 4.1.2
-      graceful-fs: 4.2.11
-      micromatch: 4.0.5
-      pretty-format: 29.7.0
-      slash: 3.0.0
-      stack-utils: 2.0.6
-    dev: true
-
-  /jest-mock-warn@1.1.0:
-    resolution: {integrity: sha512-Q0EjGIUowgcuH7K1v6KgZ/WtqQaA9kc/TxayKaZKKeTGBn9nC4uKI65nt0O3l8opaPi2VSvG18WcLPEqzowxrQ==}
-    dev: true
-
-  /jest-mock@29.7.0:
-    resolution: {integrity: sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==}
-    engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-    dependencies:
-      '@jest/types': 29.6.3
-      '@types/node': 20.11.19
-      jest-util: 29.7.0
-    dev: true
-
-  /jest-pnp-resolver@1.2.3(jest-resolve@29.7.0):
-    resolution: {integrity: sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==}
-    engines: {node: '>=6'}
-    peerDependencies:
-      jest-resolve: '*'
-    peerDependenciesMeta:
-      jest-resolve:
-        optional: true
-    dependencies:
-      jest-resolve: 29.7.0
-    dev: true
-
-  /jest-regex-util@29.6.3:
-    resolution: {integrity: sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==}
-    engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-    dev: true
-
-  /jest-resolve-dependencies@29.7.0:
-    resolution: {integrity: sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==}
-    engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-    dependencies:
-      jest-regex-util: 29.6.3
-      jest-snapshot: 29.7.0
-    transitivePeerDependencies:
-      - supports-color
-    dev: true
-
-  /jest-resolve@29.7.0:
-    resolution: {integrity: sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==}
-    engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-    dependencies:
-      chalk: 4.1.2
-      graceful-fs: 4.2.11
-      jest-haste-map: 29.7.0
-      jest-pnp-resolver: 1.2.3(jest-resolve@29.7.0)
-      jest-util: 29.7.0
-      jest-validate: 29.7.0
-      resolve: 1.22.8
-      resolve.exports: 2.0.2
-      slash: 3.0.0
-    dev: true
-
-  /jest-runner@29.7.0:
-    resolution: {integrity: sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==}
-    engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-    dependencies:
-      '@jest/console': 29.7.0
-      '@jest/environment': 29.7.0
-      '@jest/test-result': 29.7.0
-      '@jest/transform': 29.7.0
-      '@jest/types': 29.6.3
-      '@types/node': 20.12.7
-      chalk: 4.1.2
-      emittery: 0.13.1
-      graceful-fs: 4.2.11
-      jest-docblock: 29.7.0
-      jest-environment-node: 29.7.0
-      jest-haste-map: 29.7.0
-      jest-leak-detector: 29.7.0
-      jest-message-util: 29.7.0
-      jest-resolve: 29.7.0
-      jest-runtime: 29.7.0
-      jest-util: 29.7.0
-      jest-watcher: 29.7.0
-      jest-worker: 29.7.0
-      p-limit: 3.1.0
-      source-map-support: 0.5.13
-    transitivePeerDependencies:
-      - supports-color
-    dev: true
-
-  /jest-runtime@29.7.0:
-    resolution: {integrity: sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==}
-    engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-    dependencies:
-      '@jest/environment': 29.7.0
-      '@jest/fake-timers': 29.7.0
-      '@jest/globals': 29.7.0
-      '@jest/source-map': 29.6.3
-      '@jest/test-result': 29.7.0
-      '@jest/transform': 29.7.0
-      '@jest/types': 29.6.3
-      '@types/node': 20.12.7
-      chalk: 4.1.2
-      cjs-module-lexer: 1.2.3
-      collect-v8-coverage: 1.0.2
-      glob: 7.2.3
-      graceful-fs: 4.2.11
-      jest-haste-map: 29.7.0
-      jest-message-util: 29.7.0
-      jest-mock: 29.7.0
-      jest-regex-util: 29.6.3
-      jest-resolve: 29.7.0
-      jest-snapshot: 29.7.0
-      jest-util: 29.7.0
-      slash: 3.0.0
-      strip-bom: 4.0.0
-    transitivePeerDependencies:
-      - supports-color
-    dev: true
-
-  /jest-snapshot@29.7.0:
-    resolution: {integrity: sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==}
-    engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-    dependencies:
-      '@babel/core': 7.22.11
-      '@babel/generator': 7.22.10
-      '@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.22.11)
-      '@babel/plugin-syntax-typescript': 7.22.5(@babel/core@7.22.11)
-      '@babel/types': 7.22.11
-      '@jest/expect-utils': 29.7.0
-      '@jest/transform': 29.7.0
-      '@jest/types': 29.6.3
-      babel-preset-current-node-syntax: 1.0.1(@babel/core@7.22.11)
-      chalk: 4.1.2
-      expect: 29.7.0
-      graceful-fs: 4.2.11
-      jest-diff: 29.7.0
-      jest-get-type: 29.6.3
-      jest-matcher-utils: 29.7.0
-      jest-message-util: 29.7.0
-      jest-util: 29.7.0
-      natural-compare: 1.4.0
-      pretty-format: 29.7.0
-      semver: 7.6.0
-    transitivePeerDependencies:
-      - supports-color
-    dev: true
-
-  /jest-util@29.7.0:
-    resolution: {integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==}
-    engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-    dependencies:
-      '@jest/types': 29.6.3
-      '@types/node': 20.11.19
-      chalk: 4.1.2
-      ci-info: 3.8.0
-      graceful-fs: 4.2.11
-      picomatch: 2.3.1
-    dev: true
-
-  /jest-validate@29.7.0:
-    resolution: {integrity: sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==}
-    engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-    dependencies:
-      '@jest/types': 29.6.3
-      camelcase: 6.3.0
-      chalk: 4.1.2
-      jest-get-type: 29.6.3
-      leven: 3.1.0
-      pretty-format: 29.7.0
-    dev: true
-
-  /jest-watcher@29.7.0:
-    resolution: {integrity: sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==}
-    engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-    dependencies:
-      '@jest/test-result': 29.7.0
-      '@jest/types': 29.6.3
-      '@types/node': 20.12.7
-      ansi-escapes: 4.3.2
-      chalk: 4.1.2
-      emittery: 0.13.1
-      jest-util: 29.7.0
-      string-length: 4.0.2
-    dev: true
-
-  /jest-worker@29.7.0:
-    resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==}
-    engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-    dependencies:
-      '@types/node': 20.12.7
-      jest-util: 29.7.0
-      merge-stream: 2.0.0
-      supports-color: 8.1.1
-    dev: true
-
-  /jest@29.7.0:
-    resolution: {integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==}
-    engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
-    hasBin: true
-    peerDependencies:
-      node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0
-    peerDependenciesMeta:
-      node-notifier:
-        optional: true
-    dependencies:
-      '@jest/core': 29.7.0
-      '@jest/types': 29.6.3
-      import-local: 3.1.0
-      jest-cli: 29.7.0
-    transitivePeerDependencies:
-      - '@types/node'
-      - babel-plugin-macros
-      - supports-color
-      - ts-node
-    dev: true
-
   /jju@1.4.0:
     resolution: {integrity: sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==}
     dev: true
@@ -4748,12 +3533,8 @@ packages:
     resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
     dev: true
 
-  /js-yaml@3.14.1:
-    resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==}
-    hasBin: true
-    dependencies:
-      argparse: 1.0.10
-      esprima: 4.0.1
+  /js-tokens@9.0.0:
+    resolution: {integrity: sha512-WriZw1luRMlmV3LGJaR6QOJjWwgLUTf89OwT2lUOyjX2dJGBwgmIkbcz+7WFZjrZM635JOIR517++e/67CP9dQ==}
     dev: true
 
   /js-yaml@4.1.0:
@@ -4805,53 +3586,6 @@ packages:
       - utf-8-validate
     dev: true
 
-  /jsdom@20.0.3:
-    resolution: {integrity: sha512-SYhBvTh89tTfCD/CRdSOm13mOBa42iTaTyfyEWBdKcGdPxPtLFBXuHR8XHb33YNYaP+lLbmSvBTsnoesCNJEsQ==}
-    engines: {node: '>=14'}
-    peerDependencies:
-      canvas: ^2.5.0
-    peerDependenciesMeta:
-      canvas:
-        optional: true
-    dependencies:
-      abab: 2.0.6
-      acorn: 8.10.0
-      acorn-globals: 7.0.1
-      cssom: 0.5.0
-      cssstyle: 2.3.0
-      data-urls: 3.0.2
-      decimal.js: 10.4.3
-      domexception: 4.0.0
-      escodegen: 2.1.0
-      form-data: 4.0.0
-      html-encoding-sniffer: 3.0.0
-      http-proxy-agent: 5.0.0
-      https-proxy-agent: 5.0.1
-      is-potential-custom-element-name: 1.0.1
-      nwsapi: 2.2.7
-      parse5: 7.1.2
-      saxes: 6.0.0
-      symbol-tree: 3.2.4
-      tough-cookie: 4.1.3
-      w3c-xmlserializer: 4.0.0
-      webidl-conversions: 7.0.0
-      whatwg-encoding: 2.0.0
-      whatwg-mimetype: 3.0.0
-      whatwg-url: 11.0.0
-      ws: 8.13.0
-      xml-name-validator: 4.0.0
-    transitivePeerDependencies:
-      - bufferutil
-      - supports-color
-      - utf-8-validate
-    dev: true
-
-  /jsesc@2.5.2:
-    resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==}
-    engines: {node: '>=4'}
-    hasBin: true
-    dev: true
-
   /json-buffer@3.0.1:
     resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==}
     dev: true
@@ -4872,12 +3606,6 @@ packages:
     resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==}
     dev: true
 
-  /json5@2.2.3:
-    resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==}
-    engines: {node: '>=6'}
-    hasBin: true
-    dev: true
-
   /jsonc-parser@3.2.1:
     resolution: {integrity: sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==}
     dev: true
@@ -4921,16 +3649,6 @@ packages:
     engines: {node: '>=0.10.0'}
     dev: true
 
-  /kleur@3.0.3:
-    resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==}
-    engines: {node: '>=6'}
-    dev: true
-
-  /leven@3.1.0:
-    resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==}
-    engines: {node: '>=6'}
-    dev: true
-
   /lie@3.3.0:
     resolution: {integrity: sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==}
     dependencies:
@@ -4987,6 +3705,14 @@ packages:
       strip-bom: 3.0.0
     dev: true
 
+  /local-pkg@0.5.0:
+    resolution: {integrity: sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==}
+    engines: {node: '>=14'}
+    dependencies:
+      mlly: 1.7.1
+      pkg-types: 1.1.1
+    dev: true
+
   /locate-path@2.0.0:
     resolution: {integrity: sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==}
     engines: {node: '>=4'}
@@ -5137,6 +3863,12 @@ packages:
       get-func-name: 2.0.0
     dev: true
 
+  /loupe@2.3.7:
+    resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==}
+    dependencies:
+      get-func-name: 2.0.2
+    dev: true
+
   /lowercase-keys@2.0.0:
     resolution: {integrity: sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==}
     engines: {node: '>=8'}
@@ -5154,12 +3886,6 @@ packages:
       yallist: 2.1.2
     dev: true
 
-  /lru-cache@5.1.1:
-    resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
-    dependencies:
-      yallist: 3.1.1
-    dev: true
-
   /lru-cache@6.0.0:
     resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==}
     engines: {node: '>=10'}
@@ -5184,6 +3910,14 @@ packages:
     dependencies:
       '@jridgewell/sourcemap-codec': 1.4.15
 
+  /magicast@0.3.4:
+    resolution: {integrity: sha512-TyDF/Pn36bBji9rWKHlZe+PZb6Mx5V8IHCSxk7X4aljM4e/vyDvZZYwHewdVaqiA0nb3ghfHU/6AUpDxWoER2Q==}
+    dependencies:
+      '@babel/parser': 7.24.4
+      '@babel/types': 7.24.0
+      source-map-js: 1.2.0
+    dev: true
+
   /make-dir@3.1.0:
     resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==}
     engines: {node: '>=8'}
@@ -5198,12 +3932,6 @@ packages:
       semver: 7.6.0
     dev: true
 
-  /makeerror@1.0.12:
-    resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==}
-    dependencies:
-      tmpl: 1.0.5
-    dev: true
-
   /map-obj@1.0.1:
     resolution: {integrity: sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==}
     engines: {node: '>=0.10.0'}
@@ -5383,6 +4111,15 @@ packages:
     hasBin: true
     dev: true
 
+  /mlly@1.7.1:
+    resolution: {integrity: sha512-rrVRZRELyQzrIUAVMHxP97kv+G786pHmOKzuFII8zDYahFBS7qnHh2AlYSl1GAHhaMPCz6/oHjVMcfFYgFYHgA==}
+    dependencies:
+      acorn: 8.12.0
+      pathe: 1.1.2
+      pkg-types: 1.1.1
+      ufo: 1.5.3
+    dev: true
+
   /mocha@9.2.2:
     resolution: {integrity: sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g==}
     engines: {node: '>= 12.0.0'}
@@ -5419,6 +4156,11 @@ packages:
     engines: {node: '>=0.10.0'}
     dev: true
 
+  /mrmime@2.0.0:
+    resolution: {integrity: sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==}
+    engines: {node: '>=10'}
+    dev: true
+
   /ms@2.1.2:
     resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==}
 
@@ -5449,10 +4191,6 @@ packages:
     engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
     hasBin: true
 
-  /natural-compare@1.4.0:
-    resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
-    dev: true
-
   /neo-async@2.6.2:
     resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==}
     dev: true
@@ -5524,14 +4262,6 @@ packages:
       - utf-8-validate
     dev: true
 
-  /node-int64@0.4.0:
-    resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==}
-    dev: true
-
-  /node-releases@2.0.13:
-    resolution: {integrity: sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==}
-    dev: true
-
   /nopt@7.2.0:
     resolution: {integrity: sha512-CVDtwCdhYIvnAzFoJ6NJ6dX3oga9/HyciQDnG1vQDjSLMeKLJ4A93ZqYKDrgYSr1FBY5/hMYC+2VCi24pgpkGA==}
     engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
@@ -5581,13 +4311,6 @@ packages:
       path-key: 2.0.1
     dev: true
 
-  /npm-run-path@4.0.1:
-    resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==}
-    engines: {node: '>=8'}
-    dependencies:
-      path-key: 3.1.1
-    dev: true
-
   /npm-run-path@5.1.0:
     resolution: {integrity: sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==}
     engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
@@ -5679,6 +4402,13 @@ packages:
       yocto-queue: 0.1.0
     dev: true
 
+  /p-limit@5.0.0:
+    resolution: {integrity: sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==}
+    engines: {node: '>=18'}
+    dependencies:
+      yocto-queue: 1.0.0
+    dev: true
+
   /p-locate@2.0.0:
     resolution: {integrity: sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==}
     engines: {node: '>=4'}
@@ -5805,6 +4535,10 @@ packages:
     engines: {node: '>=12'}
     dev: true
 
+  /pathe@1.1.2:
+    resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==}
+    dev: true
+
   /pathval@1.1.1:
     resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==}
     dev: true
@@ -5859,6 +4593,14 @@ packages:
       find-up: 4.1.0
     dev: true
 
+  /pkg-types@1.1.1:
+    resolution: {integrity: sha512-ko14TjmDuQJ14zsotODv7dBlwxKhUKQEhuhmbqo1uCi9BB0Z2alo/wAXg6q1dTR5TyuqYyWhjtfe/Tsh+X28jQ==}
+    dependencies:
+      confbox: 0.1.7
+      mlly: 1.7.1
+      pathe: 1.1.2
+    dev: true
+
   /postcss@8.4.38:
     resolution: {integrity: sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==}
     engines: {node: ^10 || ^12 || >=14}
@@ -5890,14 +4632,6 @@ packages:
     resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==}
     dev: true
 
-  /prompts@2.4.2:
-    resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==}
-    engines: {node: '>= 6'}
-    dependencies:
-      kleur: 3.0.3
-      sisteransi: 1.0.5
-    dev: true
-
   /proto-list@1.2.4:
     resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==}
     dev: true
@@ -5939,10 +4673,6 @@ packages:
     engines: {node: '>=6'}
     dev: true
 
-  /pure-rand@6.0.2:
-    resolution: {integrity: sha512-6Yg0ekpKICSjPswYOuC5sku/TSWaRYlA0qsXqJgM/d/4pLPHPuTxK7Nbf7jFKzAeedUhR8C7K9Uv63FBsSo8xQ==}
-    dev: true
-
   /q@1.5.1:
     resolution: {integrity: sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==}
     engines: {node: '>=0.6.0', teleport: '>=0.2.0'}
@@ -6061,23 +4791,6 @@ packages:
     resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==}
     dev: true
 
-  /resolve-cwd@3.0.0:
-    resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==}
-    engines: {node: '>=8'}
-    dependencies:
-      resolve-from: 5.0.0
-    dev: true
-
-  /resolve-from@5.0.0:
-    resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==}
-    engines: {node: '>=8'}
-    dev: true
-
-  /resolve.exports@2.0.2:
-    resolution: {integrity: sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==}
-    engines: {node: '>=10'}
-    dev: true
-
   /resolve@1.19.0:
     resolution: {integrity: sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==}
     dependencies:
@@ -6233,13 +4946,6 @@ packages:
       xmlchars: 2.2.0
     dev: true
 
-  /saxes@6.0.0:
-    resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==}
-    engines: {node: '>=v12.22.7'}
-    dependencies:
-      xmlchars: 2.2.0
-    dev: true
-
   /search-insights@2.13.0:
     resolution: {integrity: sha512-Orrsjf9trHHxFRuo9/rzm0KIWmgzE8RMlZMzuhZOJ01Rnz3D0YBAe+V6473t6/H6c7irs6Lt48brULAiRWb3Vw==}
     dev: false
@@ -6345,6 +5051,10 @@ packages:
       '@shikijs/core': 1.3.0
     dev: false
 
+  /siginfo@2.0.0:
+    resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==}
+    dev: true
+
   /signal-exit@3.0.7:
     resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==}
     dev: true
@@ -6364,13 +5074,13 @@ packages:
       - supports-color
     dev: false
 
-  /sisteransi@1.0.5:
-    resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==}
-    dev: true
-
-  /slash@3.0.0:
-    resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
-    engines: {node: '>=8'}
+  /sirv@2.0.4:
+    resolution: {integrity: sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==}
+    engines: {node: '>= 10'}
+    dependencies:
+      '@polka/url': 1.0.0-next.25
+      mrmime: 2.0.0
+      totalist: 3.0.1
     dev: true
 
   /slash@4.0.0:
@@ -6407,13 +5117,6 @@ packages:
     resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==}
     engines: {node: '>=0.10.0'}
 
-  /source-map-support@0.5.13:
-    resolution: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==}
-    dependencies:
-      buffer-from: 1.1.2
-      source-map: 0.6.1
-    dev: true
-
   /source-map-support@0.5.21:
     resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==}
     dependencies:
@@ -6475,11 +5178,8 @@ packages:
     resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==}
     dev: true
 
-  /stack-utils@2.0.6:
-    resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==}
-    engines: {node: '>=10'}
-    dependencies:
-      escape-string-regexp: 2.0.0
+  /stackback@0.0.2:
+    resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==}
     dev: true
 
   /stacktrace-parser@0.1.10:
@@ -6489,6 +5189,10 @@ packages:
       type-fest: 0.7.1
     dev: true
 
+  /std-env@3.7.0:
+    resolution: {integrity: sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==}
+    dev: true
+
   /stream-combiner@0.0.4:
     resolution: {integrity: sha512-rT00SPnTVyRsaSz5zgSPma/aHSOic5U1prhYdRy5HS2kTZviFpmDgzilbtsJsxiroqACmayynDN/9VzIbX5DOw==}
     dependencies:
@@ -6500,14 +5204,6 @@ packages:
     engines: {node: '>=0.6.19'}
     dev: true
 
-  /string-length@4.0.2:
-    resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==}
-    engines: {node: '>=10'}
-    dependencies:
-      char-regex: 1.0.2
-      strip-ansi: 6.0.1
-    dev: true
-
   /string-width@4.2.3:
     resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
     engines: {node: '>=8'}
@@ -6566,21 +5262,11 @@ packages:
     engines: {node: '>=4'}
     dev: true
 
-  /strip-bom@4.0.0:
-    resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==}
-    engines: {node: '>=8'}
-    dev: true
-
   /strip-eof@1.0.0:
     resolution: {integrity: sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==}
     engines: {node: '>=0.10.0'}
     dev: true
 
-  /strip-final-newline@2.0.0:
-    resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==}
-    engines: {node: '>=6'}
-    dev: true
-
   /strip-final-newline@3.0.0:
     resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==}
     engines: {node: '>=12'}
@@ -6603,6 +5289,12 @@ packages:
     engines: {node: '>=8'}
     dev: true
 
+  /strip-literal@2.1.0:
+    resolution: {integrity: sha512-Op+UycaUt/8FbN/Z2TWPBLge3jWrP3xj10f3fnYxf052bKuS3EKs1ZQcVGjnEMdsNVAM+plXRdmjrZ/KgG3Skw==}
+    dependencies:
+      js-tokens: 9.0.0
+    dev: true
+
   /sucrase@3.34.0:
     resolution: {integrity: sha512-70/LQEZ07TEcxiU2dz51FKaE6hCTWC6vr7FOk3Gr0U60C3shtAN+H+BFr9XlYe5xqf3RA8nrc+VIwzCfnxuXJw==}
     engines: {node: '>=8'}
@@ -6747,6 +5439,20 @@ packages:
     resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==}
     dev: true
 
+  /tinybench@2.8.0:
+    resolution: {integrity: sha512-1/eK7zUnIklz4JUUlL+658n58XO2hHLQfSk1Zf2LKieUjxidN16eKFEoDEfjHc3ohofSSqK3X5yO6VGb6iW8Lw==}
+    dev: true
+
+  /tinypool@0.8.4:
+    resolution: {integrity: sha512-i11VH5gS6IFeLY3gMBQ00/MmLncVP7JLXOw1vlgkytLmJK7QnEr7NXf0LBdxfmNPAeyetukOk0bOYrJrFGjYJQ==}
+    engines: {node: '>=14.0.0'}
+    dev: true
+
+  /tinyspy@2.2.1:
+    resolution: {integrity: sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==}
+    engines: {node: '>=14.0.0'}
+    dev: true
+
   /tmp@0.2.1:
     resolution: {integrity: sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==}
     engines: {node: '>=8.17.0'}
@@ -6754,10 +5460,6 @@ packages:
       rimraf: 3.0.2
     dev: true
 
-  /tmpl@1.0.5:
-    resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==}
-    dev: true
-
   /to-fast-properties@2.0.0:
     resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==}
     engines: {node: '>=4'}
@@ -6769,6 +5471,11 @@ packages:
       is-number: 7.0.0
     dev: true
 
+  /totalist@3.0.1:
+    resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==}
+    engines: {node: '>=6'}
+    dev: true
+
   /tough-cookie@4.1.3:
     resolution: {integrity: sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==}
     engines: {node: '>=6'}
@@ -6814,11 +5521,6 @@ packages:
     engines: {node: '>=10'}
     dev: true
 
-  /type-fest@0.21.3:
-    resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==}
-    engines: {node: '>=10'}
-    dev: true
-
   /type-fest@0.6.0:
     resolution: {integrity: sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==}
     engines: {node: '>=8'}
@@ -6867,6 +5569,10 @@ packages:
     engines: {node: '>=14.17'}
     hasBin: true
 
+  /ufo@1.5.3:
+    resolution: {integrity: sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==}
+    dev: true
+
   /uglify-js@3.17.4:
     resolution: {integrity: sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==}
     engines: {node: '>=0.8.0'}
@@ -6903,17 +5609,6 @@ packages:
     engines: {node: '>=8'}
     dev: true
 
-  /update-browserslist-db@1.0.11(browserslist@4.21.10):
-    resolution: {integrity: sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==}
-    hasBin: true
-    peerDependencies:
-      browserslist: '>= 4.21.0'
-    dependencies:
-      browserslist: 4.21.10
-      escalade: 3.1.1
-      picocolors: 1.0.0
-    dev: true
-
   /uri-js@4.4.1:
     resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
     dependencies:
@@ -6942,15 +5637,6 @@ packages:
     hasBin: true
     dev: true
 
-  /v8-to-istanbul@9.1.0:
-    resolution: {integrity: sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA==}
-    engines: {node: '>=10.12.0'}
-    dependencies:
-      '@jridgewell/trace-mapping': 0.3.19
-      '@types/istanbul-lib-coverage': 2.0.4
-      convert-source-map: 1.9.0
-    dev: true
-
   /validate-npm-package-license@3.0.4:
     resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==}
     dependencies:
@@ -6963,6 +5649,27 @@ packages:
     engines: {node: '>= 0.10'}
     dev: true
 
+  /vite-node@1.6.0:
+    resolution: {integrity: sha512-de6HJgzC+TFzOu0NTC4RAIsyf/DY/ibWDYQUcuEA84EMHhcefTUGkjFHKKEJhQN4A+6I0u++kr3l36ZF2d7XRw==}
+    engines: {node: ^18.0.0 || >=20.0.0}
+    hasBin: true
+    dependencies:
+      cac: 6.7.14
+      debug: 4.3.4
+      pathe: 1.1.2
+      picocolors: 1.0.0
+      vite: 5.2.9(@types/node@20.12.7)
+    transitivePeerDependencies:
+      - '@types/node'
+      - less
+      - lightningcss
+      - sass
+      - stylus
+      - sugarss
+      - supports-color
+      - terser
+    dev: true
+
   /vite@5.2.9(@types/node@20.12.7):
     resolution: {integrity: sha512-uOQWfuZBlc6Y3W/DTuQ1Sr+oIXWvqljLvS881SVmAj00d5RdgShLcuXWxseWPd4HXwiYBFW/vXHfKFeqj9uQnw==}
     engines: {node: ^18.0.0 || >=20.0.0}
@@ -7068,6 +5775,62 @@ packages:
       - universal-cookie
     dev: false
 
+  /vitest@1.6.0(@vitest/ui@1.6.0):
+    resolution: {integrity: sha512-H5r/dN06swuFnzNFhq/dnz37bPXnq8xB2xB5JOVk8K09rUtoeNN+LHWkoQ0A/i3hvbUKKcCei9KpbxqHMLhLLA==}
+    engines: {node: ^18.0.0 || >=20.0.0}
+    hasBin: true
+    peerDependencies:
+      '@edge-runtime/vm': '*'
+      '@types/node': ^18.0.0 || >=20.0.0
+      '@vitest/browser': 1.6.0
+      '@vitest/ui': 1.6.0
+      happy-dom: '*'
+      jsdom: '*'
+    peerDependenciesMeta:
+      '@edge-runtime/vm':
+        optional: true
+      '@types/node':
+        optional: true
+      '@vitest/browser':
+        optional: true
+      '@vitest/ui':
+        optional: true
+      happy-dom:
+        optional: true
+      jsdom:
+        optional: true
+    dependencies:
+      '@vitest/expect': 1.6.0
+      '@vitest/runner': 1.6.0
+      '@vitest/snapshot': 1.6.0
+      '@vitest/spy': 1.6.0
+      '@vitest/ui': 1.6.0(vitest@1.6.0)
+      '@vitest/utils': 1.6.0
+      acorn-walk: 8.3.3
+      chai: 4.4.1
+      debug: 4.3.4
+      execa: 8.0.1
+      local-pkg: 0.5.0
+      magic-string: 0.30.9
+      pathe: 1.1.2
+      picocolors: 1.0.0
+      std-env: 3.7.0
+      strip-literal: 2.1.0
+      tinybench: 2.8.0
+      tinypool: 0.8.4
+      vite: 5.2.9(@types/node@20.12.7)
+      vite-node: 1.6.0
+      why-is-node-running: 2.2.2
+    transitivePeerDependencies:
+      - less
+      - lightningcss
+      - sass
+      - stylus
+      - sugarss
+      - supports-color
+      - terser
+    dev: true
+
   /vscode-oniguruma@1.7.0:
     resolution: {integrity: sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==}
     dev: true
@@ -7143,19 +5906,6 @@ packages:
       xml-name-validator: 4.0.0
     dev: true
 
-  /w3c-xmlserializer@4.0.0:
-    resolution: {integrity: sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==}
-    engines: {node: '>=14'}
-    dependencies:
-      xml-name-validator: 4.0.0
-    dev: true
-
-  /walker@1.0.8:
-    resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==}
-    dependencies:
-      makeerror: 1.0.12
-    dev: true
-
   /wcwidth@1.0.1:
     resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==}
     dependencies:
@@ -7210,6 +5960,15 @@ packages:
       isexe: 2.0.0
     dev: true
 
+  /why-is-node-running@2.2.2:
+    resolution: {integrity: sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==}
+    engines: {node: '>=8'}
+    hasBin: true
+    dependencies:
+      siginfo: 2.0.0
+      stackback: 0.0.2
+    dev: true
+
   /widest-line@3.1.0:
     resolution: {integrity: sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==}
     engines: {node: '>=8'}
@@ -7256,14 +6015,6 @@ packages:
     resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
     dev: true
 
-  /write-file-atomic@4.0.2:
-    resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==}
-    engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
-    dependencies:
-      imurmurhash: 0.1.4
-      signal-exit: 3.0.7
-    dev: true
-
   /ws@8.13.0:
     resolution: {integrity: sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==}
     engines: {node: '>=10.0.0'}
@@ -7300,10 +6051,6 @@ packages:
     resolution: {integrity: sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==}
     dev: true
 
-  /yallist@3.1.1:
-    resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
-    dev: true
-
   /yallist@4.0.0:
     resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
     dev: true
@@ -7323,11 +6070,6 @@ packages:
     engines: {node: '>=10'}
     dev: true
 
-  /yargs-parser@21.1.1:
-    resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==}
-    engines: {node: '>=12'}
-    dev: true
-
   /yargs-unparser@2.0.0:
     resolution: {integrity: sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==}
     engines: {node: '>=10'}
@@ -7351,19 +6093,6 @@ packages:
       yargs-parser: 20.2.4
     dev: true
 
-  /yargs@17.7.2:
-    resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==}
-    engines: {node: '>=12'}
-    dependencies:
-      cliui: 8.0.1
-      escalade: 3.1.1
-      get-caller-file: 2.0.5
-      require-directory: 2.1.1
-      string-width: 4.2.3
-      y18n: 5.0.8
-      yargs-parser: 21.1.1
-    dev: true
-
   /yauzl@2.10.0:
     resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==}
     dependencies:
@@ -7376,6 +6105,11 @@ packages:
     engines: {node: '>=10'}
     dev: true
 
+  /yocto-queue@1.0.0:
+    resolution: {integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==}
+    engines: {node: '>=12.20'}
+    dev: true
+
   /yorkie@2.0.0:
     resolution: {integrity: sha512-jcKpkthap6x63MB4TxwCyuIGkV0oYP/YRyuQU5UO0Yz/E/ZAu+653/uov+phdmO54n6BcvFRyyt0RRrWdN2mpw==}
     engines: {node: '>=4'}