├── .github
└── workflows
│ ├── e2e-tests.yml
│ └── github-pages.yaml
├── .gitignore
├── .npmrc
├── .prettierrc.json
├── CHANGELOG
├── LICENSE
├── README.md
├── e2e
└── navigation-guard.spec.ts
├── example
├── .gitignore
├── next.config.mjs
├── package.json
├── src
│ ├── app
│ │ ├── favicon.ico
│ │ ├── fonts
│ │ │ ├── GeistMonoVF.woff
│ │ │ └── GeistVF.woff
│ │ ├── globals.css
│ │ ├── layout.tsx
│ │ ├── page.module.css
│ │ ├── page.tsx
│ │ ├── page1
│ │ │ └── page.tsx
│ │ ├── page2
│ │ │ └── page.tsx
│ │ └── page3
│ │ │ └── page.tsx
│ ├── components
│ │ ├── BackButton.tsx
│ │ ├── ForwardButton.tsx
│ │ ├── NavigationGuardToggle.tsx
│ │ ├── RefreshButton.tsx
│ │ └── SharedPage.tsx
│ └── pages
│ │ ├── _app.tsx
│ │ └── pages-router
│ │ ├── page1.tsx
│ │ ├── page2.tsx
│ │ └── page3.tsx
└── tsconfig.json
├── package.json
├── playwright.config.ts
├── pnpm-lock.yaml
├── pnpm-workspace.yaml
├── src
├── components
│ ├── InterceptAppRouterProvider.tsx
│ ├── InterceptPagesRouterProvider.tsx
│ ├── NavigationGuardProvider.tsx
│ └── NavigationGuardProviderContext.tsx
├── hooks
│ ├── useInterceptPageUnload.ts
│ ├── useInterceptPopState.ts
│ ├── useInterceptedAppRouter.ts
│ ├── useInterceptedPagesRouter.ts
│ ├── useIsomorphicLayoutEffect.ts
│ └── useNavigationGuard.ts
├── index.ts
├── types.ts
└── utils
│ ├── debug.ts
│ └── historyAugmentation.tsx
└── tsconfig.json
/.github/workflows/e2e-tests.yml:
--------------------------------------------------------------------------------
1 | name: E2E Tests
2 |
3 | on:
4 | push:
5 | branches: [main]
6 | pull_request:
7 | branches: [main]
8 |
9 | jobs:
10 | test:
11 | timeout-minutes: 60
12 | runs-on: ubuntu-latest
13 | strategy:
14 | matrix:
15 | next-version: ["14.0", "14.1", "14.2", "15.0", "15.1", "15.2", "15.3"]
16 | node-version: [20]
17 | steps:
18 | - uses: actions/checkout@v4
19 |
20 | - run: corepack enable
21 |
22 | - name: Use Node.js ${{ matrix.node-version }}
23 | uses: actions/setup-node@v4
24 | with:
25 | node-version: ${{ matrix.node-version }}
26 | cache: "pnpm"
27 |
28 | - name: Install dependencies
29 | run: pnpm install
30 |
31 | - name: Build library
32 | run: pnpm build
33 |
34 | - name: Update Next.js version in example
35 | run: pnpm add next@~${{ matrix.next-version }} --save-exact
36 | working-directory: example
37 |
38 | - name: Build example app
39 | run: pnpm build
40 | working-directory: example
41 |
42 | - name: Run example app
43 | run: pnpm start &
44 | working-directory: example
45 |
46 | - name: Install Playwright Browsers
47 | run: pnpm exec playwright install --with-deps
48 |
49 | - name: Wait for server ready
50 | run: curl --fail --retry 10 --retry-delay 1 --retry-all-errors --silent --output /dev/null --head http://localhost:3000
51 |
52 | - name: Run Playwright tests
53 | run: PORT=3000 pnpm playwright test
54 |
55 | - uses: actions/upload-artifact@v4
56 | if: ${{ !cancelled() }}
57 | with:
58 | name: playwright-report-next-${{ matrix.next-version }}
59 | path: playwright-report/
60 | retention-days: 30
61 |
--------------------------------------------------------------------------------
/.github/workflows/github-pages.yaml:
--------------------------------------------------------------------------------
1 | name: Deploy Next.js example to GitHub Pages
2 |
3 | on:
4 | # Runs on pushes targeting the default branch
5 | push:
6 | branches: ["main"]
7 |
8 | # Allows you to run this workflow manually from the Actions tab
9 | workflow_dispatch:
10 |
11 | # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
12 | permissions:
13 | contents: read
14 | pages: write
15 | id-token: write
16 |
17 | # Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
18 | # However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
19 | concurrency:
20 | group: "pages"
21 | cancel-in-progress: false
22 |
23 | jobs:
24 | # Build job
25 | build:
26 | runs-on: ubuntu-latest
27 | steps:
28 | - name: Checkout
29 | uses: actions/checkout@v4
30 | - uses: pnpm/action-setup@v4.0.0
31 | name: Install pnpm
32 | with:
33 | run_install: false
34 | - name: Setup Node
35 | uses: actions/setup-node@v4
36 | with:
37 | node-version: "20"
38 | cache: pnpm
39 | - name: Setup Pages
40 | uses: actions/configure-pages@v5
41 | with:
42 | # Automatically inject basePath in your Next.js configuration file and disable
43 | # server side image optimization (https://nextjs.org/docs/api-reference/next/image#unoptimized).
44 | #
45 | # You may remove this line if you want to manage the configuration yourself.
46 | static_site_generator: next
47 | generator_config_file: example/next.config.mjs
48 | - name: Restore cache
49 | uses: actions/cache@v4
50 | with:
51 | path: |
52 | example/.next/cache
53 | # Generate a new cache whenever packages or source files change.
54 | key: ${{ runner.os }}-nextjs-${{ hashFiles('**/pnpm-lock.yaml') }}-${{ hashFiles('**.[jt]s', '**.[jt]sx') }}
55 | # If source files changed but packages didn't, rebuild from a prior cache.
56 | restore-keys: |
57 | ${{ runner.os }}-nextjs-${{ hashFiles('**/pnpm-lock.yaml') }}-
58 | - name: Install dependencies
59 | run: pnpm install --frozen-lockfile
60 | - name: Build the library
61 | run: pnpm run build
62 | - name: Build with Next.js
63 | working-directory: example
64 | run: pnpm run build
65 | - name: Upload artifact
66 | uses: actions/upload-pages-artifact@v3
67 | with:
68 | path: ./example/out
69 |
70 | # Deployment job
71 | deploy:
72 | environment:
73 | name: github-pages
74 | url: ${{ steps.deployment.outputs.page_url }}
75 | runs-on: ubuntu-latest
76 | needs: build
77 | steps:
78 | - name: Deploy to GitHub Pages
79 | id: deployment
80 | uses: actions/deploy-pages@v4
81 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | dist
2 | node_modules
3 |
4 | # Playwright
5 | /test-results/
6 | /playwright-report/
7 | /blob-report/
8 | /playwright/.cache/
9 |
10 | /.claude/settings.local.json
11 |
--------------------------------------------------------------------------------
/.npmrc:
--------------------------------------------------------------------------------
1 | ignore-workspace-root-check=true
2 |
--------------------------------------------------------------------------------
/.prettierrc.json:
--------------------------------------------------------------------------------
1 | {}
2 |
--------------------------------------------------------------------------------
/CHANGELOG:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | All notable changes to this project will be documented in this file.
4 |
5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7 |
8 | ## [Unreleased]
9 |
10 | ## [0.1.2] - 2024-12-11
11 |
12 | ### Fixed
13 |
14 | - deps: Support Next.js 14 / 15 as peer dependencies ([#13](https://github.com/LayerXcom/next-navigation-guard/pulls/13)). @zachelrath
15 |
16 | ## [0.1.1] - 2024-10-07
17 |
18 | ### Fixed
19 |
20 | - Fix back/forward button does not change the contents of the page ([#2](https://github.com/LayerXcom/next-navigation-guard/issues/2)).
21 |
22 | ## [0.1.0] - 2024-09-18
23 |
24 | ### Added
25 |
26 | - The initial release of next-navigation-guard.
27 |
28 | [unreleased]: https://github.com/LayerXcom/next-navigation-guard/compare/v0.1.2...HEAD
29 | [0.1.2]: https://github.com/LayerXcom/next-navigation-guard/releases/tag/v0.1.2
30 | [0.1.1]: https://github.com/LayerXcom/next-navigation-guard/releases/tag/v0.1.1
31 | [0.1.0]: https://github.com/LayerXcom/next-navigation-guard/releases/tag/v0.1.0
32 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024 LayerX Inc.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # next-navigation-guard
2 |
3 | You use Next.js, and you want to show "You have unsaved changes that will be lost." dialog when user leaves page?
4 | This library is just for you!
5 |
6 | ## Demo
7 |
8 | [https://layerxcom.github.io/next-navigation-guard/](https://layerxcom.github.io/next-navigation-guard/)
9 |
10 | ## How does it work?
11 |
12 | - [English Slide](https://speakerdeck.com/ypresto/cancel-next-js-page-navigation-full-throttle)
13 | - [Japanese Slide](https://speakerdeck.com/ypresto/hack-to-prevent-page-navigation-in-next-js)
14 |
15 | ## Installation
16 |
17 | ```bash
18 | npm install next-navigation-guard
19 | # or
20 | yarn install next-navigation-guard
21 | # or
22 | pnpm install next-navigation-guard
23 | ```
24 |
25 | - App Router: app/layout.tsx
26 |
27 | ```tsx
28 |
29 |
30 | {children}
31 |
32 |
33 | ```
34 |
35 | - Page Router: page/_app.tsx
36 |
37 | ```tsx
38 | export default function MyApp({ Component, pageProps }: AppProps) {
39 | return (
40 |
41 |
42 |
43 | );
44 | }
45 | ```
46 |
47 | ## Usage
48 |
49 | - window.confirm()
50 |
51 | ```tsx
52 | useNavigationGuard({ enabled: form.changed, confirm: () => window.confirm("You have unsaved changes that will be lost.") })
53 | ```
54 |
55 | - Custom dialog component
56 |
57 | ```tsx
58 | const navGuard = useNavigationGuard({ enabled: form.changed })
59 |
60 | return (
61 | <>
62 |
63 |
64 |
72 | >
73 | )
74 | ```
75 |
76 | See working example in example/ directory and its `NavigationGuardToggle` component.
77 |
--------------------------------------------------------------------------------
/e2e/navigation-guard.spec.ts:
--------------------------------------------------------------------------------
1 | import { test, expect, Page } from "@playwright/test";
2 |
3 | // Helper function to wait for and handle beforeunload dialog
4 | async function waitForBeforeUnloadDialog(
5 | page: Page,
6 | action: "accept" | "dismiss" = "dismiss"
7 | ) {
8 | return new Promise((resolve) => {
9 | page.once("dialog", (dialog) => {
10 | expect(dialog.type()).toBe("beforeunload");
11 |
12 | if (action === "accept") {
13 | dialog.accept();
14 | } else {
15 | dialog.dismiss();
16 | }
17 | resolve();
18 | });
19 | });
20 | }
21 |
22 | // Define test parameters for both routers
23 | const routers = [
24 | {
25 | name: "App Router",
26 | routerType: "appRouter",
27 | startUrl: "/page1",
28 | linkIndex: 0, // First set of links
29 | basePath: "",
30 | },
31 | {
32 | name: "Pages Router",
33 | routerType: "pagesRouter",
34 | startUrl: "/pages-router/page1",
35 | linkIndex: 1, // Second set of links
36 | basePath: "/pages-router",
37 | },
38 | ];
39 |
40 | // Parameterized tests that run for both routers
41 | routers.forEach(({ name, routerType, startUrl, linkIndex, basePath }) => {
42 | test.describe(`Navigation Guard - ${name}`, () => {
43 | test("should navigate freely when guard is disabled", async ({ page }) => {
44 | // Navigate to page1
45 | await page.goto(startUrl);
46 | await expect(
47 | page.locator(`text=Current Page: ${routerType} 1`)
48 | ).toBeVisible();
49 |
50 | // Navigate to page 2
51 | await page.getByRole("link", { name: "Page2" }).nth(linkIndex).click();
52 | await expect(
53 | page.locator(`text=Current Page: ${routerType} 2`)
54 | ).toBeVisible();
55 | await expect(page).toHaveURL(`${basePath}/page2`);
56 |
57 | // Navigate back to page 1 then to page 3
58 | await page.getByRole("link", { name: "Page1" }).nth(linkIndex).click();
59 | await expect(
60 | page.locator(`text=Current Page: ${routerType} 1`)
61 | ).toBeVisible();
62 | await expect(page).toHaveURL(`${basePath}/page1`);
63 |
64 | await page.getByRole("link", { name: "Page3" }).nth(linkIndex).click();
65 | await expect(
66 | page.locator(`text=Current Page: ${routerType} 3`)
67 | ).toBeVisible();
68 | await expect(page).toHaveURL(`${basePath}/page3`);
69 | });
70 |
71 | test("should show sync confirmation dialog when guard is enabled", async ({
72 | page,
73 | }) => {
74 | await page.goto(startUrl);
75 | await page.waitForSelector("text=Current Page:");
76 |
77 | // Enable navigation guard
78 | await page
79 | .getByRole("checkbox", { name: "Enable Navigation Guard" })
80 | .check();
81 |
82 | // Set up dialog handler
83 | page.on("dialog", (dialog) => {
84 | expect(dialog.message()).toBe(
85 | "You have unsaved changes that will be lost."
86 | );
87 | dialog.accept();
88 | });
89 |
90 | // Try to navigate
91 | await page.getByRole("link", { name: "Page2" }).nth(linkIndex).click();
92 | await expect(
93 | page.locator(`text=Current Page: ${routerType} 2`)
94 | ).toBeVisible();
95 | await expect(page).toHaveURL(`${basePath}/page2`);
96 | });
97 |
98 | test("should prevent navigation when sync confirmation is cancelled", async ({
99 | page,
100 | }) => {
101 | await page.goto(startUrl);
102 | await page.waitForSelector("text=Current Page:");
103 |
104 | // Set up dialog handler to cancel BEFORE enabling guard
105 | page.once("dialog", (dialog) => {
106 | expect(dialog.message()).toBe(
107 | "You have unsaved changes that will be lost."
108 | );
109 | dialog.dismiss();
110 | });
111 |
112 | // Enable navigation guard
113 | await page
114 | .getByRole("checkbox", { name: "Enable Navigation Guard" })
115 | .check();
116 |
117 | // Try to navigate
118 | await page.getByRole("link", { name: "Page2" }).nth(linkIndex).click();
119 |
120 | // Should still be on page 1
121 | await page.waitForTimeout(1000); // Give it time to not navigate
122 | await expect(
123 | page.locator(`text=Current Page: ${routerType} 1`)
124 | ).toBeVisible();
125 | await expect(page).toHaveURL(`${basePath}/page1`);
126 | });
127 |
128 | test("should show async confirmation UI when async mode is selected", async ({
129 | page,
130 | }) => {
131 | await page.goto(startUrl);
132 | await page.waitForSelector("text=Current Page:");
133 |
134 | // Enable navigation guard and select async mode
135 | await page
136 | .getByRole("checkbox", { name: "Enable Navigation Guard" })
137 | .check();
138 | await page.getByRole("checkbox", { name: "Use Async Confirm" }).check();
139 |
140 | // Try to navigate
141 | await page.getByRole("link", { name: "Page2" }).nth(linkIndex).click();
142 |
143 | // Check that confirmation UI appears
144 | await expect(
145 | page.locator("text=You have unsaved changes that will be lost.")
146 | ).toBeVisible();
147 | await expect(page.getByRole("button", { name: "OK" })).toBeVisible();
148 | await expect(page.getByRole("button", { name: "Cancel" })).toBeVisible();
149 | });
150 |
151 | test("should navigate when async confirmation is accepted", async ({
152 | page,
153 | }) => {
154 | await page.goto(startUrl);
155 | await page.waitForSelector("text=Current Page:");
156 |
157 | // Enable navigation guard and select async mode
158 | await page
159 | .getByRole("checkbox", { name: "Enable Navigation Guard" })
160 | .check();
161 | await page.getByRole("checkbox", { name: "Use Async Confirm" }).check();
162 |
163 | // Try to navigate
164 | await page.getByRole("link", { name: "Page2" }).nth(linkIndex).click();
165 |
166 | // Accept the confirmation
167 | await page.getByRole("button", { name: "OK" }).click();
168 |
169 | // Should navigate to page 2
170 | await expect(
171 | page.locator(`text=Current Page: ${routerType} 2`)
172 | ).toBeVisible();
173 | await expect(page).toHaveURL(`${basePath}/page2`);
174 | });
175 |
176 | test("should prevent navigation when async confirmation is cancelled", async ({
177 | page,
178 | }) => {
179 | await page.goto(startUrl);
180 | await page.waitForSelector("text=Current Page:");
181 |
182 | // Enable navigation guard and select async mode
183 | await page
184 | .getByRole("checkbox", { name: "Enable Navigation Guard" })
185 | .check();
186 | await page.getByRole("checkbox", { name: "Use Async Confirm" }).check();
187 |
188 | // Try to navigate
189 | await page.getByRole("link", { name: "Page2" }).nth(linkIndex).click();
190 |
191 | // Cancel the confirmation
192 | await page.getByRole("button", { name: "Cancel" }).click();
193 |
194 | // Should still be on page 1
195 | await page.waitForTimeout(1000);
196 | await expect(
197 | page.locator(`text=Current Page: ${routerType} 1`)
198 | ).toBeVisible();
199 | await expect(page).toHaveURL(`${basePath}/page1`);
200 | });
201 |
202 | test("should guard browser back button navigation", async ({ page }) => {
203 | // Navigate to page2 first
204 | await page.goto(startUrl);
205 | await page.getByRole("link", { name: "Page2" }).nth(linkIndex).click();
206 | await expect(
207 | page.locator(`text=Current Page: ${routerType} 2`)
208 | ).toBeVisible();
209 |
210 | // Enable navigation guard
211 | await page
212 | .getByRole("checkbox", { name: "Enable Navigation Guard" })
213 | .check();
214 |
215 | // Set up dialog handler to cancel
216 | page.once("dialog", (dialog) => {
217 | expect(dialog.message()).toBe(
218 | "You have unsaved changes that will be lost."
219 | );
220 | dialog.dismiss();
221 | });
222 |
223 | // Try to go back using browser back button
224 | await page.goBack();
225 |
226 | // Should still be on page 2
227 | await page.waitForTimeout(1000);
228 | await expect(
229 | page.locator(`text=Current Page: ${routerType} 2`)
230 | ).toBeVisible();
231 | await expect(page).toHaveURL(`${basePath}/page2`);
232 | });
233 |
234 | test("should guard browser forward button navigation", async ({ page }) => {
235 | // Navigate to page2 then back to page1
236 | await page.goto(startUrl);
237 | await page.getByRole("link", { name: "Page2" }).nth(linkIndex).click();
238 | await expect(
239 | page.locator(`text=Current Page: ${routerType} 2`)
240 | ).toBeVisible();
241 |
242 | await page.goBack();
243 | await expect(
244 | page.locator(`text=Current Page: ${routerType} 1`)
245 | ).toBeVisible();
246 | await expect(page).toHaveURL(`${basePath}/page1`);
247 |
248 | // Enable navigation guard
249 | await page
250 | .getByRole("checkbox", { name: "Enable Navigation Guard" })
251 | .check();
252 |
253 | // Set up dialog handler to cancel
254 | page.once("dialog", (dialog) => {
255 | expect(dialog.message()).toBe(
256 | "You have unsaved changes that will be lost."
257 | );
258 | dialog.dismiss();
259 | });
260 |
261 | // Try to go forward using browser forward button
262 | await page.goForward();
263 |
264 | // Should still be on page 1
265 | await page.waitForTimeout(1000);
266 | await expect(
267 | page.locator(`text=Current Page: ${routerType} 1`)
268 | ).toBeVisible();
269 | await expect(page).toHaveURL(`${basePath}/page1`);
270 | });
271 |
272 | test("should guard router.back() navigation", async ({ page }) => {
273 | // Navigate to page2 first
274 | await page.goto(startUrl);
275 | await page.getByRole("link", { name: "Page2" }).nth(linkIndex).click();
276 | await expect(
277 | page.locator(`text=Current Page: ${routerType} 2`)
278 | ).toBeVisible();
279 |
280 | // Enable navigation guard
281 | await page
282 | .getByRole("checkbox", { name: "Enable Navigation Guard" })
283 | .check();
284 |
285 | // Set up dialog handler to cancel
286 | page.once("dialog", (dialog) => {
287 | expect(dialog.message()).toBe(
288 | "You have unsaved changes that will be lost."
289 | );
290 | dialog.dismiss();
291 | });
292 |
293 | // Try to go back using router.back() button
294 | await page.getByRole("button", { name: "router.back()" }).click();
295 |
296 | // Should still be on page 2
297 | await page.waitForTimeout(1000);
298 | await expect(
299 | page.locator(`text=Current Page: ${routerType} 2`)
300 | ).toBeVisible();
301 | await expect(page).toHaveURL(`${basePath}/page2`);
302 | });
303 |
304 | test("should guard router.forward() navigation", async ({ page }) => {
305 | // Navigate to page2 then back to page1
306 | await page.goto(startUrl);
307 | await page.getByRole("link", { name: "Page2" }).nth(linkIndex).click();
308 | await expect(
309 | page.locator(`text=Current Page: ${routerType} 2`)
310 | ).toBeVisible();
311 |
312 | await page.getByRole("button", { name: "router.back()" }).click();
313 | await expect(
314 | page.locator(`text=Current Page: ${routerType} 1`)
315 | ).toBeVisible();
316 | await expect(page).toHaveURL(`${basePath}/page1`);
317 |
318 | // Enable navigation guard
319 | await page
320 | .getByRole("checkbox", { name: "Enable Navigation Guard" })
321 | .check();
322 |
323 | // Set up dialog handler to cancel
324 | page.once("dialog", (dialog) => {
325 | expect(dialog.message()).toBe(
326 | "You have unsaved changes that will be lost."
327 | );
328 | dialog.dismiss();
329 | });
330 |
331 | // Try to go forward using router.forward() button
332 | await page.getByRole("button", { name: "router.forward()" }).click();
333 |
334 | // Should still be on page 1
335 | await page.waitForTimeout(1000);
336 | await expect(
337 | page.locator(`text=Current Page: ${routerType} 1`)
338 | ).toBeVisible();
339 | await expect(page).toHaveURL(`${basePath}/page1`);
340 | });
341 |
342 | test("should guard page refresh", async ({ page }) => {
343 | await page.goto(startUrl);
344 |
345 | // Enable navigation guard
346 | await page
347 | .getByRole("checkbox", { name: "Enable Navigation Guard" })
348 | .check();
349 |
350 | // Set up dialog handler to cancel
351 | page.once("dialog", (dialog) => {
352 | expect(dialog.message()).toBe(
353 | "You have unsaved changes that will be lost."
354 | );
355 | dialog.dismiss();
356 | });
357 |
358 | // Try to refresh using router.refresh() button
359 | await page.getByRole("button", { name: "router.refresh()" }).click();
360 |
361 | // Should still be on the same page with guard enabled
362 | await page.waitForTimeout(1000);
363 | await expect(
364 | page.locator(`text=Current Page: ${routerType} 1`)
365 | ).toBeVisible();
366 | await expect(page).toHaveURL(startUrl);
367 | await expect(
368 | page.getByRole("checkbox", { name: "Enable Navigation Guard" })
369 | ).toBeChecked();
370 | });
371 |
372 | test("should guard tab close/navigation away", async ({ page }) => {
373 | await page.goto(startUrl);
374 |
375 | // Enable navigation guard
376 | await page
377 | .getByRole("checkbox", { name: "Enable Navigation Guard" })
378 | .check();
379 |
380 | // Test navigation to external URL
381 | const dialogPromise = waitForBeforeUnloadDialog(page, "dismiss");
382 |
383 | // Start navigation but don't await it
384 | const navigationPromise = page
385 | .goto("https://example.com", { waitUntil: "commit" })
386 | .catch(() => {
387 | // Navigation will be cancelled, so we catch the error
388 | });
389 |
390 | // Wait for dialog to be handled
391 | await dialogPromise;
392 |
393 | // Wait a bit for navigation to be cancelled
394 | await page.waitForTimeout(500);
395 |
396 | // Should still be on the original page
397 | await expect(
398 | page.locator(`text=Current Page: ${routerType} 1`)
399 | ).toBeVisible();
400 | await expect(page).toHaveURL(startUrl);
401 |
402 | // Test closing tab/window
403 | // Note: We can't actually test page.close() as it will close the page
404 | // Instead, we'll test that beforeunload dialog appears when trying to close
405 | // This is typically tested manually or with browser-specific APIs
406 |
407 | // Test navigation via window.location
408 | const dialogPromise2 = waitForBeforeUnloadDialog(page, "dismiss");
409 | await page.evaluate(() => {
410 | window.location.href = "https://example.com";
411 | });
412 | await dialogPromise2;
413 |
414 | // Should still be on the original page
415 | await page.waitForTimeout(500);
416 | await expect(
417 | page.locator(`text=Current Page: ${routerType} 1`)
418 | ).toBeVisible();
419 | await expect(page).toHaveURL(startUrl);
420 | });
421 |
422 | test("should allow navigation when guard accepts all navigation types", async ({
423 | page,
424 | }) => {
425 | // Test browser back
426 | await page.goto(startUrl);
427 | await page.getByRole("link", { name: "Page2" }).nth(linkIndex).click();
428 | await expect(
429 | page.locator(`text=Current Page: ${routerType} 2`)
430 | ).toBeVisible();
431 |
432 | await page
433 | .getByRole("checkbox", { name: "Enable Navigation Guard" })
434 | .check();
435 |
436 | page.once("dialog", (dialog) => {
437 | dialog.accept();
438 | });
439 |
440 | await page.goBack();
441 | await expect(
442 | page.locator(`text=Current Page: ${routerType} 1`)
443 | ).toBeVisible();
444 | await expect(page).toHaveURL(`${basePath}/page1`);
445 |
446 | // Test router.forward()
447 | page.once("dialog", (dialog) => {
448 | dialog.accept();
449 | });
450 |
451 | await page.getByRole("button", { name: "router.forward()" }).click();
452 | await expect(
453 | page.locator(`text=Current Page: ${routerType} 2`)
454 | ).toBeVisible();
455 | await expect(page).toHaveURL(`${basePath}/page2`);
456 | });
457 | });
458 | });
459 |
--------------------------------------------------------------------------------
/example/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 | .yarn/install-state.gz
8 |
9 | # testing
10 | /coverage
11 |
12 | # next.js
13 | /.next/
14 | /out/
15 |
16 | # production
17 | /build
18 |
19 | # misc
20 | .DS_Store
21 | *.pem
22 |
23 | # debug
24 | npm-debug.log*
25 | yarn-debug.log*
26 | yarn-error.log*
27 |
28 | # local env files
29 | .env*.local
30 |
31 | # vercel
32 | .vercel
33 |
34 | # typescript
35 | *.tsbuildinfo
36 | next-env.d.ts
37 |
--------------------------------------------------------------------------------
/example/next.config.mjs:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {};
3 |
4 | export default nextConfig;
5 |
--------------------------------------------------------------------------------
/example/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "next-navigation-guard-example",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "next dev",
7 | "build": "next build",
8 | "start": "next start",
9 | "lint": "next lint"
10 | },
11 | "dependencies": {
12 | "next": "14.2.11",
13 | "next-navigation-guard": "link:..",
14 | "react": "^18",
15 | "react-dom": "^18"
16 | },
17 | "devDependencies": {
18 | "@types/node": "^20",
19 | "@types/react": "^18",
20 | "@types/react-dom": "^18",
21 | "typescript": "^5"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/example/src/app/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LayerXcom/next-navigation-guard/d53d47395fd76a7ff9d8577480835c37af17a24a/example/src/app/favicon.ico
--------------------------------------------------------------------------------
/example/src/app/fonts/GeistMonoVF.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LayerXcom/next-navigation-guard/d53d47395fd76a7ff9d8577480835c37af17a24a/example/src/app/fonts/GeistMonoVF.woff
--------------------------------------------------------------------------------
/example/src/app/fonts/GeistVF.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LayerXcom/next-navigation-guard/d53d47395fd76a7ff9d8577480835c37af17a24a/example/src/app/fonts/GeistVF.woff
--------------------------------------------------------------------------------
/example/src/app/globals.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --background: #ffffff;
3 | --foreground: #171717;
4 | }
5 |
6 | @media (prefers-color-scheme: dark) {
7 | :root {
8 | --background: #0a0a0a;
9 | --foreground: #ededed;
10 | }
11 | }
12 |
13 | html,
14 | body {
15 | max-width: 100vw;
16 | overflow-x: hidden;
17 | }
18 |
19 | body {
20 | color: var(--foreground);
21 | background: var(--background);
22 | font-family: Arial, Helvetica, sans-serif;
23 | -webkit-font-smoothing: antialiased;
24 | -moz-osx-font-smoothing: grayscale;
25 | }
26 |
27 | * {
28 | box-sizing: border-box;
29 | padding: 0;
30 | margin: 0;
31 | }
32 |
33 | a {
34 | color: inherit;
35 | text-decoration: none;
36 | }
37 |
38 | @media (prefers-color-scheme: dark) {
39 | html {
40 | color-scheme: dark;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/example/src/app/layout.tsx:
--------------------------------------------------------------------------------
1 | import type { Metadata } from "next";
2 | import localFont from "next/font/local";
3 | import "./globals.css";
4 | import { NavigationGuardProvider } from "next-navigation-guard";
5 |
6 | const geistSans = localFont({
7 | src: "./fonts/GeistVF.woff",
8 | variable: "--font-geist-sans",
9 | weight: "100 900",
10 | });
11 | const geistMono = localFont({
12 | src: "./fonts/GeistMonoVF.woff",
13 | variable: "--font-geist-mono",
14 | weight: "100 900",
15 | });
16 |
17 | export const metadata: Metadata = {
18 | title: "next-navigation-guard Example",
19 | description:
20 | "Demo for next-navigation-guard library which provides a navigation guard for Next.js.",
21 | };
22 |
23 | export default function RootLayout({
24 | children,
25 | }: Readonly<{
26 | children: React.ReactNode;
27 | }>) {
28 | return (
29 |
30 |
31 | {children}
32 |
33 |
34 | );
35 | }
36 |
--------------------------------------------------------------------------------
/example/src/app/page.module.css:
--------------------------------------------------------------------------------
1 | .page {
2 | --gray-rgb: 0, 0, 0;
3 | --gray-alpha-200: rgba(var(--gray-rgb), 0.08);
4 | --gray-alpha-100: rgba(var(--gray-rgb), 0.05);
5 |
6 | --button-primary-hover: #383838;
7 | --button-secondary-hover: #f2f2f2;
8 |
9 | display: grid;
10 | grid-template-rows: 20px 1fr 20px;
11 | align-items: center;
12 | justify-items: center;
13 | min-height: 100svh;
14 | padding: 80px;
15 | gap: 64px;
16 | font-family: var(--font-geist-sans);
17 | }
18 |
19 | @media (prefers-color-scheme: dark) {
20 | .page {
21 | --gray-rgb: 255, 255, 255;
22 | --gray-alpha-200: rgba(var(--gray-rgb), 0.145);
23 | --gray-alpha-100: rgba(var(--gray-rgb), 0.06);
24 |
25 | --button-primary-hover: #ccc;
26 | --button-secondary-hover: #1a1a1a;
27 | }
28 | }
29 |
30 | .main {
31 | display: flex;
32 | flex-direction: column;
33 | gap: 32px;
34 | grid-row-start: 2;
35 | }
36 |
37 | .main ol {
38 | font-family: var(--font-geist-mono);
39 | padding-left: 0;
40 | margin: 0;
41 | font-size: 14px;
42 | line-height: 24px;
43 | letter-spacing: -0.01em;
44 | list-style-position: inside;
45 | }
46 |
47 | .main li:not(:last-of-type) {
48 | margin-bottom: 8px;
49 | }
50 |
51 | .main code {
52 | font-family: inherit;
53 | background: var(--gray-alpha-100);
54 | padding: 2px 4px;
55 | border-radius: 4px;
56 | font-weight: 600;
57 | }
58 |
59 | .ctas {
60 | display: flex;
61 | gap: 16px;
62 | }
63 |
64 | .ctas a {
65 | appearance: none;
66 | border-radius: 128px;
67 | height: 48px;
68 | padding: 0 20px;
69 | border: none;
70 | border: 1px solid transparent;
71 | transition: background 0.2s, color 0.2s, border-color 0.2s;
72 | cursor: pointer;
73 | display: flex;
74 | align-items: center;
75 | justify-content: center;
76 | font-size: 16px;
77 | line-height: 20px;
78 | font-weight: 500;
79 | }
80 |
81 | a.primary {
82 | background: var(--foreground);
83 | color: var(--background);
84 | gap: 8px;
85 | }
86 |
87 | a.secondary {
88 | border-color: var(--gray-alpha-200);
89 | min-width: 180px;
90 | }
91 |
92 | .footer {
93 | grid-row-start: 3;
94 | display: flex;
95 | gap: 24px;
96 | }
97 |
98 | .footer a {
99 | display: flex;
100 | align-items: center;
101 | gap: 8px;
102 | }
103 |
104 | .footer img {
105 | flex-shrink: 0;
106 | }
107 |
108 | /* Enable hover only on non-touch devices */
109 | @media (hover: hover) and (pointer: fine) {
110 | a.primary:hover {
111 | background: var(--button-primary-hover);
112 | border-color: transparent;
113 | }
114 |
115 | a.secondary:hover {
116 | background: var(--button-secondary-hover);
117 | border-color: transparent;
118 | }
119 |
120 | .footer a:hover {
121 | text-decoration: underline;
122 | text-underline-offset: 4px;
123 | }
124 | }
125 |
126 | @media (max-width: 600px) {
127 | .page {
128 | padding: 32px;
129 | padding-bottom: 80px;
130 | }
131 |
132 | .main {
133 | align-items: center;
134 | }
135 |
136 | .main ol {
137 | text-align: center;
138 | }
139 |
140 | .ctas {
141 | flex-direction: column;
142 | }
143 |
144 | .ctas a {
145 | font-size: 14px;
146 | height: 40px;
147 | padding: 0 16px;
148 | }
149 |
150 | a.secondary {
151 | min-width: auto;
152 | }
153 |
154 | .footer {
155 | flex-wrap: wrap;
156 | align-items: center;
157 | justify-content: center;
158 | }
159 | }
160 |
161 | @media (prefers-color-scheme: dark) {
162 | .logo {
163 | filter: invert();
164 | }
165 | }
166 |
--------------------------------------------------------------------------------
/example/src/app/page.tsx:
--------------------------------------------------------------------------------
1 | import Link from "next/link";
2 | import styles from "./page.module.css";
3 |
4 | export default function Home() {
5 | return (
6 |
7 |
8 | next-navigation-guard Example
9 |
10 |
11 |
12 | -
13 | App Router
14 |
15 | -
16 | Pages Router
17 |
18 |
19 |
20 |
21 |
22 | );
23 | }
24 |
--------------------------------------------------------------------------------
/example/src/app/page1/page.tsx:
--------------------------------------------------------------------------------
1 | import { SharedPage } from "@/components/SharedPage";
2 |
3 | export default function Page1() {
4 | return ;
5 | }
6 |
--------------------------------------------------------------------------------
/example/src/app/page2/page.tsx:
--------------------------------------------------------------------------------
1 | import { SharedPage } from "@/components/SharedPage";
2 |
3 | export default function Page2() {
4 | return ;
5 | }
6 |
--------------------------------------------------------------------------------
/example/src/app/page3/page.tsx:
--------------------------------------------------------------------------------
1 | import { SharedPage } from "@/components/SharedPage";
2 |
3 | export default function Page3() {
4 | return ;
5 | }
6 |
--------------------------------------------------------------------------------
/example/src/components/BackButton.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { useRouter } from "next/navigation";
4 |
5 | export function BackButton() {
6 | const router = useRouter();
7 | return (
8 |
14 | );
15 | }
16 |
--------------------------------------------------------------------------------
/example/src/components/ForwardButton.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { useRouter } from "next/navigation";
4 |
5 | export function ForwardButton() {
6 | const router = useRouter();
7 | return (
8 |
14 | );
15 | }
16 |
--------------------------------------------------------------------------------
/example/src/components/NavigationGuardToggle.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { useNavigationGuard } from "next-navigation-guard";
4 | import React, { useState } from "react";
5 |
6 | export function NavigationGuardToggle(props: { confirm: string }) {
7 | const [enabled, setEnabled] = useState(false);
8 | const [isAsync, setIsAsync] = useState(false);
9 |
10 | const navGuard = useNavigationGuard({
11 | enabled,
12 | confirm: isAsync ? undefined : () => window.confirm(props.confirm),
13 | });
14 |
15 | return (
16 |
17 |
18 |
26 |
27 |
28 |
29 |
37 |
38 |
39 | {navGuard.active && (
40 |
41 |
{props.confirm}
42 |
43 |
44 |
47 |
48 | )}
49 |
50 | );
51 | }
52 |
--------------------------------------------------------------------------------
/example/src/components/RefreshButton.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { useRouter } from "next/navigation";
4 |
5 | export function RefreshButton() {
6 | const router = useRouter();
7 | return (
8 |
14 | );
15 | }
16 |
--------------------------------------------------------------------------------
/example/src/components/SharedPage.tsx:
--------------------------------------------------------------------------------
1 | import Link from "next/link";
2 | import styles from "../app/page.module.css";
3 | import { RefreshButton } from "./RefreshButton";
4 | import { NavigationGuardToggle } from "./NavigationGuardToggle";
5 | import { BackButton } from "./BackButton";
6 | import { ForwardButton } from "./ForwardButton";
7 |
8 | export function SharedPage({
9 | current,
10 | mode,
11 | }: {
12 | current: number;
13 | mode: "appRouter" | "pagesRouter";
14 | }) {
15 | return (
16 |
17 |
18 | next-navigation-guard Example
19 |
20 | Current Page: {mode} {current}
21 |
22 |
23 |
24 |
App Router
25 |
26 | -
27 | Page1
28 |
29 | -
30 | Page2
31 |
32 | -
33 | Page3
34 |
35 |
36 |
37 |
38 |
Pages Router
39 |
40 | -
41 | Page1
42 |
43 | -
44 | Page2
45 |
46 | -
47 | Page3
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 | );
70 | }
71 |
--------------------------------------------------------------------------------
/example/src/pages/_app.tsx:
--------------------------------------------------------------------------------
1 | import type { AppProps } from "next/app";
2 | import { NavigationGuardProvider } from "next-navigation-guard";
3 |
4 | export default function MyApp({ Component, pageProps }: AppProps) {
5 | return (
6 |
7 |
8 |
9 | );
10 | }
11 |
--------------------------------------------------------------------------------
/example/src/pages/pages-router/page1.tsx:
--------------------------------------------------------------------------------
1 | import { SharedPage } from "@/components/SharedPage";
2 |
3 | export default function Page1() {
4 | return ;
5 | }
6 |
--------------------------------------------------------------------------------
/example/src/pages/pages-router/page2.tsx:
--------------------------------------------------------------------------------
1 | import { SharedPage } from "@/components/SharedPage";
2 |
3 | export default function Page2() {
4 | return ;
5 | }
6 |
--------------------------------------------------------------------------------
/example/src/pages/pages-router/page3.tsx:
--------------------------------------------------------------------------------
1 | import { SharedPage } from "@/components/SharedPage";
2 |
3 | export default function Page3() {
4 | return ;
5 | }
6 |
--------------------------------------------------------------------------------
/example/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "lib": [
4 | "dom",
5 | "dom.iterable",
6 | "esnext"
7 | ],
8 | "skipLibCheck": true,
9 | "strict": true,
10 | "noEmit": true,
11 | "esModuleInterop": true,
12 | "module": "esnext",
13 | "moduleResolution": "bundler",
14 | "resolveJsonModule": true,
15 | "isolatedModules": true,
16 | "jsx": "preserve",
17 | "incremental": true,
18 | "plugins": [
19 | {
20 | "name": "next"
21 | }
22 | ],
23 | "paths": {
24 | "@/*": [
25 | "./src/*"
26 | ]
27 | },
28 | "allowJs": true
29 | },
30 | "include": [
31 | "next-env.d.ts",
32 | "**/*.ts",
33 | "**/*.tsx",
34 | ".next/types/**/*.ts"
35 | ],
36 | "exclude": [
37 | "node_modules"
38 | ]
39 | }
40 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "next-navigation-guard",
3 | "version": "0.1.2",
4 | "description": "Navigation Guard for Next.js App Router and Pages Router.",
5 | "main": "./dist/index.js",
6 | "module": "./dist/index.js",
7 | "types": "./dist/index.d.ts",
8 | "exports": {
9 | "import": "./dist/index.js",
10 | "require": "./dist/index.js"
11 | },
12 | "files": [
13 | "dist"
14 | ],
15 | "sideEffects": false,
16 | "scripts": {
17 | "build": "tsc -p .",
18 | "watch": "tsc --watch -p .",
19 | "test": "echo \"Error: no test specified\" && exit 1",
20 | "check:packaging": "pnpm dlx @arethetypeswrong/cli --pack .",
21 | "e2e": "playwright test",
22 | "e2e:ui": "playwright test --ui",
23 | "e2e:install": "playwright install"
24 | },
25 | "keywords": [],
26 | "author": "ypresto ",
27 | "license": "MIT",
28 | "repository": {
29 | "type": "git",
30 | "url": "https://github.com/LayerXcom/next-navigation-guard.git"
31 | },
32 | "packageManager": "pnpm@9.9.0+sha512.60c18acd138bff695d339be6ad13f7e936eea6745660d4cc4a776d5247c540d0edee1a563695c183a66eb917ef88f2b4feb1fc25f32a7adcadc7aaf3438e99c1",
33 | "peerDependencies": {
34 | "next": "^14 || ^15",
35 | "react": "^18.0.0 || ^19.0.0 || ^19.0.0-rc"
36 | },
37 | "devDependencies": {
38 | "@playwright/test": "^1.52.0",
39 | "@types/node": "^20",
40 | "@types/react": "^18.3.5",
41 | "next": "^14.2.11",
42 | "playwright": "^1.52.0",
43 | "react": "^18.3.1",
44 | "tsup": "^8.2.4",
45 | "typescript": "^5.6.2"
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/playwright.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig, devices } from "@playwright/test";
2 |
3 | const PORT = process.env.PORT || 30000;
4 |
5 | export default defineConfig({
6 | testDir: "./e2e",
7 | fullyParallel: true,
8 | forbidOnly: !!process.env.CI,
9 | retries: process.env.CI ? 2 : 0,
10 | workers: process.env.CI ? 2 : undefined,
11 | reporter: "html",
12 | use: {
13 | baseURL: `http://localhost:${PORT}`,
14 | trace: "on-first-retry",
15 | },
16 |
17 | projects: [
18 | {
19 | name: "chromium",
20 | use: { ...devices["Desktop Chrome"] },
21 | },
22 | {
23 | name: "firefox",
24 | use: { ...devices["Desktop Firefox"] },
25 | },
26 | {
27 | name: "webkit",
28 | use: { ...devices["Desktop Safari"] },
29 | },
30 | ],
31 |
32 | webServer: process.env.CI
33 | ? undefined
34 | : {
35 | command: `cd example && PORT=${PORT} pnpm dev`,
36 | port: Number(PORT),
37 | reuseExistingServer: false,
38 | },
39 | });
40 |
--------------------------------------------------------------------------------
/pnpm-lock.yaml:
--------------------------------------------------------------------------------
1 | lockfileVersion: '9.0'
2 |
3 | settings:
4 | autoInstallPeers: true
5 | excludeLinksFromLockfile: false
6 |
7 | importers:
8 |
9 | .:
10 | devDependencies:
11 | '@playwright/test':
12 | specifier: ^1.52.0
13 | version: 1.52.0
14 | '@types/node':
15 | specifier: ^20
16 | version: 20.16.5
17 | '@types/react':
18 | specifier: ^18.3.5
19 | version: 18.3.5
20 | next:
21 | specifier: ^14.2.11
22 | version: 14.2.11(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
23 | playwright:
24 | specifier: ^1.52.0
25 | version: 1.52.0
26 | react:
27 | specifier: ^18.3.1
28 | version: 18.3.1
29 | tsup:
30 | specifier: ^8.2.4
31 | version: 8.2.4(postcss@8.4.31)(typescript@5.6.2)
32 | typescript:
33 | specifier: ^5.6.2
34 | version: 5.6.2
35 |
36 | example:
37 | dependencies:
38 | next:
39 | specifier: 14.2.11
40 | version: 14.2.11(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
41 | next-navigation-guard:
42 | specifier: link:..
43 | version: link:..
44 | react:
45 | specifier: ^18
46 | version: 18.3.1
47 | react-dom:
48 | specifier: ^18
49 | version: 18.3.1(react@18.3.1)
50 | devDependencies:
51 | '@types/node':
52 | specifier: ^20
53 | version: 20.16.5
54 | '@types/react':
55 | specifier: ^18
56 | version: 18.3.5
57 | '@types/react-dom':
58 | specifier: ^18
59 | version: 18.3.0
60 | typescript:
61 | specifier: ^5
62 | version: 5.6.2
63 |
64 | packages:
65 |
66 | '@esbuild/aix-ppc64@0.23.1':
67 | resolution: {integrity: sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==}
68 | engines: {node: '>=18'}
69 | cpu: [ppc64]
70 | os: [aix]
71 |
72 | '@esbuild/android-arm64@0.23.1':
73 | resolution: {integrity: sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==}
74 | engines: {node: '>=18'}
75 | cpu: [arm64]
76 | os: [android]
77 |
78 | '@esbuild/android-arm@0.23.1':
79 | resolution: {integrity: sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ==}
80 | engines: {node: '>=18'}
81 | cpu: [arm]
82 | os: [android]
83 |
84 | '@esbuild/android-x64@0.23.1':
85 | resolution: {integrity: sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==}
86 | engines: {node: '>=18'}
87 | cpu: [x64]
88 | os: [android]
89 |
90 | '@esbuild/darwin-arm64@0.23.1':
91 | resolution: {integrity: sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q==}
92 | engines: {node: '>=18'}
93 | cpu: [arm64]
94 | os: [darwin]
95 |
96 | '@esbuild/darwin-x64@0.23.1':
97 | resolution: {integrity: sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==}
98 | engines: {node: '>=18'}
99 | cpu: [x64]
100 | os: [darwin]
101 |
102 | '@esbuild/freebsd-arm64@0.23.1':
103 | resolution: {integrity: sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA==}
104 | engines: {node: '>=18'}
105 | cpu: [arm64]
106 | os: [freebsd]
107 |
108 | '@esbuild/freebsd-x64@0.23.1':
109 | resolution: {integrity: sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==}
110 | engines: {node: '>=18'}
111 | cpu: [x64]
112 | os: [freebsd]
113 |
114 | '@esbuild/linux-arm64@0.23.1':
115 | resolution: {integrity: sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g==}
116 | engines: {node: '>=18'}
117 | cpu: [arm64]
118 | os: [linux]
119 |
120 | '@esbuild/linux-arm@0.23.1':
121 | resolution: {integrity: sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ==}
122 | engines: {node: '>=18'}
123 | cpu: [arm]
124 | os: [linux]
125 |
126 | '@esbuild/linux-ia32@0.23.1':
127 | resolution: {integrity: sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ==}
128 | engines: {node: '>=18'}
129 | cpu: [ia32]
130 | os: [linux]
131 |
132 | '@esbuild/linux-loong64@0.23.1':
133 | resolution: {integrity: sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw==}
134 | engines: {node: '>=18'}
135 | cpu: [loong64]
136 | os: [linux]
137 |
138 | '@esbuild/linux-mips64el@0.23.1':
139 | resolution: {integrity: sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q==}
140 | engines: {node: '>=18'}
141 | cpu: [mips64el]
142 | os: [linux]
143 |
144 | '@esbuild/linux-ppc64@0.23.1':
145 | resolution: {integrity: sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw==}
146 | engines: {node: '>=18'}
147 | cpu: [ppc64]
148 | os: [linux]
149 |
150 | '@esbuild/linux-riscv64@0.23.1':
151 | resolution: {integrity: sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA==}
152 | engines: {node: '>=18'}
153 | cpu: [riscv64]
154 | os: [linux]
155 |
156 | '@esbuild/linux-s390x@0.23.1':
157 | resolution: {integrity: sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw==}
158 | engines: {node: '>=18'}
159 | cpu: [s390x]
160 | os: [linux]
161 |
162 | '@esbuild/linux-x64@0.23.1':
163 | resolution: {integrity: sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ==}
164 | engines: {node: '>=18'}
165 | cpu: [x64]
166 | os: [linux]
167 |
168 | '@esbuild/netbsd-x64@0.23.1':
169 | resolution: {integrity: sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA==}
170 | engines: {node: '>=18'}
171 | cpu: [x64]
172 | os: [netbsd]
173 |
174 | '@esbuild/openbsd-arm64@0.23.1':
175 | resolution: {integrity: sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==}
176 | engines: {node: '>=18'}
177 | cpu: [arm64]
178 | os: [openbsd]
179 |
180 | '@esbuild/openbsd-x64@0.23.1':
181 | resolution: {integrity: sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA==}
182 | engines: {node: '>=18'}
183 | cpu: [x64]
184 | os: [openbsd]
185 |
186 | '@esbuild/sunos-x64@0.23.1':
187 | resolution: {integrity: sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==}
188 | engines: {node: '>=18'}
189 | cpu: [x64]
190 | os: [sunos]
191 |
192 | '@esbuild/win32-arm64@0.23.1':
193 | resolution: {integrity: sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A==}
194 | engines: {node: '>=18'}
195 | cpu: [arm64]
196 | os: [win32]
197 |
198 | '@esbuild/win32-ia32@0.23.1':
199 | resolution: {integrity: sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ==}
200 | engines: {node: '>=18'}
201 | cpu: [ia32]
202 | os: [win32]
203 |
204 | '@esbuild/win32-x64@0.23.1':
205 | resolution: {integrity: sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==}
206 | engines: {node: '>=18'}
207 | cpu: [x64]
208 | os: [win32]
209 |
210 | '@isaacs/cliui@8.0.2':
211 | resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
212 | engines: {node: '>=12'}
213 |
214 | '@jridgewell/gen-mapping@0.3.5':
215 | resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==}
216 | engines: {node: '>=6.0.0'}
217 |
218 | '@jridgewell/resolve-uri@3.1.2':
219 | resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
220 | engines: {node: '>=6.0.0'}
221 |
222 | '@jridgewell/set-array@1.2.1':
223 | resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==}
224 | engines: {node: '>=6.0.0'}
225 |
226 | '@jridgewell/sourcemap-codec@1.5.0':
227 | resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==}
228 |
229 | '@jridgewell/trace-mapping@0.3.25':
230 | resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==}
231 |
232 | '@next/env@14.2.11':
233 | resolution: {integrity: sha512-HYsQRSIXwiNqvzzYThrBwq6RhXo3E0n8j8nQnAs8i4fCEo2Zf/3eS0IiRA8XnRg9Ha0YnpkyJZIZg1qEwemrHw==}
234 |
235 | '@next/swc-darwin-arm64@14.2.11':
236 | resolution: {integrity: sha512-eiY9u7wEJZWp/Pga07Qy3ZmNEfALmmSS1HtsJF3y1QEyaExu7boENz11fWqDmZ3uvcyAxCMhTrA1jfVxITQW8g==}
237 | engines: {node: '>= 10'}
238 | cpu: [arm64]
239 | os: [darwin]
240 |
241 | '@next/swc-darwin-x64@14.2.11':
242 | resolution: {integrity: sha512-lnB0zYCld4yE0IX3ANrVMmtAbziBb7MYekcmR6iE9bujmgERl6+FK+b0MBq0pl304lYe7zO4yxJus9H/Af8jbg==}
243 | engines: {node: '>= 10'}
244 | cpu: [x64]
245 | os: [darwin]
246 |
247 | '@next/swc-linux-arm64-gnu@14.2.11':
248 | resolution: {integrity: sha512-Ulo9TZVocYmUAtzvZ7FfldtwUoQY0+9z3BiXZCLSUwU2bp7GqHA7/bqrfsArDlUb2xeGwn3ZuBbKtNK8TR0A8w==}
249 | engines: {node: '>= 10'}
250 | cpu: [arm64]
251 | os: [linux]
252 |
253 | '@next/swc-linux-arm64-musl@14.2.11':
254 | resolution: {integrity: sha512-fH377DnKGyUnkWlmUpFF1T90m0dADBfK11dF8sOQkiELF9M+YwDRCGe8ZyDzvQcUd20Rr5U7vpZRrAxKwd3Rzg==}
255 | engines: {node: '>= 10'}
256 | cpu: [arm64]
257 | os: [linux]
258 |
259 | '@next/swc-linux-x64-gnu@14.2.11':
260 | resolution: {integrity: sha512-a0TH4ZZp4NS0LgXP/488kgvWelNpwfgGTUCDXVhPGH6pInb7yIYNgM4kmNWOxBFt+TIuOH6Pi9NnGG4XWFUyXQ==}
261 | engines: {node: '>= 10'}
262 | cpu: [x64]
263 | os: [linux]
264 |
265 | '@next/swc-linux-x64-musl@14.2.11':
266 | resolution: {integrity: sha512-DYYZcO4Uir2gZxA4D2JcOAKVs8ZxbOFYPpXSVIgeoQbREbeEHxysVsg3nY4FrQy51e5opxt5mOHl/LzIyZBoKA==}
267 | engines: {node: '>= 10'}
268 | cpu: [x64]
269 | os: [linux]
270 |
271 | '@next/swc-win32-arm64-msvc@14.2.11':
272 | resolution: {integrity: sha512-PwqHeKG3/kKfPpM6of1B9UJ+Er6ySUy59PeFu0Un0LBzJTRKKAg2V6J60Yqzp99m55mLa+YTbU6xj61ImTv9mg==}
273 | engines: {node: '>= 10'}
274 | cpu: [arm64]
275 | os: [win32]
276 |
277 | '@next/swc-win32-ia32-msvc@14.2.11':
278 | resolution: {integrity: sha512-0U7PWMnOYIvM74GY6rbH6w7v+vNPDVH1gUhlwHpfInJnNe5LkmUZqhp7FNWeNa5wbVgRcRi1F1cyxp4dmeLLvA==}
279 | engines: {node: '>= 10'}
280 | cpu: [ia32]
281 | os: [win32]
282 |
283 | '@next/swc-win32-x64-msvc@14.2.11':
284 | resolution: {integrity: sha512-gQpS7mcgovWoaTG1FbS5/ojF7CGfql1Q0ZLsMrhcsi2Sr9HEqsUZ70MPJyaYBXbk6iEAP7UXMD9HC8KY1qNwvA==}
285 | engines: {node: '>= 10'}
286 | cpu: [x64]
287 | os: [win32]
288 |
289 | '@nodelib/fs.scandir@2.1.5':
290 | resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
291 | engines: {node: '>= 8'}
292 |
293 | '@nodelib/fs.stat@2.0.5':
294 | resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==}
295 | engines: {node: '>= 8'}
296 |
297 | '@nodelib/fs.walk@1.2.8':
298 | resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
299 | engines: {node: '>= 8'}
300 |
301 | '@pkgjs/parseargs@0.11.0':
302 | resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
303 | engines: {node: '>=14'}
304 |
305 | '@playwright/test@1.52.0':
306 | resolution: {integrity: sha512-uh6W7sb55hl7D6vsAeA+V2p5JnlAqzhqFyF0VcJkKZXkgnFcVG9PziERRHQfPLfNGx1C292a4JqbWzhR8L4R1g==}
307 | engines: {node: '>=18'}
308 | hasBin: true
309 |
310 | '@rollup/rollup-android-arm-eabi@4.21.3':
311 | resolution: {integrity: sha512-MmKSfaB9GX+zXl6E8z4koOr/xU63AMVleLEa64v7R0QF/ZloMs5vcD1sHgM64GXXS1csaJutG+ddtzcueI/BLg==}
312 | cpu: [arm]
313 | os: [android]
314 |
315 | '@rollup/rollup-android-arm64@4.21.3':
316 | resolution: {integrity: sha512-zrt8ecH07PE3sB4jPOggweBjJMzI1JG5xI2DIsUbkA+7K+Gkjys6eV7i9pOenNSDJH3eOr/jLb/PzqtmdwDq5g==}
317 | cpu: [arm64]
318 | os: [android]
319 |
320 | '@rollup/rollup-darwin-arm64@4.21.3':
321 | resolution: {integrity: sha512-P0UxIOrKNBFTQaXTxOH4RxuEBVCgEA5UTNV6Yz7z9QHnUJ7eLX9reOd/NYMO3+XZO2cco19mXTxDMXxit4R/eQ==}
322 | cpu: [arm64]
323 | os: [darwin]
324 |
325 | '@rollup/rollup-darwin-x64@4.21.3':
326 | resolution: {integrity: sha512-L1M0vKGO5ASKntqtsFEjTq/fD91vAqnzeaF6sfNAy55aD+Hi2pBI5DKwCO+UNDQHWsDViJLqshxOahXyLSh3EA==}
327 | cpu: [x64]
328 | os: [darwin]
329 |
330 | '@rollup/rollup-linux-arm-gnueabihf@4.21.3':
331 | resolution: {integrity: sha512-btVgIsCjuYFKUjopPoWiDqmoUXQDiW2A4C3Mtmp5vACm7/GnyuprqIDPNczeyR5W8rTXEbkmrJux7cJmD99D2g==}
332 | cpu: [arm]
333 | os: [linux]
334 |
335 | '@rollup/rollup-linux-arm-musleabihf@4.21.3':
336 | resolution: {integrity: sha512-zmjbSphplZlau6ZTkxd3+NMtE4UKVy7U4aVFMmHcgO5CUbw17ZP6QCgyxhzGaU/wFFdTfiojjbLG3/0p9HhAqA==}
337 | cpu: [arm]
338 | os: [linux]
339 |
340 | '@rollup/rollup-linux-arm64-gnu@4.21.3':
341 | resolution: {integrity: sha512-nSZfcZtAnQPRZmUkUQwZq2OjQciR6tEoJaZVFvLHsj0MF6QhNMg0fQ6mUOsiCUpTqxTx0/O6gX0V/nYc7LrgPw==}
342 | cpu: [arm64]
343 | os: [linux]
344 |
345 | '@rollup/rollup-linux-arm64-musl@4.21.3':
346 | resolution: {integrity: sha512-MnvSPGO8KJXIMGlQDYfvYS3IosFN2rKsvxRpPO2l2cum+Z3exiExLwVU+GExL96pn8IP+GdH8Tz70EpBhO0sIQ==}
347 | cpu: [arm64]
348 | os: [linux]
349 |
350 | '@rollup/rollup-linux-powerpc64le-gnu@4.21.3':
351 | resolution: {integrity: sha512-+W+p/9QNDr2vE2AXU0qIy0qQE75E8RTwTwgqS2G5CRQ11vzq0tbnfBd6brWhS9bCRjAjepJe2fvvkvS3dno+iw==}
352 | cpu: [ppc64]
353 | os: [linux]
354 |
355 | '@rollup/rollup-linux-riscv64-gnu@4.21.3':
356 | resolution: {integrity: sha512-yXH6K6KfqGXaxHrtr+Uoy+JpNlUlI46BKVyonGiaD74ravdnF9BUNC+vV+SIuB96hUMGShhKV693rF9QDfO6nQ==}
357 | cpu: [riscv64]
358 | os: [linux]
359 |
360 | '@rollup/rollup-linux-s390x-gnu@4.21.3':
361 | resolution: {integrity: sha512-R8cwY9wcnApN/KDYWTH4gV/ypvy9yZUHlbJvfaiXSB48JO3KpwSpjOGqO4jnGkLDSk1hgjYkTbTt6Q7uvPf8eg==}
362 | cpu: [s390x]
363 | os: [linux]
364 |
365 | '@rollup/rollup-linux-x64-gnu@4.21.3':
366 | resolution: {integrity: sha512-kZPbX/NOPh0vhS5sI+dR8L1bU2cSO9FgxwM8r7wHzGydzfSjLRCFAT87GR5U9scj2rhzN3JPYVC7NoBbl4FZ0g==}
367 | cpu: [x64]
368 | os: [linux]
369 |
370 | '@rollup/rollup-linux-x64-musl@4.21.3':
371 | resolution: {integrity: sha512-S0Yq+xA1VEH66uiMNhijsWAafffydd2X5b77eLHfRmfLsRSpbiAWiRHV6DEpz6aOToPsgid7TI9rGd6zB1rhbg==}
372 | cpu: [x64]
373 | os: [linux]
374 |
375 | '@rollup/rollup-win32-arm64-msvc@4.21.3':
376 | resolution: {integrity: sha512-9isNzeL34yquCPyerog+IMCNxKR8XYmGd0tHSV+OVx0TmE0aJOo9uw4fZfUuk2qxobP5sug6vNdZR6u7Mw7Q+Q==}
377 | cpu: [arm64]
378 | os: [win32]
379 |
380 | '@rollup/rollup-win32-ia32-msvc@4.21.3':
381 | resolution: {integrity: sha512-nMIdKnfZfzn1Vsk+RuOvl43ONTZXoAPUUxgcU0tXooqg4YrAqzfKzVenqqk2g5efWh46/D28cKFrOzDSW28gTA==}
382 | cpu: [ia32]
383 | os: [win32]
384 |
385 | '@rollup/rollup-win32-x64-msvc@4.21.3':
386 | resolution: {integrity: sha512-fOvu7PCQjAj4eWDEuD8Xz5gpzFqXzGlxHZozHP4b9Jxv9APtdxL6STqztDzMLuRXEc4UpXGGhx029Xgm91QBeA==}
387 | cpu: [x64]
388 | os: [win32]
389 |
390 | '@swc/counter@0.1.3':
391 | resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==}
392 |
393 | '@swc/helpers@0.5.5':
394 | resolution: {integrity: sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==}
395 |
396 | '@types/estree@1.0.5':
397 | resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==}
398 |
399 | '@types/node@20.16.5':
400 | resolution: {integrity: sha512-VwYCweNo3ERajwy0IUlqqcyZ8/A7Zwa9ZP3MnENWcB11AejO+tLy3pu850goUW2FC/IJMdZUfKpX/yxL1gymCA==}
401 |
402 | '@types/prop-types@15.7.12':
403 | resolution: {integrity: sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==}
404 |
405 | '@types/react-dom@18.3.0':
406 | resolution: {integrity: sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==}
407 |
408 | '@types/react@18.3.5':
409 | resolution: {integrity: sha512-WeqMfGJLGuLCqHGYRGHxnKrXcTitc6L/nBUWfWPcTarG3t9PsquqUMuVeXZeca+mglY4Vo5GZjCi0A3Or2lnxA==}
410 |
411 | ansi-regex@5.0.1:
412 | resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
413 | engines: {node: '>=8'}
414 |
415 | ansi-regex@6.1.0:
416 | resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==}
417 | engines: {node: '>=12'}
418 |
419 | ansi-styles@4.3.0:
420 | resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
421 | engines: {node: '>=8'}
422 |
423 | ansi-styles@6.2.1:
424 | resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==}
425 | engines: {node: '>=12'}
426 |
427 | any-promise@1.3.0:
428 | resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==}
429 |
430 | anymatch@3.1.3:
431 | resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
432 | engines: {node: '>= 8'}
433 |
434 | array-union@2.1.0:
435 | resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==}
436 | engines: {node: '>=8'}
437 |
438 | balanced-match@1.0.2:
439 | resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
440 |
441 | binary-extensions@2.3.0:
442 | resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
443 | engines: {node: '>=8'}
444 |
445 | brace-expansion@2.0.1:
446 | resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==}
447 |
448 | braces@3.0.3:
449 | resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
450 | engines: {node: '>=8'}
451 |
452 | bundle-require@5.0.0:
453 | resolution: {integrity: sha512-GuziW3fSSmopcx4KRymQEJVbZUfqlCqcq7dvs6TYwKRZiegK/2buMxQTPs6MGlNv50wms1699qYO54R8XfRX4w==}
454 | engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
455 | peerDependencies:
456 | esbuild: '>=0.18'
457 |
458 | busboy@1.6.0:
459 | resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==}
460 | engines: {node: '>=10.16.0'}
461 |
462 | cac@6.7.14:
463 | resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==}
464 | engines: {node: '>=8'}
465 |
466 | caniuse-lite@1.0.30001660:
467 | resolution: {integrity: sha512-GacvNTTuATm26qC74pt+ad1fW15mlQ/zuTzzY1ZoIzECTP8HURDfF43kNxPgf7H1jmelCBQTTbBNxdSXOA7Bqg==}
468 |
469 | chokidar@3.6.0:
470 | resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
471 | engines: {node: '>= 8.10.0'}
472 |
473 | client-only@0.0.1:
474 | resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==}
475 |
476 | color-convert@2.0.1:
477 | resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
478 | engines: {node: '>=7.0.0'}
479 |
480 | color-name@1.1.4:
481 | resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
482 |
483 | commander@4.1.1:
484 | resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==}
485 | engines: {node: '>= 6'}
486 |
487 | consola@3.2.3:
488 | resolution: {integrity: sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==}
489 | engines: {node: ^14.18.0 || >=16.10.0}
490 |
491 | cross-spawn@7.0.3:
492 | resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
493 | engines: {node: '>= 8'}
494 |
495 | csstype@3.1.3:
496 | resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
497 |
498 | debug@4.3.7:
499 | resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==}
500 | engines: {node: '>=6.0'}
501 | peerDependencies:
502 | supports-color: '*'
503 | peerDependenciesMeta:
504 | supports-color:
505 | optional: true
506 |
507 | dir-glob@3.0.1:
508 | resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==}
509 | engines: {node: '>=8'}
510 |
511 | eastasianwidth@0.2.0:
512 | resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
513 |
514 | emoji-regex@8.0.0:
515 | resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
516 |
517 | emoji-regex@9.2.2:
518 | resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==}
519 |
520 | esbuild@0.23.1:
521 | resolution: {integrity: sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==}
522 | engines: {node: '>=18'}
523 | hasBin: true
524 |
525 | execa@5.1.1:
526 | resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==}
527 | engines: {node: '>=10'}
528 |
529 | fast-glob@3.3.2:
530 | resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==}
531 | engines: {node: '>=8.6.0'}
532 |
533 | fastq@1.17.1:
534 | resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==}
535 |
536 | fill-range@7.1.1:
537 | resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
538 | engines: {node: '>=8'}
539 |
540 | foreground-child@3.3.0:
541 | resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==}
542 | engines: {node: '>=14'}
543 |
544 | fsevents@2.3.2:
545 | resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
546 | engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
547 | os: [darwin]
548 |
549 | fsevents@2.3.3:
550 | resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
551 | engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
552 | os: [darwin]
553 |
554 | get-stream@6.0.1:
555 | resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==}
556 | engines: {node: '>=10'}
557 |
558 | glob-parent@5.1.2:
559 | resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
560 | engines: {node: '>= 6'}
561 |
562 | glob@10.4.5:
563 | resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==}
564 | hasBin: true
565 |
566 | globby@11.1.0:
567 | resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==}
568 | engines: {node: '>=10'}
569 |
570 | graceful-fs@4.2.11:
571 | resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
572 |
573 | human-signals@2.1.0:
574 | resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==}
575 | engines: {node: '>=10.17.0'}
576 |
577 | ignore@5.3.2:
578 | resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==}
579 | engines: {node: '>= 4'}
580 |
581 | is-binary-path@2.1.0:
582 | resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
583 | engines: {node: '>=8'}
584 |
585 | is-extglob@2.1.1:
586 | resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
587 | engines: {node: '>=0.10.0'}
588 |
589 | is-fullwidth-code-point@3.0.0:
590 | resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
591 | engines: {node: '>=8'}
592 |
593 | is-glob@4.0.3:
594 | resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
595 | engines: {node: '>=0.10.0'}
596 |
597 | is-number@7.0.0:
598 | resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
599 | engines: {node: '>=0.12.0'}
600 |
601 | is-stream@2.0.1:
602 | resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==}
603 | engines: {node: '>=8'}
604 |
605 | isexe@2.0.0:
606 | resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
607 |
608 | jackspeak@3.4.3:
609 | resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==}
610 |
611 | joycon@3.1.1:
612 | resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==}
613 | engines: {node: '>=10'}
614 |
615 | js-tokens@4.0.0:
616 | resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
617 |
618 | lilconfig@3.1.2:
619 | resolution: {integrity: sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==}
620 | engines: {node: '>=14'}
621 |
622 | lines-and-columns@1.2.4:
623 | resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
624 |
625 | load-tsconfig@0.2.5:
626 | resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==}
627 | engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
628 |
629 | lodash.sortby@4.7.0:
630 | resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==}
631 |
632 | loose-envify@1.4.0:
633 | resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
634 | hasBin: true
635 |
636 | lru-cache@10.4.3:
637 | resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==}
638 |
639 | merge-stream@2.0.0:
640 | resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==}
641 |
642 | merge2@1.4.1:
643 | resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
644 | engines: {node: '>= 8'}
645 |
646 | micromatch@4.0.8:
647 | resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==}
648 | engines: {node: '>=8.6'}
649 |
650 | mimic-fn@2.1.0:
651 | resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==}
652 | engines: {node: '>=6'}
653 |
654 | minimatch@9.0.5:
655 | resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==}
656 | engines: {node: '>=16 || 14 >=14.17'}
657 |
658 | minipass@7.1.2:
659 | resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==}
660 | engines: {node: '>=16 || 14 >=14.17'}
661 |
662 | ms@2.1.3:
663 | resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
664 |
665 | mz@2.7.0:
666 | resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==}
667 |
668 | nanoid@3.3.7:
669 | resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==}
670 | engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
671 | hasBin: true
672 |
673 | next@14.2.11:
674 | resolution: {integrity: sha512-8MDFqHBhdmR2wdfaWc8+lW3A/hppFe1ggQ9vgIu/g2/2QEMYJrPoQP6b+VNk56gIug/bStysAmrpUKtj3XN8Bw==}
675 | engines: {node: '>=18.17.0'}
676 | hasBin: true
677 | peerDependencies:
678 | '@opentelemetry/api': ^1.1.0
679 | '@playwright/test': ^1.41.2
680 | react: ^18.2.0
681 | react-dom: ^18.2.0
682 | sass: ^1.3.0
683 | peerDependenciesMeta:
684 | '@opentelemetry/api':
685 | optional: true
686 | '@playwright/test':
687 | optional: true
688 | sass:
689 | optional: true
690 |
691 | normalize-path@3.0.0:
692 | resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
693 | engines: {node: '>=0.10.0'}
694 |
695 | npm-run-path@4.0.1:
696 | resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==}
697 | engines: {node: '>=8'}
698 |
699 | object-assign@4.1.1:
700 | resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
701 | engines: {node: '>=0.10.0'}
702 |
703 | onetime@5.1.2:
704 | resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==}
705 | engines: {node: '>=6'}
706 |
707 | package-json-from-dist@1.0.0:
708 | resolution: {integrity: sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==}
709 |
710 | path-key@3.1.1:
711 | resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
712 | engines: {node: '>=8'}
713 |
714 | path-scurry@1.11.1:
715 | resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==}
716 | engines: {node: '>=16 || 14 >=14.18'}
717 |
718 | path-type@4.0.0:
719 | resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
720 | engines: {node: '>=8'}
721 |
722 | picocolors@1.1.0:
723 | resolution: {integrity: sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==}
724 |
725 | picomatch@2.3.1:
726 | resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
727 | engines: {node: '>=8.6'}
728 |
729 | pirates@4.0.6:
730 | resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==}
731 | engines: {node: '>= 6'}
732 |
733 | playwright-core@1.52.0:
734 | resolution: {integrity: sha512-l2osTgLXSMeuLZOML9qYODUQoPPnUsKsb5/P6LJ2e6uPKXUdPK5WYhN4z03G+YNbWmGDY4YENauNu4ZKczreHg==}
735 | engines: {node: '>=18'}
736 | hasBin: true
737 |
738 | playwright@1.52.0:
739 | resolution: {integrity: sha512-JAwMNMBlxJ2oD1kce4KPtMkDeKGHQstdpFPcPH3maElAXon/QZeTvtsfXmTMRyO9TslfoYOXkSsvao2nE1ilTw==}
740 | engines: {node: '>=18'}
741 | hasBin: true
742 |
743 | postcss-load-config@6.0.1:
744 | resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==}
745 | engines: {node: '>= 18'}
746 | peerDependencies:
747 | jiti: '>=1.21.0'
748 | postcss: '>=8.0.9'
749 | tsx: ^4.8.1
750 | yaml: ^2.4.2
751 | peerDependenciesMeta:
752 | jiti:
753 | optional: true
754 | postcss:
755 | optional: true
756 | tsx:
757 | optional: true
758 | yaml:
759 | optional: true
760 |
761 | postcss@8.4.31:
762 | resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==}
763 | engines: {node: ^10 || ^12 || >=14}
764 |
765 | punycode@2.3.1:
766 | resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
767 | engines: {node: '>=6'}
768 |
769 | queue-microtask@1.2.3:
770 | resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
771 |
772 | react-dom@18.3.1:
773 | resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==}
774 | peerDependencies:
775 | react: ^18.3.1
776 |
777 | react@18.3.1:
778 | resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==}
779 | engines: {node: '>=0.10.0'}
780 |
781 | readdirp@3.6.0:
782 | resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
783 | engines: {node: '>=8.10.0'}
784 |
785 | resolve-from@5.0.0:
786 | resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==}
787 | engines: {node: '>=8'}
788 |
789 | reusify@1.0.4:
790 | resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==}
791 | engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
792 |
793 | rollup@4.21.3:
794 | resolution: {integrity: sha512-7sqRtBNnEbcBtMeRVc6VRsJMmpI+JU1z9VTvW8D4gXIYQFz0aLcsE6rRkyghZkLfEgUZgVvOG7A5CVz/VW5GIA==}
795 | engines: {node: '>=18.0.0', npm: '>=8.0.0'}
796 | hasBin: true
797 |
798 | run-parallel@1.2.0:
799 | resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
800 |
801 | scheduler@0.23.2:
802 | resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==}
803 |
804 | shebang-command@2.0.0:
805 | resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
806 | engines: {node: '>=8'}
807 |
808 | shebang-regex@3.0.0:
809 | resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
810 | engines: {node: '>=8'}
811 |
812 | signal-exit@3.0.7:
813 | resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==}
814 |
815 | signal-exit@4.1.0:
816 | resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
817 | engines: {node: '>=14'}
818 |
819 | slash@3.0.0:
820 | resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
821 | engines: {node: '>=8'}
822 |
823 | source-map-js@1.2.1:
824 | resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
825 | engines: {node: '>=0.10.0'}
826 |
827 | source-map@0.8.0-beta.0:
828 | resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==}
829 | engines: {node: '>= 8'}
830 |
831 | streamsearch@1.1.0:
832 | resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==}
833 | engines: {node: '>=10.0.0'}
834 |
835 | string-width@4.2.3:
836 | resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
837 | engines: {node: '>=8'}
838 |
839 | string-width@5.1.2:
840 | resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==}
841 | engines: {node: '>=12'}
842 |
843 | strip-ansi@6.0.1:
844 | resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
845 | engines: {node: '>=8'}
846 |
847 | strip-ansi@7.1.0:
848 | resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==}
849 | engines: {node: '>=12'}
850 |
851 | strip-final-newline@2.0.0:
852 | resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==}
853 | engines: {node: '>=6'}
854 |
855 | styled-jsx@5.1.1:
856 | resolution: {integrity: sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==}
857 | engines: {node: '>= 12.0.0'}
858 | peerDependencies:
859 | '@babel/core': '*'
860 | babel-plugin-macros: '*'
861 | react: '>= 16.8.0 || 17.x.x || ^18.0.0-0'
862 | peerDependenciesMeta:
863 | '@babel/core':
864 | optional: true
865 | babel-plugin-macros:
866 | optional: true
867 |
868 | sucrase@3.35.0:
869 | resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==}
870 | engines: {node: '>=16 || 14 >=14.17'}
871 | hasBin: true
872 |
873 | thenify-all@1.6.0:
874 | resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==}
875 | engines: {node: '>=0.8'}
876 |
877 | thenify@3.3.1:
878 | resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==}
879 |
880 | to-regex-range@5.0.1:
881 | resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
882 | engines: {node: '>=8.0'}
883 |
884 | tr46@1.0.1:
885 | resolution: {integrity: sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==}
886 |
887 | tree-kill@1.2.2:
888 | resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==}
889 | hasBin: true
890 |
891 | ts-interface-checker@0.1.13:
892 | resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==}
893 |
894 | tslib@2.8.1:
895 | resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
896 |
897 | tsup@8.2.4:
898 | resolution: {integrity: sha512-akpCPePnBnC/CXgRrcy72ZSntgIEUa1jN0oJbbvpALWKNOz1B7aM+UVDWGRGIO/T/PZugAESWDJUAb5FD48o8Q==}
899 | engines: {node: '>=18'}
900 | hasBin: true
901 | peerDependencies:
902 | '@microsoft/api-extractor': ^7.36.0
903 | '@swc/core': ^1
904 | postcss: ^8.4.12
905 | typescript: '>=4.5.0'
906 | peerDependenciesMeta:
907 | '@microsoft/api-extractor':
908 | optional: true
909 | '@swc/core':
910 | optional: true
911 | postcss:
912 | optional: true
913 | typescript:
914 | optional: true
915 |
916 | typescript@5.6.2:
917 | resolution: {integrity: sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==}
918 | engines: {node: '>=14.17'}
919 | hasBin: true
920 |
921 | undici-types@6.19.8:
922 | resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==}
923 |
924 | webidl-conversions@4.0.2:
925 | resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==}
926 |
927 | whatwg-url@7.1.0:
928 | resolution: {integrity: sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==}
929 |
930 | which@2.0.2:
931 | resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
932 | engines: {node: '>= 8'}
933 | hasBin: true
934 |
935 | wrap-ansi@7.0.0:
936 | resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
937 | engines: {node: '>=10'}
938 |
939 | wrap-ansi@8.1.0:
940 | resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==}
941 | engines: {node: '>=12'}
942 |
943 | snapshots:
944 |
945 | '@esbuild/aix-ppc64@0.23.1':
946 | optional: true
947 |
948 | '@esbuild/android-arm64@0.23.1':
949 | optional: true
950 |
951 | '@esbuild/android-arm@0.23.1':
952 | optional: true
953 |
954 | '@esbuild/android-x64@0.23.1':
955 | optional: true
956 |
957 | '@esbuild/darwin-arm64@0.23.1':
958 | optional: true
959 |
960 | '@esbuild/darwin-x64@0.23.1':
961 | optional: true
962 |
963 | '@esbuild/freebsd-arm64@0.23.1':
964 | optional: true
965 |
966 | '@esbuild/freebsd-x64@0.23.1':
967 | optional: true
968 |
969 | '@esbuild/linux-arm64@0.23.1':
970 | optional: true
971 |
972 | '@esbuild/linux-arm@0.23.1':
973 | optional: true
974 |
975 | '@esbuild/linux-ia32@0.23.1':
976 | optional: true
977 |
978 | '@esbuild/linux-loong64@0.23.1':
979 | optional: true
980 |
981 | '@esbuild/linux-mips64el@0.23.1':
982 | optional: true
983 |
984 | '@esbuild/linux-ppc64@0.23.1':
985 | optional: true
986 |
987 | '@esbuild/linux-riscv64@0.23.1':
988 | optional: true
989 |
990 | '@esbuild/linux-s390x@0.23.1':
991 | optional: true
992 |
993 | '@esbuild/linux-x64@0.23.1':
994 | optional: true
995 |
996 | '@esbuild/netbsd-x64@0.23.1':
997 | optional: true
998 |
999 | '@esbuild/openbsd-arm64@0.23.1':
1000 | optional: true
1001 |
1002 | '@esbuild/openbsd-x64@0.23.1':
1003 | optional: true
1004 |
1005 | '@esbuild/sunos-x64@0.23.1':
1006 | optional: true
1007 |
1008 | '@esbuild/win32-arm64@0.23.1':
1009 | optional: true
1010 |
1011 | '@esbuild/win32-ia32@0.23.1':
1012 | optional: true
1013 |
1014 | '@esbuild/win32-x64@0.23.1':
1015 | optional: true
1016 |
1017 | '@isaacs/cliui@8.0.2':
1018 | dependencies:
1019 | string-width: 5.1.2
1020 | string-width-cjs: string-width@4.2.3
1021 | strip-ansi: 7.1.0
1022 | strip-ansi-cjs: strip-ansi@6.0.1
1023 | wrap-ansi: 8.1.0
1024 | wrap-ansi-cjs: wrap-ansi@7.0.0
1025 |
1026 | '@jridgewell/gen-mapping@0.3.5':
1027 | dependencies:
1028 | '@jridgewell/set-array': 1.2.1
1029 | '@jridgewell/sourcemap-codec': 1.5.0
1030 | '@jridgewell/trace-mapping': 0.3.25
1031 |
1032 | '@jridgewell/resolve-uri@3.1.2': {}
1033 |
1034 | '@jridgewell/set-array@1.2.1': {}
1035 |
1036 | '@jridgewell/sourcemap-codec@1.5.0': {}
1037 |
1038 | '@jridgewell/trace-mapping@0.3.25':
1039 | dependencies:
1040 | '@jridgewell/resolve-uri': 3.1.2
1041 | '@jridgewell/sourcemap-codec': 1.5.0
1042 |
1043 | '@next/env@14.2.11': {}
1044 |
1045 | '@next/swc-darwin-arm64@14.2.11':
1046 | optional: true
1047 |
1048 | '@next/swc-darwin-x64@14.2.11':
1049 | optional: true
1050 |
1051 | '@next/swc-linux-arm64-gnu@14.2.11':
1052 | optional: true
1053 |
1054 | '@next/swc-linux-arm64-musl@14.2.11':
1055 | optional: true
1056 |
1057 | '@next/swc-linux-x64-gnu@14.2.11':
1058 | optional: true
1059 |
1060 | '@next/swc-linux-x64-musl@14.2.11':
1061 | optional: true
1062 |
1063 | '@next/swc-win32-arm64-msvc@14.2.11':
1064 | optional: true
1065 |
1066 | '@next/swc-win32-ia32-msvc@14.2.11':
1067 | optional: true
1068 |
1069 | '@next/swc-win32-x64-msvc@14.2.11':
1070 | optional: true
1071 |
1072 | '@nodelib/fs.scandir@2.1.5':
1073 | dependencies:
1074 | '@nodelib/fs.stat': 2.0.5
1075 | run-parallel: 1.2.0
1076 |
1077 | '@nodelib/fs.stat@2.0.5': {}
1078 |
1079 | '@nodelib/fs.walk@1.2.8':
1080 | dependencies:
1081 | '@nodelib/fs.scandir': 2.1.5
1082 | fastq: 1.17.1
1083 |
1084 | '@pkgjs/parseargs@0.11.0':
1085 | optional: true
1086 |
1087 | '@playwright/test@1.52.0':
1088 | dependencies:
1089 | playwright: 1.52.0
1090 |
1091 | '@rollup/rollup-android-arm-eabi@4.21.3':
1092 | optional: true
1093 |
1094 | '@rollup/rollup-android-arm64@4.21.3':
1095 | optional: true
1096 |
1097 | '@rollup/rollup-darwin-arm64@4.21.3':
1098 | optional: true
1099 |
1100 | '@rollup/rollup-darwin-x64@4.21.3':
1101 | optional: true
1102 |
1103 | '@rollup/rollup-linux-arm-gnueabihf@4.21.3':
1104 | optional: true
1105 |
1106 | '@rollup/rollup-linux-arm-musleabihf@4.21.3':
1107 | optional: true
1108 |
1109 | '@rollup/rollup-linux-arm64-gnu@4.21.3':
1110 | optional: true
1111 |
1112 | '@rollup/rollup-linux-arm64-musl@4.21.3':
1113 | optional: true
1114 |
1115 | '@rollup/rollup-linux-powerpc64le-gnu@4.21.3':
1116 | optional: true
1117 |
1118 | '@rollup/rollup-linux-riscv64-gnu@4.21.3':
1119 | optional: true
1120 |
1121 | '@rollup/rollup-linux-s390x-gnu@4.21.3':
1122 | optional: true
1123 |
1124 | '@rollup/rollup-linux-x64-gnu@4.21.3':
1125 | optional: true
1126 |
1127 | '@rollup/rollup-linux-x64-musl@4.21.3':
1128 | optional: true
1129 |
1130 | '@rollup/rollup-win32-arm64-msvc@4.21.3':
1131 | optional: true
1132 |
1133 | '@rollup/rollup-win32-ia32-msvc@4.21.3':
1134 | optional: true
1135 |
1136 | '@rollup/rollup-win32-x64-msvc@4.21.3':
1137 | optional: true
1138 |
1139 | '@swc/counter@0.1.3': {}
1140 |
1141 | '@swc/helpers@0.5.5':
1142 | dependencies:
1143 | '@swc/counter': 0.1.3
1144 | tslib: 2.8.1
1145 |
1146 | '@types/estree@1.0.5': {}
1147 |
1148 | '@types/node@20.16.5':
1149 | dependencies:
1150 | undici-types: 6.19.8
1151 |
1152 | '@types/prop-types@15.7.12': {}
1153 |
1154 | '@types/react-dom@18.3.0':
1155 | dependencies:
1156 | '@types/react': 18.3.5
1157 |
1158 | '@types/react@18.3.5':
1159 | dependencies:
1160 | '@types/prop-types': 15.7.12
1161 | csstype: 3.1.3
1162 |
1163 | ansi-regex@5.0.1: {}
1164 |
1165 | ansi-regex@6.1.0: {}
1166 |
1167 | ansi-styles@4.3.0:
1168 | dependencies:
1169 | color-convert: 2.0.1
1170 |
1171 | ansi-styles@6.2.1: {}
1172 |
1173 | any-promise@1.3.0: {}
1174 |
1175 | anymatch@3.1.3:
1176 | dependencies:
1177 | normalize-path: 3.0.0
1178 | picomatch: 2.3.1
1179 |
1180 | array-union@2.1.0: {}
1181 |
1182 | balanced-match@1.0.2: {}
1183 |
1184 | binary-extensions@2.3.0: {}
1185 |
1186 | brace-expansion@2.0.1:
1187 | dependencies:
1188 | balanced-match: 1.0.2
1189 |
1190 | braces@3.0.3:
1191 | dependencies:
1192 | fill-range: 7.1.1
1193 |
1194 | bundle-require@5.0.0(esbuild@0.23.1):
1195 | dependencies:
1196 | esbuild: 0.23.1
1197 | load-tsconfig: 0.2.5
1198 |
1199 | busboy@1.6.0:
1200 | dependencies:
1201 | streamsearch: 1.1.0
1202 |
1203 | cac@6.7.14: {}
1204 |
1205 | caniuse-lite@1.0.30001660: {}
1206 |
1207 | chokidar@3.6.0:
1208 | dependencies:
1209 | anymatch: 3.1.3
1210 | braces: 3.0.3
1211 | glob-parent: 5.1.2
1212 | is-binary-path: 2.1.0
1213 | is-glob: 4.0.3
1214 | normalize-path: 3.0.0
1215 | readdirp: 3.6.0
1216 | optionalDependencies:
1217 | fsevents: 2.3.3
1218 |
1219 | client-only@0.0.1: {}
1220 |
1221 | color-convert@2.0.1:
1222 | dependencies:
1223 | color-name: 1.1.4
1224 |
1225 | color-name@1.1.4: {}
1226 |
1227 | commander@4.1.1: {}
1228 |
1229 | consola@3.2.3: {}
1230 |
1231 | cross-spawn@7.0.3:
1232 | dependencies:
1233 | path-key: 3.1.1
1234 | shebang-command: 2.0.0
1235 | which: 2.0.2
1236 |
1237 | csstype@3.1.3: {}
1238 |
1239 | debug@4.3.7:
1240 | dependencies:
1241 | ms: 2.1.3
1242 |
1243 | dir-glob@3.0.1:
1244 | dependencies:
1245 | path-type: 4.0.0
1246 |
1247 | eastasianwidth@0.2.0: {}
1248 |
1249 | emoji-regex@8.0.0: {}
1250 |
1251 | emoji-regex@9.2.2: {}
1252 |
1253 | esbuild@0.23.1:
1254 | optionalDependencies:
1255 | '@esbuild/aix-ppc64': 0.23.1
1256 | '@esbuild/android-arm': 0.23.1
1257 | '@esbuild/android-arm64': 0.23.1
1258 | '@esbuild/android-x64': 0.23.1
1259 | '@esbuild/darwin-arm64': 0.23.1
1260 | '@esbuild/darwin-x64': 0.23.1
1261 | '@esbuild/freebsd-arm64': 0.23.1
1262 | '@esbuild/freebsd-x64': 0.23.1
1263 | '@esbuild/linux-arm': 0.23.1
1264 | '@esbuild/linux-arm64': 0.23.1
1265 | '@esbuild/linux-ia32': 0.23.1
1266 | '@esbuild/linux-loong64': 0.23.1
1267 | '@esbuild/linux-mips64el': 0.23.1
1268 | '@esbuild/linux-ppc64': 0.23.1
1269 | '@esbuild/linux-riscv64': 0.23.1
1270 | '@esbuild/linux-s390x': 0.23.1
1271 | '@esbuild/linux-x64': 0.23.1
1272 | '@esbuild/netbsd-x64': 0.23.1
1273 | '@esbuild/openbsd-arm64': 0.23.1
1274 | '@esbuild/openbsd-x64': 0.23.1
1275 | '@esbuild/sunos-x64': 0.23.1
1276 | '@esbuild/win32-arm64': 0.23.1
1277 | '@esbuild/win32-ia32': 0.23.1
1278 | '@esbuild/win32-x64': 0.23.1
1279 |
1280 | execa@5.1.1:
1281 | dependencies:
1282 | cross-spawn: 7.0.3
1283 | get-stream: 6.0.1
1284 | human-signals: 2.1.0
1285 | is-stream: 2.0.1
1286 | merge-stream: 2.0.0
1287 | npm-run-path: 4.0.1
1288 | onetime: 5.1.2
1289 | signal-exit: 3.0.7
1290 | strip-final-newline: 2.0.0
1291 |
1292 | fast-glob@3.3.2:
1293 | dependencies:
1294 | '@nodelib/fs.stat': 2.0.5
1295 | '@nodelib/fs.walk': 1.2.8
1296 | glob-parent: 5.1.2
1297 | merge2: 1.4.1
1298 | micromatch: 4.0.8
1299 |
1300 | fastq@1.17.1:
1301 | dependencies:
1302 | reusify: 1.0.4
1303 |
1304 | fill-range@7.1.1:
1305 | dependencies:
1306 | to-regex-range: 5.0.1
1307 |
1308 | foreground-child@3.3.0:
1309 | dependencies:
1310 | cross-spawn: 7.0.3
1311 | signal-exit: 4.1.0
1312 |
1313 | fsevents@2.3.2:
1314 | optional: true
1315 |
1316 | fsevents@2.3.3:
1317 | optional: true
1318 |
1319 | get-stream@6.0.1: {}
1320 |
1321 | glob-parent@5.1.2:
1322 | dependencies:
1323 | is-glob: 4.0.3
1324 |
1325 | glob@10.4.5:
1326 | dependencies:
1327 | foreground-child: 3.3.0
1328 | jackspeak: 3.4.3
1329 | minimatch: 9.0.5
1330 | minipass: 7.1.2
1331 | package-json-from-dist: 1.0.0
1332 | path-scurry: 1.11.1
1333 |
1334 | globby@11.1.0:
1335 | dependencies:
1336 | array-union: 2.1.0
1337 | dir-glob: 3.0.1
1338 | fast-glob: 3.3.2
1339 | ignore: 5.3.2
1340 | merge2: 1.4.1
1341 | slash: 3.0.0
1342 |
1343 | graceful-fs@4.2.11: {}
1344 |
1345 | human-signals@2.1.0: {}
1346 |
1347 | ignore@5.3.2: {}
1348 |
1349 | is-binary-path@2.1.0:
1350 | dependencies:
1351 | binary-extensions: 2.3.0
1352 |
1353 | is-extglob@2.1.1: {}
1354 |
1355 | is-fullwidth-code-point@3.0.0: {}
1356 |
1357 | is-glob@4.0.3:
1358 | dependencies:
1359 | is-extglob: 2.1.1
1360 |
1361 | is-number@7.0.0: {}
1362 |
1363 | is-stream@2.0.1: {}
1364 |
1365 | isexe@2.0.0: {}
1366 |
1367 | jackspeak@3.4.3:
1368 | dependencies:
1369 | '@isaacs/cliui': 8.0.2
1370 | optionalDependencies:
1371 | '@pkgjs/parseargs': 0.11.0
1372 |
1373 | joycon@3.1.1: {}
1374 |
1375 | js-tokens@4.0.0: {}
1376 |
1377 | lilconfig@3.1.2: {}
1378 |
1379 | lines-and-columns@1.2.4: {}
1380 |
1381 | load-tsconfig@0.2.5: {}
1382 |
1383 | lodash.sortby@4.7.0: {}
1384 |
1385 | loose-envify@1.4.0:
1386 | dependencies:
1387 | js-tokens: 4.0.0
1388 |
1389 | lru-cache@10.4.3: {}
1390 |
1391 | merge-stream@2.0.0: {}
1392 |
1393 | merge2@1.4.1: {}
1394 |
1395 | micromatch@4.0.8:
1396 | dependencies:
1397 | braces: 3.0.3
1398 | picomatch: 2.3.1
1399 |
1400 | mimic-fn@2.1.0: {}
1401 |
1402 | minimatch@9.0.5:
1403 | dependencies:
1404 | brace-expansion: 2.0.1
1405 |
1406 | minipass@7.1.2: {}
1407 |
1408 | ms@2.1.3: {}
1409 |
1410 | mz@2.7.0:
1411 | dependencies:
1412 | any-promise: 1.3.0
1413 | object-assign: 4.1.1
1414 | thenify-all: 1.6.0
1415 |
1416 | nanoid@3.3.7: {}
1417 |
1418 | next@14.2.11(@playwright/test@1.52.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
1419 | dependencies:
1420 | '@next/env': 14.2.11
1421 | '@swc/helpers': 0.5.5
1422 | busboy: 1.6.0
1423 | caniuse-lite: 1.0.30001660
1424 | graceful-fs: 4.2.11
1425 | postcss: 8.4.31
1426 | react: 18.3.1
1427 | react-dom: 18.3.1(react@18.3.1)
1428 | styled-jsx: 5.1.1(react@18.3.1)
1429 | optionalDependencies:
1430 | '@next/swc-darwin-arm64': 14.2.11
1431 | '@next/swc-darwin-x64': 14.2.11
1432 | '@next/swc-linux-arm64-gnu': 14.2.11
1433 | '@next/swc-linux-arm64-musl': 14.2.11
1434 | '@next/swc-linux-x64-gnu': 14.2.11
1435 | '@next/swc-linux-x64-musl': 14.2.11
1436 | '@next/swc-win32-arm64-msvc': 14.2.11
1437 | '@next/swc-win32-ia32-msvc': 14.2.11
1438 | '@next/swc-win32-x64-msvc': 14.2.11
1439 | '@playwright/test': 1.52.0
1440 | transitivePeerDependencies:
1441 | - '@babel/core'
1442 | - babel-plugin-macros
1443 |
1444 | normalize-path@3.0.0: {}
1445 |
1446 | npm-run-path@4.0.1:
1447 | dependencies:
1448 | path-key: 3.1.1
1449 |
1450 | object-assign@4.1.1: {}
1451 |
1452 | onetime@5.1.2:
1453 | dependencies:
1454 | mimic-fn: 2.1.0
1455 |
1456 | package-json-from-dist@1.0.0: {}
1457 |
1458 | path-key@3.1.1: {}
1459 |
1460 | path-scurry@1.11.1:
1461 | dependencies:
1462 | lru-cache: 10.4.3
1463 | minipass: 7.1.2
1464 |
1465 | path-type@4.0.0: {}
1466 |
1467 | picocolors@1.1.0: {}
1468 |
1469 | picomatch@2.3.1: {}
1470 |
1471 | pirates@4.0.6: {}
1472 |
1473 | playwright-core@1.52.0: {}
1474 |
1475 | playwright@1.52.0:
1476 | dependencies:
1477 | playwright-core: 1.52.0
1478 | optionalDependencies:
1479 | fsevents: 2.3.2
1480 |
1481 | postcss-load-config@6.0.1(postcss@8.4.31):
1482 | dependencies:
1483 | lilconfig: 3.1.2
1484 | optionalDependencies:
1485 | postcss: 8.4.31
1486 |
1487 | postcss@8.4.31:
1488 | dependencies:
1489 | nanoid: 3.3.7
1490 | picocolors: 1.1.0
1491 | source-map-js: 1.2.1
1492 |
1493 | punycode@2.3.1: {}
1494 |
1495 | queue-microtask@1.2.3: {}
1496 |
1497 | react-dom@18.3.1(react@18.3.1):
1498 | dependencies:
1499 | loose-envify: 1.4.0
1500 | react: 18.3.1
1501 | scheduler: 0.23.2
1502 |
1503 | react@18.3.1:
1504 | dependencies:
1505 | loose-envify: 1.4.0
1506 |
1507 | readdirp@3.6.0:
1508 | dependencies:
1509 | picomatch: 2.3.1
1510 |
1511 | resolve-from@5.0.0: {}
1512 |
1513 | reusify@1.0.4: {}
1514 |
1515 | rollup@4.21.3:
1516 | dependencies:
1517 | '@types/estree': 1.0.5
1518 | optionalDependencies:
1519 | '@rollup/rollup-android-arm-eabi': 4.21.3
1520 | '@rollup/rollup-android-arm64': 4.21.3
1521 | '@rollup/rollup-darwin-arm64': 4.21.3
1522 | '@rollup/rollup-darwin-x64': 4.21.3
1523 | '@rollup/rollup-linux-arm-gnueabihf': 4.21.3
1524 | '@rollup/rollup-linux-arm-musleabihf': 4.21.3
1525 | '@rollup/rollup-linux-arm64-gnu': 4.21.3
1526 | '@rollup/rollup-linux-arm64-musl': 4.21.3
1527 | '@rollup/rollup-linux-powerpc64le-gnu': 4.21.3
1528 | '@rollup/rollup-linux-riscv64-gnu': 4.21.3
1529 | '@rollup/rollup-linux-s390x-gnu': 4.21.3
1530 | '@rollup/rollup-linux-x64-gnu': 4.21.3
1531 | '@rollup/rollup-linux-x64-musl': 4.21.3
1532 | '@rollup/rollup-win32-arm64-msvc': 4.21.3
1533 | '@rollup/rollup-win32-ia32-msvc': 4.21.3
1534 | '@rollup/rollup-win32-x64-msvc': 4.21.3
1535 | fsevents: 2.3.3
1536 |
1537 | run-parallel@1.2.0:
1538 | dependencies:
1539 | queue-microtask: 1.2.3
1540 |
1541 | scheduler@0.23.2:
1542 | dependencies:
1543 | loose-envify: 1.4.0
1544 |
1545 | shebang-command@2.0.0:
1546 | dependencies:
1547 | shebang-regex: 3.0.0
1548 |
1549 | shebang-regex@3.0.0: {}
1550 |
1551 | signal-exit@3.0.7: {}
1552 |
1553 | signal-exit@4.1.0: {}
1554 |
1555 | slash@3.0.0: {}
1556 |
1557 | source-map-js@1.2.1: {}
1558 |
1559 | source-map@0.8.0-beta.0:
1560 | dependencies:
1561 | whatwg-url: 7.1.0
1562 |
1563 | streamsearch@1.1.0: {}
1564 |
1565 | string-width@4.2.3:
1566 | dependencies:
1567 | emoji-regex: 8.0.0
1568 | is-fullwidth-code-point: 3.0.0
1569 | strip-ansi: 6.0.1
1570 |
1571 | string-width@5.1.2:
1572 | dependencies:
1573 | eastasianwidth: 0.2.0
1574 | emoji-regex: 9.2.2
1575 | strip-ansi: 7.1.0
1576 |
1577 | strip-ansi@6.0.1:
1578 | dependencies:
1579 | ansi-regex: 5.0.1
1580 |
1581 | strip-ansi@7.1.0:
1582 | dependencies:
1583 | ansi-regex: 6.1.0
1584 |
1585 | strip-final-newline@2.0.0: {}
1586 |
1587 | styled-jsx@5.1.1(react@18.3.1):
1588 | dependencies:
1589 | client-only: 0.0.1
1590 | react: 18.3.1
1591 |
1592 | sucrase@3.35.0:
1593 | dependencies:
1594 | '@jridgewell/gen-mapping': 0.3.5
1595 | commander: 4.1.1
1596 | glob: 10.4.5
1597 | lines-and-columns: 1.2.4
1598 | mz: 2.7.0
1599 | pirates: 4.0.6
1600 | ts-interface-checker: 0.1.13
1601 |
1602 | thenify-all@1.6.0:
1603 | dependencies:
1604 | thenify: 3.3.1
1605 |
1606 | thenify@3.3.1:
1607 | dependencies:
1608 | any-promise: 1.3.0
1609 |
1610 | to-regex-range@5.0.1:
1611 | dependencies:
1612 | is-number: 7.0.0
1613 |
1614 | tr46@1.0.1:
1615 | dependencies:
1616 | punycode: 2.3.1
1617 |
1618 | tree-kill@1.2.2: {}
1619 |
1620 | ts-interface-checker@0.1.13: {}
1621 |
1622 | tslib@2.8.1: {}
1623 |
1624 | tsup@8.2.4(postcss@8.4.31)(typescript@5.6.2):
1625 | dependencies:
1626 | bundle-require: 5.0.0(esbuild@0.23.1)
1627 | cac: 6.7.14
1628 | chokidar: 3.6.0
1629 | consola: 3.2.3
1630 | debug: 4.3.7
1631 | esbuild: 0.23.1
1632 | execa: 5.1.1
1633 | globby: 11.1.0
1634 | joycon: 3.1.1
1635 | picocolors: 1.1.0
1636 | postcss-load-config: 6.0.1(postcss@8.4.31)
1637 | resolve-from: 5.0.0
1638 | rollup: 4.21.3
1639 | source-map: 0.8.0-beta.0
1640 | sucrase: 3.35.0
1641 | tree-kill: 1.2.2
1642 | optionalDependencies:
1643 | postcss: 8.4.31
1644 | typescript: 5.6.2
1645 | transitivePeerDependencies:
1646 | - jiti
1647 | - supports-color
1648 | - tsx
1649 | - yaml
1650 |
1651 | typescript@5.6.2: {}
1652 |
1653 | undici-types@6.19.8: {}
1654 |
1655 | webidl-conversions@4.0.2: {}
1656 |
1657 | whatwg-url@7.1.0:
1658 | dependencies:
1659 | lodash.sortby: 4.7.0
1660 | tr46: 1.0.1
1661 | webidl-conversions: 4.0.2
1662 |
1663 | which@2.0.2:
1664 | dependencies:
1665 | isexe: 2.0.0
1666 |
1667 | wrap-ansi@7.0.0:
1668 | dependencies:
1669 | ansi-styles: 4.3.0
1670 | string-width: 4.2.3
1671 | strip-ansi: 6.0.1
1672 |
1673 | wrap-ansi@8.1.0:
1674 | dependencies:
1675 | ansi-styles: 6.2.1
1676 | string-width: 5.1.2
1677 | strip-ansi: 7.1.0
1678 |
--------------------------------------------------------------------------------
/pnpm-workspace.yaml:
--------------------------------------------------------------------------------
1 | packages:
2 | - '.'
3 | - 'example'
4 |
--------------------------------------------------------------------------------
/src/components/InterceptAppRouterProvider.tsx:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { AppRouterContext } from "next/dist/shared/lib/app-router-context.shared-runtime";
4 | import React, { MutableRefObject } from "react";
5 | import { useInterceptedAppRouter } from "../hooks/useInterceptedAppRouter";
6 | import { GuardDef } from "../types";
7 |
8 | export function InterceptAppRouterProvider({
9 | guardMapRef,
10 | children,
11 | }: {
12 | guardMapRef: MutableRefObject