diff --git a/.changeset/config.json b/.changeset/config.json index 571e46a..64b4210 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -8,7 +8,7 @@ "baseBranch": "main", "updateInternalDependencies": "patch", "ignore": [ - "summer-sale", + "shirt-shop", "svelte-example", "next-13", "next-14", diff --git a/examples/summer-sale/.eslintrc.json b/examples/shirt-shop/.eslintrc.json similarity index 100% rename from examples/summer-sale/.eslintrc.json rename to examples/shirt-shop/.eslintrc.json diff --git a/examples/summer-sale/.gitignore b/examples/shirt-shop/.gitignore similarity index 100% rename from examples/summer-sale/.gitignore rename to examples/shirt-shop/.gitignore diff --git a/examples/shirt-shop/README.md b/examples/shirt-shop/README.md new file mode 100644 index 0000000..76002bc --- /dev/null +++ b/examples/shirt-shop/README.md @@ -0,0 +1,56 @@ +# Shirt Shop Flags SDK Example + +This example uses the [Flags SDK](https://flags-sdk.dev) along with the [Flags Explorer](https://vercel.com/docs/workflow-collaboration/feature-flags/using-vercel-toolbar) and `@vercel/analytics`. + +## Demo + +[https://shirt-shop.labs.vercel.dev/](https://shirt-shop.labs.vercel.dev/) + +## How it works + +This demo uses two feature flags defined in code control the visibility of two banners on the page. +Both flags are configured to show/hide each banner 50% of the time. + +Once you visit the page, you can see a variation of both/one/none of the banners. +Since this example is using a stable id to identify users, you will see the same variation all the time. + +To test different variations, you can use the Dev Tools at the bottom to reset the stable id and reload the page. +This allows you to test different variations of the banners. + +This templates also tracks analytics events in Vercel Analytics. + +If you deployed your own instance of this example you can also use the [Flags Explorer](https://vercel.com/docs/workflow-collaboration/feature-flags/using-vercel-toolbar) to test different variations by creating overrides. + +## Deploy this template + +[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fvercel%2Fflags%2Ftree%2Fmain%2Fexamples%2Fshirt-shop&env=FLAGS_SECRET&envDescription=The+FLAGS_SECRET+will+be+used+by+the+Flags+Explorer+to+securely+overwrite+feature+flags.+Must+be+32+random+bytes%2C+base64-encoded.+Use+the+generated+value+or+set+your+own.&envLink=https%3A%2F%2Fvercel.com%2Fdocs%2Fworkflow-collaboration%2Ffeature-flags%2Fsupporting-feature-flags%23flags_secret-environment-variable&project-name=shirt-shop-flags-sdk-example&repository-name=shirt-shop-flags-sdk-example) + +### Step 1: Link the project + +In order to use the Flags Explorer, you need to link the project on your local machine. + +```bash +vercel link +``` + +Select the project from the list you just deployed. + +### Step 2: Pull all environment variables + +This allows the Flags SDK and the Flags Explorer to work correctly, by getting additional metadata. + +```bash +vercel env pull +``` + +### Step 2: Install dependencies + +```bash +npm install +``` + +### Step 3: Run the project + +```bash +npm run dev +``` diff --git a/examples/summer-sale/app/.well-known/vercel/flags/route.ts b/examples/shirt-shop/app/.well-known/vercel/flags/route.ts similarity index 85% rename from examples/summer-sale/app/.well-known/vercel/flags/route.ts rename to examples/shirt-shop/app/.well-known/vercel/flags/route.ts index 9b0c824..548debe 100644 --- a/examples/summer-sale/app/.well-known/vercel/flags/route.ts +++ b/examples/shirt-shop/app/.well-known/vercel/flags/route.ts @@ -10,6 +10,7 @@ export async function GET(request: NextRequest) { const access = await verifyAccess(request.headers.get('Authorization')); if (!access) return NextResponse.json(null, { status: 401 }); - const providerData = getProviderData(flags); + // Forward info from Flags in Code + const providerData = await getProviderData(flags); return NextResponse.json(providerData); } diff --git a/examples/summer-sale/app/[code]/layout.tsx b/examples/shirt-shop/app/[code]/layout.tsx similarity index 53% rename from examples/summer-sale/app/[code]/layout.tsx rename to examples/shirt-shop/app/[code]/layout.tsx index 9caffa0..a49cdc1 100644 --- a/examples/summer-sale/app/[code]/layout.tsx +++ b/examples/shirt-shop/app/[code]/layout.tsx @@ -1,13 +1,6 @@ -import { precomputeFlags } from '@/flags'; -import { type FlagValuesType, encrypt } from 'flags'; +import { productFlags } from '@/flags'; import { deserialize, generatePermutations } from 'flags/next'; import { FlagValues } from 'flags/react'; -import { Suspense } from 'react'; - -async function ConfidentialFlagValues({ values }: { values: FlagValuesType }) { - const encryptedFlagValues = await encrypt(values); - return ; -} export async function generateStaticParams() { // Returning an empty array here is important as it enables ISR, so @@ -17,7 +10,7 @@ export async function generateStaticParams() { // Instead of returning an empty array you could also call generatePermutations // to generate the permutations upfront. - const codes = await generatePermutations(precomputeFlags); + const codes = await generatePermutations(productFlags); return codes.map((code) => ({ code })); } @@ -28,17 +21,12 @@ export default async function Layout(props: { }>; }) { const params = await props.params; - - const { children } = props; - - const values = await deserialize(precomputeFlags, params.code); + const values = await deserialize(productFlags, params.code); return ( <> - {children} - - - + {props.children} + ); } diff --git a/examples/shirt-shop/app/[code]/page.tsx b/examples/shirt-shop/app/[code]/page.tsx new file mode 100644 index 0000000..9f62c8e --- /dev/null +++ b/examples/shirt-shop/app/[code]/page.tsx @@ -0,0 +1,54 @@ +import { AddToCartButton } from '@/components/add-to-cart-button'; +import { FreeDeliveryBanner } from '@/components/banners/free-delivery-banner'; +import { SummerBanner } from '@/components/banners/summer-banner'; +import { ColorPicker } from '@/components/color-picker'; +import { DevTools } from '@/components/dev-tools'; +import { Footer } from '@/components/footer'; +import { ImageGallery } from '@/components/image-gallery'; +import { Navigation } from '@/components/navigation'; +import { ProductDetails } from '@/components/product-details'; +import { ProductHeader } from '@/components/product-header'; +import { SizePicker } from '@/components/size-picker'; +import { + productFlags, + showFreeDeliveryBannerFlag, + showSummerBannerFlag, +} from '@/flags'; +import { getPrecomputed } from 'flags/next'; + +export default async function Page(props: { + params: Promise<{ code: string }>; +}) { + const params = await props.params; + + const [showSummerBanner, showFreeDeliveryBanner] = await getPrecomputed( + [showSummerBannerFlag, showFreeDeliveryBannerFlag], + productFlags, + params.code, + ); + + return ( +
+ + + + +
+
+ + + +
+ + + + +
+
+
+ +
+ +
+ ); +} diff --git a/examples/shirt-shop/app/favicon.ico b/examples/shirt-shop/app/favicon.ico new file mode 100644 index 0000000..81d9b2d Binary files /dev/null and b/examples/shirt-shop/app/favicon.ico differ diff --git a/examples/shirt-shop/app/globals.css b/examples/shirt-shop/app/globals.css new file mode 100644 index 0000000..d4b5078 --- /dev/null +++ b/examples/shirt-shop/app/globals.css @@ -0,0 +1 @@ +@import 'tailwindcss'; diff --git a/examples/summer-sale/app/layout.tsx b/examples/shirt-shop/app/layout.tsx similarity index 73% rename from examples/summer-sale/app/layout.tsx rename to examples/shirt-shop/app/layout.tsx index 4c0a88a..beda9b7 100644 --- a/examples/summer-sale/app/layout.tsx +++ b/examples/shirt-shop/app/layout.tsx @@ -1,12 +1,11 @@ -import type { Metadata } from 'next'; import { VercelToolbar } from '@vercel/toolbar/next'; import { Analytics } from '@vercel/analytics/next'; +import type { Metadata } from 'next'; import './globals.css'; export const metadata: Metadata = { title: 'Shirt Shop', - description: 'Generated by create next app', }; export default function RootLayout({ @@ -14,14 +13,12 @@ export default function RootLayout({ }: Readonly<{ children: React.ReactNode; }>) { - const shouldInjectToolbar = process.env.NODE_ENV === 'development'; return ( {children} - - {shouldInjectToolbar && } + ); diff --git a/examples/shirt-shop/components/add-to-cart-button.tsx b/examples/shirt-shop/components/add-to-cart-button.tsx new file mode 100644 index 0000000..14b9cd6 --- /dev/null +++ b/examples/shirt-shop/components/add-to-cart-button.tsx @@ -0,0 +1,20 @@ +'use client'; + +import { track } from '@vercel/analytics'; +import { useEffect } from 'react'; + +export function AddToCartButton() { + useEffect(() => { + track('add_to_cart:viewed'); + }, []); + + return ( + + ); +} diff --git a/examples/shirt-shop/components/banners/free-delivery-banner.tsx b/examples/shirt-shop/components/banners/free-delivery-banner.tsx new file mode 100644 index 0000000..edb2bcc --- /dev/null +++ b/examples/shirt-shop/components/banners/free-delivery-banner.tsx @@ -0,0 +1,18 @@ +'use client'; + +import { track } from '@vercel/analytics'; +import { useEffect } from 'react'; + +export function FreeDeliveryBanner(props: { show: boolean }) { + useEffect(() => { + if (props.show) track('free_delivery_banner:viewed'); + }, [props.show]); + + if (!props.show) return null; + + return ( +
+ Get free delivery on orders over $100 +
+ ); +} diff --git a/examples/summer-sale/components/promo.tsx b/examples/shirt-shop/components/banners/summer-banner.tsx similarity index 67% rename from examples/summer-sale/components/promo.tsx rename to examples/shirt-shop/components/banners/summer-banner.tsx index 39e7add..220af75 100644 --- a/examples/summer-sale/components/promo.tsx +++ b/examples/shirt-shop/components/banners/summer-banner.tsx @@ -1,18 +1,25 @@ 'use client'; +import pool from '@/public/images/pool.jpg'; import Image from 'next/image'; -import summer from '../public/etienne-girardet-Xh6BpT-1tXo-unsplash.jpg'; -import { track } from '@vercel/analytics/react'; +import { track } from '@vercel/analytics'; +import { useEffect } from 'react'; + +export function SummerBanner(props: { show: boolean }) { + useEffect(() => { + if (props.show) track('summer_banner:viewed'); + }, [props.show]); + + if (!props.show) return null; -export function Promo() { return (
-
+
@@ -22,19 +29,15 @@ export function Promo() { Summer Sale

- Enjoy 20% off all summer styles, + Enjoy 20% off all summer basics,
- from bright dresses to pastel-hued tops. + including swimwear and accessories.

+
+ ); +} diff --git a/examples/shirt-shop/components/footer.tsx b/examples/shirt-shop/components/footer.tsx new file mode 100644 index 0000000..e05fe12 --- /dev/null +++ b/examples/shirt-shop/components/footer.tsx @@ -0,0 +1,49 @@ +import { ShoppingBagIcon } from '@heroicons/react/24/outline'; + +const navigation = [ + 'Home', + 'About', + 'Terms & Conditions', + 'Shipping & Return Policy', + 'Privacy Policy', + 'FAQ', +]; + +export function Footer() { + return ( +
+
+
+
+
+ +
+ +
+
+ +
+
+
+
+ +
+

+ © {new Date().getFullYear()} ACME, Inc. All rights reserved. +

+
+
+
+ ); +} diff --git a/examples/shirt-shop/components/image-gallery.tsx b/examples/shirt-shop/components/image-gallery.tsx new file mode 100644 index 0000000..7ff58ff --- /dev/null +++ b/examples/shirt-shop/components/image-gallery.tsx @@ -0,0 +1,28 @@ +import clsx from 'clsx'; +import Image from 'next/image'; + +import blue from '@/public/images/product/shirt-blue.avif'; +import black from '@/public/images/product/shirt-black.avif'; +import white from '@/public/images/product/shirt-white.avif'; + +const images = [black, white, blue]; + +export function ImageGallery() { + return ( +
+
+ {images.map((image, index) => ( + Product Image + ))} +
+
+ ); +} diff --git a/examples/shirt-shop/components/navigation.tsx b/examples/shirt-shop/components/navigation.tsx new file mode 100644 index 0000000..dc1804b --- /dev/null +++ b/examples/shirt-shop/components/navigation.tsx @@ -0,0 +1,52 @@ +import { + Bars3Icon, + ShoppingBagIcon, + ShoppingCartIcon, +} from '@heroicons/react/24/outline'; + +const navigation = ['Home', 'Sale', 'New', 'Shirts', 'Stickers']; + +export function Navigation() { + return ( +
+ +
+ ); +} diff --git a/examples/shirt-shop/components/product-details.tsx b/examples/shirt-shop/components/product-details.tsx new file mode 100644 index 0000000..7bd216f --- /dev/null +++ b/examples/shirt-shop/components/product-details.tsx @@ -0,0 +1,40 @@ +export function ProductDetails() { + return ( + <> +
+

Description

+
+

+ Embrace geometric simplicity with our Circles tee. This modern take + on casual wear features a clean, minimalist design that speaks + volumes without saying a word. Each circle pattern is perfectly + balanced, creating a visual rhythm that makes this tee both a + statement piece and a versatile wardrobe essential. +

+
+
+ +
+

+ Quality you can feel +

+
+
    +
  • + Premium-grade cotton blend for exceptional comfort +
  • +
  • + Pre-washed and pre-shrunk for a reliable fit +
  • +
  • + Proudly produced in local partner facilities +
  • +
+
+
+ + ); +} diff --git a/examples/shirt-shop/components/product-header.tsx b/examples/shirt-shop/components/product-header.tsx new file mode 100644 index 0000000..13679b1 --- /dev/null +++ b/examples/shirt-shop/components/product-header.tsx @@ -0,0 +1,13 @@ +import { ProductReviews } from './product-reviews'; + +export function ProductHeader() { + return ( +
+
+

Circles T-Shirt

+

20.00 USD

+
+ +
+ ); +} diff --git a/examples/shirt-shop/components/product-reviews.tsx b/examples/shirt-shop/components/product-reviews.tsx new file mode 100644 index 0000000..f66e291 --- /dev/null +++ b/examples/shirt-shop/components/product-reviews.tsx @@ -0,0 +1,27 @@ +import { StarIcon } from '@heroicons/react/20/solid'; +import clsx from 'clsx'; + +export function ProductReviews() { + return ( +
+
+

4.9

+
+ {[0, 1, 2, 3, 4].map((rating) => ( +
+ +
+ See all 312 reviews +
+
+
+ ); +} diff --git a/examples/shirt-shop/components/size-picker.tsx b/examples/shirt-shop/components/size-picker.tsx new file mode 100644 index 0000000..0b27780 --- /dev/null +++ b/examples/shirt-shop/components/size-picker.tsx @@ -0,0 +1,50 @@ +'use client'; + +import { Radio, RadioGroup } from '@headlessui/react'; +import clsx from 'clsx'; +import { useState } from 'react'; + +const sizes = [ + { name: 'XXS', inStock: true }, + { name: 'XS', inStock: true }, + { name: 'S', inStock: true }, + { name: 'M', inStock: true }, + { name: 'L', inStock: true }, + { name: 'XL', inStock: false }, +]; + +export function SizePicker() { + const [selectedSize, setSelectedSize] = useState(sizes[0]); + + return ( +
+
+

Size

+
+ +
+ + {sizes.map((size) => ( + + {size.name} + + ))} + +
+
+ ); +} diff --git a/examples/shirt-shop/flags.ts b/examples/shirt-shop/flags.ts new file mode 100644 index 0000000..891f785 --- /dev/null +++ b/examples/shirt-shop/flags.ts @@ -0,0 +1,45 @@ +import { flag } from 'flags/next'; +import { identify, type EvaluationContext } from './utils/identify'; +import { xxHash32 } from 'js-xxhash'; + +/** + * Takes a string and puts it into a bucket. + * + * Typically the key consists of the experiment name and the stableId, such that + * every experiment has a different outcome. If it would depend on the stableId only, + * then a user would consistently get assigned the same bucket for all experiments, + * which we need to avoid. + * + * @param key - The key to hash. + * @param buckets - The number of buckets to use. + * @returns The determined bucket number. + */ +function bucket(key: string, buckets: number = 2) { + const hashNum = xxHash32(key); + return hashNum % buckets; +} + +export const showSummerBannerFlag = flag({ + key: 'summer_sale', + defaultValue: false, + identify, + decide({ entities }) { + if (!entities || !entities.stableId) return this.defaultValue!; + return bucket(`${this.key}/${entities.stableId}`) === 1; + }, +}); + +export const showFreeDeliveryBannerFlag = flag({ + key: 'free_delivery', + defaultValue: false, + identify, + decide({ entities }) { + if (!entities || !entities.stableId) return this.defaultValue!; + return bucket(`${this.key}/${entities.stableId}`) === 1; + }, +}); + +export const productFlags = [ + showFreeDeliveryBannerFlag, + showSummerBannerFlag, +] as const; diff --git a/examples/shirt-shop/middleware.ts b/examples/shirt-shop/middleware.ts new file mode 100644 index 0000000..228d020 --- /dev/null +++ b/examples/shirt-shop/middleware.ts @@ -0,0 +1,29 @@ +import { type NextRequest, NextResponse } from 'next/server'; +import { precompute } from 'flags/next'; +import { productFlags } from '@/flags'; +import { getStableId } from './utils/get-stable-id'; + +export const config = { + matcher: ['/'], +}; + +export async function middleware(request: NextRequest) { + const stableId = await getStableId(); + + if (request.nextUrl.pathname === '/') { + const code = await precompute(productFlags); + + // rewrites the request to the variant for this flag combination + const nextUrl = new URL( + `/${code}${request.nextUrl.pathname}${request.nextUrl.search}`, + request.url, + ); + + return NextResponse.rewrite(nextUrl, { + request, + headers: stableId.isFresh + ? { 'set-cookie': `stable-id=${stableId.value}` } + : undefined, + }); + } +} diff --git a/examples/summer-sale/next.config.mjs b/examples/shirt-shop/next.config.mjs similarity index 100% rename from examples/summer-sale/next.config.mjs rename to examples/shirt-shop/next.config.mjs diff --git a/examples/shirt-shop/package.json b/examples/shirt-shop/package.json new file mode 100644 index 0000000..ef3776d --- /dev/null +++ b/examples/shirt-shop/package.json @@ -0,0 +1,39 @@ +{ + "name": "shirt-shop", + "version": "0.0.0", + "private": true, + "scripts": { + "build": "next build", + "dev": "next dev", + "lint": "next lint", + "start": "next start" + }, + "dependencies": { + "@headlessui/react": "^2.2.0", + "@heroicons/react": "2.2.0", + "@tailwindcss/aspect-ratio": "0.4.2", + "@tailwindcss/forms": "0.5.10", + "@tailwindcss/postcss": "^4.0.8", + "@tailwindcss/typography": "0.5.16", + "@vercel/analytics": "1.5.0", + "@vercel/edge": "1.2.1", + "@vercel/edge-config": "1.4.0", + "@vercel/toolbar": "0.1.33", + "clsx": "2.1.1", + "flags": "workspace:*", + "js-xxhash": "4.0.0", + "nanoid": "5.1.2", + "next": "15.1.7", + "react": "^19.0.0", + "react-dom": "^19.0.0" + }, + "devDependencies": { + "@types/node": "^22.13.5", + "@types/react": "^19.0.10", + "@types/react-dom": "^19.0.4", + "eslint": "^9.21.0", + "postcss": "^8.5.3", + "tailwindcss": "^4.0.8", + "typescript": "^5.7.3" + } +} diff --git a/examples/summer-sale/postcss.config.mjs b/examples/shirt-shop/postcss.config.mjs similarity index 78% rename from examples/summer-sale/postcss.config.mjs rename to examples/shirt-shop/postcss.config.mjs index 1a69fd2..5d6d845 100644 --- a/examples/summer-sale/postcss.config.mjs +++ b/examples/shirt-shop/postcss.config.mjs @@ -1,7 +1,7 @@ /** @type {import('postcss-load-config').Config} */ const config = { plugins: { - tailwindcss: {}, + '@tailwindcss/postcss': {}, }, }; diff --git a/examples/summer-sale/public/etienne-girardet-Xh6BpT-1tXo-unsplash.jpg b/examples/shirt-shop/public/images/pool.jpg similarity index 100% rename from examples/summer-sale/public/etienne-girardet-Xh6BpT-1tXo-unsplash.jpg rename to examples/shirt-shop/public/images/pool.jpg diff --git a/examples/shirt-shop/public/images/product/shirt-black.avif b/examples/shirt-shop/public/images/product/shirt-black.avif new file mode 100644 index 0000000..3ca437e Binary files /dev/null and b/examples/shirt-shop/public/images/product/shirt-black.avif differ diff --git a/examples/shirt-shop/public/images/product/shirt-blue.avif b/examples/shirt-shop/public/images/product/shirt-blue.avif new file mode 100644 index 0000000..1888ea9 Binary files /dev/null and b/examples/shirt-shop/public/images/product/shirt-blue.avif differ diff --git a/examples/shirt-shop/public/images/product/shirt-white.avif b/examples/shirt-shop/public/images/product/shirt-white.avif new file mode 100644 index 0000000..3a2895e Binary files /dev/null and b/examples/shirt-shop/public/images/product/shirt-white.avif differ diff --git a/examples/summer-sale/tailwind.config.ts b/examples/shirt-shop/tailwind.config.ts similarity index 53% rename from examples/summer-sale/tailwind.config.ts rename to examples/shirt-shop/tailwind.config.ts index 0e69377..ef5c0cf 100644 --- a/examples/summer-sale/tailwind.config.ts +++ b/examples/shirt-shop/tailwind.config.ts @@ -2,23 +2,14 @@ import type { Config } from 'tailwindcss'; const config: Config = { content: [ - './pages/**/*.{js,ts,jsx,tsx,mdx}', './components/**/*.{js,ts,jsx,tsx,mdx}', './app/**/*.{js,ts,jsx,tsx,mdx}', ], - theme: { - extend: { - backgroundImage: { - 'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))', - 'gradient-conic': - 'conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))', - }, - }, - }, plugins: [ require('@tailwindcss/forms'), require('@tailwindcss/typography'), require('@tailwindcss/aspect-ratio'), ], }; + export default config; diff --git a/examples/summer-sale/tsconfig.json b/examples/shirt-shop/tsconfig.json similarity index 100% rename from examples/summer-sale/tsconfig.json rename to examples/shirt-shop/tsconfig.json diff --git a/examples/shirt-shop/utils/get-stable-id.ts b/examples/shirt-shop/utils/get-stable-id.ts new file mode 100644 index 0000000..78a9c5b --- /dev/null +++ b/examples/shirt-shop/utils/get-stable-id.ts @@ -0,0 +1,13 @@ +import { cookies } from 'next/headers'; +import { dedupe } from 'flags/next'; +import { nanoid } from 'nanoid'; + +/** + * Reads the stable id from the cookie or returns a new stable id + */ +export const getStableId = dedupe(async () => { + const cookiesStore = await cookies(); + const stableId = cookiesStore.get('stable-id')?.value; + if (!stableId) return { value: nanoid(), isFresh: true }; + return { value: stableId, isFresh: false }; +}); diff --git a/examples/shirt-shop/utils/identify.ts b/examples/shirt-shop/utils/identify.ts new file mode 100644 index 0000000..5f99f46 --- /dev/null +++ b/examples/shirt-shop/utils/identify.ts @@ -0,0 +1,13 @@ +import { Identify } from 'flags'; +import { dedupe } from 'flags/next'; +import { getStableId } from './get-stable-id'; + +export type EvaluationContext = { + stableId?: string; +}; + +export const identify = dedupe(async () => { + const stableId = await getStableId(); + + return { stableId: stableId.value }; +}) satisfies Identify; diff --git a/examples/summer-sale/CHANGELOG.md b/examples/summer-sale/CHANGELOG.md deleted file mode 100644 index d706724..0000000 --- a/examples/summer-sale/CHANGELOG.md +++ /dev/null @@ -1,55 +0,0 @@ -# summer-sale - -## 0.1.7 - -### Patch Changes - -- Updated dependencies [fb50709] -- Updated dependencies [87503b6] - - @vercel/flags@2.7.0 - -## 0.1.6 - -### Patch Changes - -- Updated dependencies [69f8df0] -- Updated dependencies [65d3d73] - - @vercel/flags@2.6.3 - -## 0.1.5 - -### Patch Changes - -- Updated dependencies [80e0737] - - @vercel/flags@2.6.2 - -## 0.1.4 - -### Patch Changes - -- Updated dependencies [9c379a8] - - @vercel/flags@2.6.1 - -## 0.1.3 - -### Patch Changes - -- Updated dependencies [7b9aa17] -- Updated dependencies [b049c26] -- Updated dependencies [c12f4d4] -- Updated dependencies [1be4799] - - @vercel/flags@2.6.0 - -## 0.1.2 - -### Patch Changes - -- Updated dependencies [3a68cf7] - - @vercel/flags@2.5.1 - -## 0.1.1 - -### Patch Changes - -- Updated dependencies [1003c29] - - @vercel/flags@2.5.0 diff --git a/examples/summer-sale/README.md b/examples/summer-sale/README.md deleted file mode 100644 index c403366..0000000 --- a/examples/summer-sale/README.md +++ /dev/null @@ -1,36 +0,0 @@ -This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app). - -## Getting Started - -First, run the development server: - -```bash -npm run dev -# or -yarn dev -# or -pnpm dev -# or -bun dev -``` - -Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. - -You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file. - -This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font. - -## Learn More - -To learn more about Next.js, take a look at the following resources: - -- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. -- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. - -You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome! - -## Deploy on Vercel - -The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. - -Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details. diff --git a/examples/summer-sale/app/[code]/page.tsx b/examples/summer-sale/app/[code]/page.tsx deleted file mode 100644 index 53d57ff..0000000 --- a/examples/summer-sale/app/[code]/page.tsx +++ /dev/null @@ -1,80 +0,0 @@ -import { Header } from '@/components/header'; -import { Reviews } from '@/components/reviews'; -import { RelatedProducts } from '@/components/related-products'; -import { ProductDetailReviews } from '@/components/product-detail-reviews'; -import { ImageGallery } from '@/components/image-gallery'; -import { ColorPicker } from '@/components/color-picker'; -import { SizePicker } from '@/components/size-picker'; -import { Policies } from '@/components/policies'; -import { ProductDetails } from '@/components/product-details'; -import { Footer } from '@/components/footer'; -import { Materials } from '@/components/materials'; -import { ProductHeading } from '@/components/product-heading'; -import { Promo } from '@/components/promo'; -import { TopBanner } from '@/components/top-banner'; -import { getPrecomputed, generatePermutations } from 'flags/next'; -import { - showFreeDeliveryBannerFlag, - showSummerBannerFlag, - precomputeFlags, -} from '@/flags'; - -export const dynamicParams = true; -export async function generateStaticParams() { - const codes = await generatePermutations(precomputeFlags); - return codes.map((code) => ({ code })); -} - -export default async function Example(props: { - params: Promise<{ code: string }>; -}) { - const params = await props.params; - const [showSummerBanner, showFreeDeliveryBanner] = await getPrecomputed( - [showSummerBannerFlag, showFreeDeliveryBannerFlag], - precomputeFlags, - params.code, - ); - - return ( -
- {showFreeDeliveryBanner ? : null} -
- {showSummerBanner ? : null} - -
-
-
- - -
- - - -
-
- - - - - - - - - - -
-
- - - -
- -
-
- ); -} diff --git a/examples/summer-sale/app/data.ts b/examples/summer-sale/app/data.ts deleted file mode 100644 index 5b7fe22..0000000 --- a/examples/summer-sale/app/data.ts +++ /dev/null @@ -1,153 +0,0 @@ -import { - CurrencyDollarIcon, - GlobeAmericasIcon, -} from '@heroicons/react/24/outline'; -import product0 from '../public/product-page-0.jpg'; -import product1 from '../public/product-page-1.jpg'; -import product2 from '../public/product-page-2.jpg'; -import relatedProduct0 from '../public/product-related-0.jpg'; - -export const navigation = { - categories: [ - { - id: 'women', - name: 'Women', - }, - { - id: 'men', - name: 'Men', - }, - { - id: 'company', - name: 'Company', - }, - { - id: 'stores', - name: 'Stores', - }, - ], -}; -export const product = { - name: 'Basic Tee', - price: '$35', - href: '#', - breadcrumbs: [ - { id: 1, name: 'Women', href: '#' }, - { id: 2, name: 'Clothing', href: '#' }, - ], - images: [ - { - id: 1, - imageSrc: product0, - imageAlt: "Back of women's Basic Tee in black.", - primary: true, - }, - { - id: 2, - imageSrc: product1, - imageAlt: "Side profile of women's Basic Tee in black.", - primary: false, - }, - { - id: 3, - imageSrc: product2, - imageAlt: "Front of women's Basic Tee in black.", - primary: false, - }, - ], - colors: [ - { name: 'Black', bgColor: 'bg-gray-900', selectedColor: 'ring-gray-900' }, - { - name: 'Heather Grey', - bgColor: 'bg-gray-400', - selectedColor: 'ring-gray-400', - }, - ], - sizes: [ - { name: 'XXS', inStock: true }, - { name: 'XS', inStock: true }, - { name: 'S', inStock: true }, - { name: 'M', inStock: true }, - { name: 'L', inStock: true }, - { name: 'XL', inStock: false }, - ], - description: ` -

The Basic tee is an honest new take on a classic. The tee uses super soft, pre-shrunk cotton for true comfort and a dependable fit. They are hand cut and sewn locally, with a special dye technique that gives each tee it's own look.

-

Looking to stock your closet? The Basic tee also comes in a 3-pack or 5-pack at a bundle discount.

- `, - details: [ - 'Only the best materials', - 'Ethically and locally made', - 'Pre-washed and pre-shrunk', - 'Machine wash cold with similar colors', - ], -}; -export const policies = [ - { - name: 'International delivery', - icon: GlobeAmericasIcon, - description: 'Get your order in 2 days', - }, - { - name: 'Loyalty rewards', - icon: CurrencyDollarIcon, - description: "Don't look at other tees", - }, -]; -export const reviews = { - average: 3.9, - totalCount: 512, - featured: [ - { - id: 1, - title: "Can't say enough good things", - rating: 5, - content: ` -

I was really pleased with the overall shopping experience. My order even included a little personal, handwritten note, which delighted me!

-

The product quality is amazing, it looks and feel even better than I had anticipated. Brilliant stuff! I would gladly recommend this store to my friends. And, now that I think of it... I actually have, many times!

- `, - author: 'Risako M', - date: 'May 16, 2021', - datetime: '2021-01-06', - }, - // More reviews... - ], -}; -export const relatedProducts = [ - { - id: 1, - name: 'Basic Tee', - href: '#', - imageSrc: relatedProduct0, - imageAlt: "Front of men's Basic Tee in white.", - price: '$35', - color: 'Aspen White', - }, - // More products... -]; -export const footerNavigation = { - products: [ - { name: 'Bags', href: '#' }, - { name: 'Tees', href: '#' }, - { name: 'Objects', href: '#' }, - { name: 'Home Goods', href: '#' }, - { name: 'Accessories', href: '#' }, - ], - company: [ - { name: 'Who we are', href: '#' }, - { name: 'Sustainability', href: '#' }, - { name: 'Press', href: '#' }, - { name: 'Careers', href: '#' }, - { name: 'Terms & Conditions', href: '#' }, - { name: 'Privacy', href: '#' }, - ], - customerService: [ - { name: 'Contact', href: '#' }, - { name: 'Shipping', href: '#' }, - { name: 'Returns', href: '#' }, - { name: 'Warranty', href: '#' }, - { name: 'Secure Payments', href: '#' }, - { name: 'FAQ', href: '#' }, - { name: 'Find a store', href: '#' }, - ], -}; diff --git a/examples/summer-sale/app/favicon.ico b/examples/summer-sale/app/favicon.ico deleted file mode 100644 index 4b98a2b..0000000 Binary files a/examples/summer-sale/app/favicon.ico and /dev/null differ diff --git a/examples/summer-sale/app/globals.css b/examples/summer-sale/app/globals.css deleted file mode 100644 index b5c61c9..0000000 --- a/examples/summer-sale/app/globals.css +++ /dev/null @@ -1,3 +0,0 @@ -@tailwind base; -@tailwind components; -@tailwind utilities; diff --git a/examples/summer-sale/components/color-picker.tsx b/examples/summer-sale/components/color-picker.tsx deleted file mode 100644 index 7d41255..0000000 --- a/examples/summer-sale/components/color-picker.tsx +++ /dev/null @@ -1,51 +0,0 @@ -'use client'; - -import clsx from 'clsx'; -import { useState } from 'react'; -import { RadioGroup } from '@headlessui/react'; -import { product } from '@/app/data'; - -export function ColorPicker() { - const [selectedColor, setSelectedColor] = useState(product.colors[0]); - - return ( -
-

Color

- - - Choose a color -
- {product.colors.map((color) => ( - - clsx( - color.selectedColor, - active && checked ? 'ring ring-offset-1' : '', - !active && checked ? 'ring-2' : '', - 'relative -m-0.5 flex cursor-pointer items-center justify-center rounded-full p-0.5 focus:outline-none', - ) - } - > - - {color.name} - - - ))} -
-
-
- ); -} diff --git a/examples/summer-sale/components/eu-flag.tsx b/examples/summer-sale/components/eu-flag.tsx deleted file mode 100644 index 76d1b8f..0000000 --- a/examples/summer-sale/components/eu-flag.tsx +++ /dev/null @@ -1,62 +0,0 @@ -export function EuFlag({ className }: { className: string }) { - return ( - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ); -} diff --git a/examples/summer-sale/components/footer.tsx b/examples/summer-sale/components/footer.tsx deleted file mode 100644 index af89fa8..0000000 --- a/examples/summer-sale/components/footer.tsx +++ /dev/null @@ -1,113 +0,0 @@ -import { ShoppingBagIcon } from '@heroicons/react/24/outline'; -import { footerNavigation } from '@/app/data'; - -export function Footer() { - return ( -
- -
-
-
- {/* Image section */} -
- -
- - {/* Sitemap sections */} -
-
-
-

- Products -

- -
-
-

Company

- -
-
-
-

- Customer Service -

- -
-
- - {/* Newsletter section */} -
-

- Sign up for our newsletter -

-

- The latest deals and savings, sent to your inbox weekly. -

-
- - -
- -
-
-
-
-
- -
-

- © 2021 Your Company, Inc. All rights reserved. -

-
-
-
- ); -} diff --git a/examples/summer-sale/components/header.tsx b/examples/summer-sale/components/header.tsx deleted file mode 100644 index 2b6071a..0000000 --- a/examples/summer-sale/components/header.tsx +++ /dev/null @@ -1,125 +0,0 @@ -'use client'; - -import { clsx } from 'clsx'; -import { Popover } from '@headlessui/react'; -import { - Bars3Icon, - MagnifyingGlassIcon, - ShoppingBagIcon, - ShoppingCartIcon, - UserIcon, -} from '@heroicons/react/24/outline'; -import { EuFlag } from './eu-flag'; -import { navigation } from '@/app/data'; - -export function Header() { - return ( -
- -
- ); -} diff --git a/examples/summer-sale/components/image-gallery.tsx b/examples/summer-sale/components/image-gallery.tsx deleted file mode 100644 index 4289787..0000000 --- a/examples/summer-sale/components/image-gallery.tsx +++ /dev/null @@ -1,74 +0,0 @@ -import clsx from 'clsx'; -import { product } from '@/app/data'; -import Image from 'next/image'; - -export function ImageGallery() { - return ( -
-

Images

- -
- {product.images.map((image) => ( - {image.imageAlt} - ))} -
-
- ); -} - -export function ImageGalleryTwoColumns() { - return ( -
-

Images

- -
- {product.images.map((image) => { - if (image.primary) return null; - return ( - {image.imageAlt} - ); - })} -
-
- ); -} - -export function ImageGalleryReversed() { - return ( -
-

Images

- -
- {product.images - .slice() - .reverse() - .map((image) => ( - {image.imageAlt} - ))} -
-
- ); -} diff --git a/examples/summer-sale/components/materials.tsx b/examples/summer-sale/components/materials.tsx deleted file mode 100644 index 2c03407..0000000 --- a/examples/summer-sale/components/materials.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { product } from '@/app/data'; - -export function Materials() { - return ( -
-

Fabric & Care

- -
-
    - {product.details.map((item) => ( -
  • {item}
  • - ))} -
-
-
- ); -} diff --git a/examples/summer-sale/components/policies.tsx b/examples/summer-sale/components/policies.tsx deleted file mode 100644 index 10bc1d1..0000000 --- a/examples/summer-sale/components/policies.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import { policies } from '@/app/data'; - -export function Policies() { - return ( -
-

- Our Policies -

- -
- {policies.map((policy) => ( -
-
-
-
{policy.description}
-
- ))} -
-
- ); -} diff --git a/examples/summer-sale/components/product-detail-reviews.tsx b/examples/summer-sale/components/product-detail-reviews.tsx deleted file mode 100644 index a69b1e5..0000000 --- a/examples/summer-sale/components/product-detail-reviews.tsx +++ /dev/null @@ -1,40 +0,0 @@ -import clsx from 'clsx'; -import { StarIcon } from '@heroicons/react/24/solid'; -import { reviews } from '@/app/data'; - -export function ProductDetailReviews() { - return ( -
-

Reviews

-
-

- {reviews.average} - out of 5 stars -

-
- {[0, 1, 2, 3, 4].map((rating) => ( - rating ? 'text-yellow-400' : 'text-gray-200', - 'h-5 w-5 flex-shrink-0', - )} - aria-hidden="true" - /> - ))} -
- - -
-
- ); -} diff --git a/examples/summer-sale/components/product-details.tsx b/examples/summer-sale/components/product-details.tsx deleted file mode 100644 index cbe984f..0000000 --- a/examples/summer-sale/components/product-details.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { product } from '@/app/data'; - -export function ProductDetails() { - return ( -
-

Description

- -
-
- ); -} diff --git a/examples/summer-sale/components/product-heading.tsx b/examples/summer-sale/components/product-heading.tsx deleted file mode 100644 index 6af3438..0000000 --- a/examples/summer-sale/components/product-heading.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import { product } from '@/app/data'; - -export function ProductHeading() { - return ( -
-

{product.name}

-

{product.price}

-
- ); -} diff --git a/examples/summer-sale/components/related-products.tsx b/examples/summer-sale/components/related-products.tsx deleted file mode 100644 index 863502f..0000000 --- a/examples/summer-sale/components/related-products.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import { relatedProducts } from '@/app/data'; -import Image from 'next/image'; - -export function RelatedProducts() { - return ( -
- - -
- {relatedProducts.map((relatedProduct) => ( -
-
- {relatedProduct.imageAlt} -
-
-
-

- - -

-

- {relatedProduct.color} -

-
-

- {relatedProduct.price} -

-
-
- ))} -
-
- ); -} diff --git a/examples/summer-sale/components/reviews.tsx b/examples/summer-sale/components/reviews.tsx deleted file mode 100644 index 27ad322..0000000 --- a/examples/summer-sale/components/reviews.tsx +++ /dev/null @@ -1,66 +0,0 @@ -import clsx from 'clsx'; -import { StarIcon } from '@heroicons/react/24/solid'; -import { reviews } from '@/app/data'; - -export function Reviews() { - return ( -
-

- Recent reviews -

- -
- {reviews.featured.map((review) => ( -
-
-
-
- {[0, 1, 2, 3, 4].map((rating) => ( - rating - ? 'text-yellow-400' - : 'text-gray-200', - 'h-5 w-5 flex-shrink-0', - )} - aria-hidden="true" - /> - ))} -
-

- {review.rating} - out of 5 stars -

-
- -
-

- {review.title} -

- -
-
-
- -
-

{review.author}

- -
-
- ))} -
-
- ); -} diff --git a/examples/summer-sale/components/size-picker.tsx b/examples/summer-sale/components/size-picker.tsx deleted file mode 100644 index 2173311..0000000 --- a/examples/summer-sale/components/size-picker.tsx +++ /dev/null @@ -1,55 +0,0 @@ -'use client'; - -import clsx from 'clsx'; -import { useState } from 'react'; -import { RadioGroup } from '@headlessui/react'; -import { product } from '@/app/data'; - -export function SizePicker() { - const [selectedSize, setSelectedSize] = useState(product.sizes[2]); - - return ( -
- - - - Choose a size -
- {product.sizes.map((size) => ( - - clsx( - size.inStock - ? 'cursor-pointer focus:outline-none' - : 'cursor-not-allowed opacity-25', - active ? 'ring-2 ring-slate-500 ring-offset-2' : '', - checked - ? 'border-transparent bg-slate-600 text-white hover:bg-slate-700' - : 'border-gray-200 bg-white text-gray-900 hover:bg-gray-50', - 'flex items-center justify-center rounded-md border py-3 px-3 text-sm font-medium uppercase sm:flex-1', - ) - } - disabled={!size.inStock} - > - {size.name} - - ))} -
-
-
- ); -} diff --git a/examples/summer-sale/components/top-banner.tsx b/examples/summer-sale/components/top-banner.tsx deleted file mode 100644 index a06a4ba..0000000 --- a/examples/summer-sale/components/top-banner.tsx +++ /dev/null @@ -1,7 +0,0 @@ -export function TopBanner() { - return ( -
- Get free delivery on orders over $100 -
- ); -} diff --git a/examples/summer-sale/flags.ts b/examples/summer-sale/flags.ts deleted file mode 100644 index 3da6677..0000000 --- a/examples/summer-sale/flags.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { flag, dedupe } from 'flags/next'; -import { getOrGenerateVisitorId } from './utils/generateVisitorId'; - -const identify = dedupe(async () => { - return { - visitor: { id: (await getOrGenerateVisitorId()).value }, - user: { - vercelian: true, - id: 'uid1', - authenticated: true, - teamIds: ['team1'], - }, - }; -}); - -export const showSummerBannerFlag = flag({ - key: 'summer-sale', - identify, - decide: async () => { - return false; - }, -}); - -export const showFreeDeliveryBannerFlag = flag({ - key: 'free-delivery', - identify, - async decide() { - return true; - }, - origin: - 'https://app.launchdarkly.com/toggle-runner-demo/production/features/free-delivery/targeting', - description: 'Show free delivery banner', - defaultValue: true, - options: [ - { value: false, label: 'Hide' }, - { value: true, label: 'Show' }, - ], -}); - -export const countryFlag = flag({ - key: 'country', - defaultValue: 'no accept-lanugage header', - async decide({ headers }) { - return headers.get('accept-language') ?? this.defaultValue!; - }, -}); - -export const precomputeFlags = [ - showFreeDeliveryBannerFlag, - showSummerBannerFlag, - countryFlag, -] as const; - -// used for the pages router example -export const bannerFlags = [showFreeDeliveryBannerFlag] as const; diff --git a/examples/summer-sale/middleware.ts b/examples/summer-sale/middleware.ts deleted file mode 100644 index 3b95729..0000000 --- a/examples/summer-sale/middleware.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { type NextRequest, NextResponse } from 'next/server'; -import { precompute } from 'flags/next'; -import { precomputeFlags, bannerFlags } from '@/flags'; -import { getOrGenerateVisitorId } from './utils/generateVisitorId'; - -export const config = { matcher: ['/', '/precomputed-pages-router-example'] }; - -export async function middleware(request: NextRequest) { - const generatedVisitorId = await getOrGenerateVisitorId(); - console.log('visitor', generatedVisitorId); - - if (request.nextUrl.pathname === '/') { - const code = await precompute(precomputeFlags); - - // rewrites the request to the variant for this flag combination - const nextUrl = new URL( - `/${code}${request.nextUrl.pathname}${request.nextUrl.search}`, - request.url, - ); - return NextResponse.rewrite(nextUrl, { - request, - headers: generatedVisitorId.fresh - ? { 'set-cookie': `visitor-id=${generatedVisitorId.value}` } - : undefined, - }); - } - - if (request.nextUrl.pathname === '/precomputed-pages-router-example') { - const code = await precompute(bannerFlags); - - // rewrites the request to the variant for this flag combination - const nextUrl = new URL( - `/${code}${request.nextUrl.pathname}${request.nextUrl.search}`, - request.url, - ); - return NextResponse.rewrite(nextUrl, { request }); - } -} diff --git a/examples/summer-sale/package.json b/examples/summer-sale/package.json deleted file mode 100644 index 706fb55..0000000 --- a/examples/summer-sale/package.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "name": "summer-sale", - "version": "0.1.7", - "private": true, - "scripts": { - "build": "next build", - "dev": "next dev", - "lint": "next lint", - "start": "next start" - }, - "dependencies": { - "@headlessui/react": "1.7.19", - "@heroicons/react": "2.1.1", - "@tailwindcss/aspect-ratio": "0.4.2", - "@tailwindcss/forms": "0.5.7", - "@tailwindcss/typography": "0.5.10", - "@vercel/analytics": "https://vercel-analytics-package-ayb1ll9cs.vercel.online/index.tgz", - "@vercel/edge": "1.1.1", - "@vercel/edge-config": "1.2.0", - "@vercel/toolbar": "0.1.14", - "clsx": "2.0.0", - "flags": "workspace:*", - "nanoid": "5.0.7", - "next": "15.0.3", - "react": "^18", - "react-dom": "^18" - }, - "devDependencies": { - "@types/node": "^20", - "@types/react": "^18", - "@types/react-dom": "^18", - "postcss": "^8", - "tailwindcss": "^3.4.1", - "typescript": "^5" - } -} diff --git a/examples/summer-sale/public/next.svg b/examples/summer-sale/public/next.svg deleted file mode 100644 index 5174b28..0000000 --- a/examples/summer-sale/public/next.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/examples/summer-sale/public/product-page-0.jpg b/examples/summer-sale/public/product-page-0.jpg deleted file mode 100644 index effda02..0000000 Binary files a/examples/summer-sale/public/product-page-0.jpg and /dev/null differ diff --git a/examples/summer-sale/public/product-page-1.jpg b/examples/summer-sale/public/product-page-1.jpg deleted file mode 100644 index 256cc64..0000000 Binary files a/examples/summer-sale/public/product-page-1.jpg and /dev/null differ diff --git a/examples/summer-sale/public/product-page-2.jpg b/examples/summer-sale/public/product-page-2.jpg deleted file mode 100644 index cf0b93a..0000000 Binary files a/examples/summer-sale/public/product-page-2.jpg and /dev/null differ diff --git a/examples/summer-sale/public/product-related-0.jpg b/examples/summer-sale/public/product-related-0.jpg deleted file mode 100644 index 24379f1..0000000 Binary files a/examples/summer-sale/public/product-related-0.jpg and /dev/null differ diff --git a/examples/summer-sale/public/vercel.svg b/examples/summer-sale/public/vercel.svg deleted file mode 100644 index d2f8422..0000000 --- a/examples/summer-sale/public/vercel.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/examples/summer-sale/utils/generateVisitorId.ts b/examples/summer-sale/utils/generateVisitorId.ts deleted file mode 100644 index c7497b3..0000000 --- a/examples/summer-sale/utils/generateVisitorId.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { cookies } from 'next/headers'; -import { dedupe } from 'flags/next'; -import { nanoid } from 'nanoid'; - -/** - * Reads the visitor id from the cookie or returns a new visitor id - */ -export const getOrGenerateVisitorId = dedupe(async () => { - const cookiesStore = await cookies(); - const visitorId = cookiesStore.get('visitor-id')?.value; - if (!visitorId) return { value: nanoid(), fresh: true }; - return { value: visitorId, fresh: false }; -}); diff --git a/package.json b/package.json index be7fdb4..914d99e 100644 --- a/package.json +++ b/package.json @@ -24,8 +24,8 @@ "prettier-fix": "prettier --write .", "publint": "turbo publint", "release": "pnpm build && changeset publish", + "shirt-shop": "pnpm dev -F shirt-shop", "snippets": "pnpm dev -F snippets", - "summer-sale": "pnpm dev -F summer-sale", "svelte": "pnpm dev -F svelte-example", "test": "turbo test", "test:e2e": "turbo test:e2e", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0cb63aa..b13a463 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -51,6 +51,82 @@ importers: specifier: ^5.3.3 version: 5.6.3 + examples/shirt-shop: + dependencies: + '@headlessui/react': + specifier: ^2.2.0 + version: 2.2.0(react-dom@19.0.0)(react@19.0.0) + '@heroicons/react': + specifier: 2.2.0 + version: 2.2.0(react@19.0.0) + '@tailwindcss/aspect-ratio': + specifier: 0.4.2 + version: 0.4.2(tailwindcss@4.0.9) + '@tailwindcss/forms': + specifier: 0.5.10 + version: 0.5.10(tailwindcss@4.0.9) + '@tailwindcss/postcss': + specifier: ^4.0.8 + version: 4.0.9 + '@tailwindcss/typography': + specifier: 0.5.16 + version: 0.5.16(tailwindcss@4.0.9) + '@vercel/analytics': + specifier: 1.5.0 + version: 1.5.0(next@15.1.7)(react@19.0.0) + '@vercel/edge': + specifier: 1.2.1 + version: 1.2.1 + '@vercel/edge-config': + specifier: 1.4.0 + version: 1.4.0 + '@vercel/toolbar': + specifier: 0.1.33 + version: 0.1.33(@vercel/analytics@1.5.0)(next@15.1.7)(react-dom@19.0.0)(react@19.0.0) + clsx: + specifier: 2.1.1 + version: 2.1.1 + flags: + specifier: workspace:* + version: link:../../packages/flags + js-xxhash: + specifier: 4.0.0 + version: 4.0.0 + nanoid: + specifier: 5.1.2 + version: 5.1.2 + next: + specifier: 15.1.7 + version: 15.1.7(@babel/core@7.26.9)(react-dom@19.0.0)(react@19.0.0) + react: + specifier: ^19.0.0 + version: 19.0.0 + react-dom: + specifier: ^19.0.0 + version: 19.0.0(react@19.0.0) + devDependencies: + '@types/node': + specifier: ^22.13.5 + version: 22.13.5 + '@types/react': + specifier: ^19.0.10 + version: 19.0.10 + '@types/react-dom': + specifier: ^19.0.4 + version: 19.0.4(@types/react@19.0.10) + eslint: + specifier: ^9.21.0 + version: 9.21.0 + postcss: + specifier: ^8.5.3 + version: 8.5.3 + tailwindcss: + specifier: ^4.0.8 + version: 4.0.9 + typescript: + specifier: ^5.7.3 + version: 5.7.3 + examples/snippets: dependencies: '@radix-ui/react-dialog': @@ -134,6 +210,76 @@ importers: version: 5.6.3 examples/summer-sale: + dependencies: + '@headlessui/react': + specifier: ^2.2.0 + version: 2.2.0(react-dom@19.0.0)(react@19.0.0) + '@heroicons/react': + specifier: 2.2.0 + version: 2.2.0(react@19.0.0) + '@tailwindcss/aspect-ratio': + specifier: 0.4.2 + version: 0.4.2(tailwindcss@4.0.9) + '@tailwindcss/forms': + specifier: 0.5.10 + version: 0.5.10(tailwindcss@4.0.9) + '@tailwindcss/postcss': + specifier: ^4.0.8 + version: 4.0.9 + '@tailwindcss/typography': + specifier: 0.5.16 + version: 0.5.16(tailwindcss@4.0.9) + '@vercel/edge': + specifier: 1.2.1 + version: 1.2.1 + '@vercel/edge-config': + specifier: 1.4.0 + version: 1.4.0 + '@vercel/toolbar': + specifier: 0.1.33 + version: 0.1.33(next@15.1.7)(react-dom@19.0.0)(react@19.0.0) + clsx: + specifier: 2.1.1 + version: 2.1.1 + flags: + specifier: workspace:* + version: link:../../packages/flags + nanoid: + specifier: 5.1.2 + version: 5.1.2 + next: + specifier: 15.1.7 + version: 15.1.7(@babel/core@7.26.9)(react-dom@19.0.0)(react@19.0.0) + react: + specifier: ^19.0.0 + version: 19.0.0 + react-dom: + specifier: ^19.0.0 + version: 19.0.0(react@19.0.0) + devDependencies: + '@types/node': + specifier: ^22.13.5 + version: 22.13.5 + '@types/react': + specifier: ^19.0.10 + version: 19.0.10 + '@types/react-dom': + specifier: ^19.0.4 + version: 19.0.4(@types/react@19.0.10) + eslint: + specifier: ^9.21.0 + version: 9.21.0 + postcss: + specifier: ^8.5.3 + version: 8.5.3 + tailwindcss: + specifier: ^4.0.8 + version: 4.0.9 + typescript: + specifier: ^5.7.3 + version: 5.7.3 + + examples/summer-sale-orig: dependencies: '@headlessui/react': specifier: 1.7.19 @@ -198,7 +344,7 @@ importers: version: 3.4.17 typescript: specifier: ^5 - version: 5.6.3 + version: 5.7.3 examples/sveltekit-example: dependencies: @@ -278,7 +424,7 @@ importers: dependencies: '@happykit/flags': specifier: 3.3.0 - version: 3.3.0(next@15.1.4)(react@18.3.1) + version: 3.3.0(next@15.1.7)(react@19.0.0) devDependencies: '@types/node': specifier: 20.11.17 @@ -508,7 +654,7 @@ importers: version: 5.10.0 react-dom: specifier: '*' - version: 18.3.1(react@19.1.0-canary-22e39ea7-20250225) + version: 18.3.1(react@19.1.0-canary-ebc22ef7-20250225) devDependencies: '@arethetypeswrong/cli': specifier: 0.17.3 @@ -530,10 +676,10 @@ importers: version: 2.6.4(@types/node@20.11.17)(typescript@5.6.3) next: specifier: 15.1.4 - version: 15.1.4(@babel/core@7.26.9)(@opentelemetry/api@1.9.0)(react-dom@18.3.1)(react@19.1.0-canary-22e39ea7-20250225) + version: 15.1.4(@babel/core@7.26.9)(@opentelemetry/api@1.9.0)(react-dom@18.3.1)(react@19.1.0-canary-ebc22ef7-20250225) react: specifier: canary - version: 19.1.0-canary-22e39ea7-20250225 + version: 19.1.0-canary-ebc22ef7-20250225 tsconfig: specifier: workspace:* version: link:../../tooling/tsconfig @@ -1537,12 +1683,39 @@ packages: dependencies: eslint: 8.56.0 eslint-visitor-keys: 3.4.3 + + /@eslint-community/eslint-utils@4.4.1(eslint@9.21.0): + resolution: {integrity: sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + dependencies: + eslint: 9.21.0 + eslint-visitor-keys: 3.4.3 dev: true /@eslint-community/regexpp@4.12.1: resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + /@eslint/config-array@0.19.2: + resolution: {integrity: sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + dependencies: + '@eslint/object-schema': 2.1.6 + debug: 4.4.0 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@eslint/core@0.12.0: + resolution: {integrity: sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + dependencies: + '@types/json-schema': 7.0.15 + dev: true + /@eslint/eslintrc@2.1.4: resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -1559,6 +1732,23 @@ packages: transitivePeerDependencies: - supports-color + /@eslint/eslintrc@3.3.0: + resolution: {integrity: sha512-yaVPAiNAalnCZedKLdR21GOGILMLKPyqSLWaAjQFvYA2i/ciDi8ArYVr69Anohb6cH2Ukhqti4aFnYyPm8wdwQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + dependencies: + ajv: 6.12.6 + debug: 4.4.0 + espree: 10.3.0 + globals: 14.0.0 + ignore: 5.3.2 + import-fresh: 3.3.1 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + dev: true + /@eslint/js@8.48.0: resolution: {integrity: sha512-ZSjtmelB7IJfWD2Fvb7+Z+ChTIKWq6kjda95fLcQKNS5aheVHn4IkfgRQE3sIIzTcSLwLcLZUD9UBt+V7+h+Pw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -1566,6 +1756,23 @@ packages: /@eslint/js@8.56.0: resolution: {integrity: sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + /@eslint/js@9.21.0: + resolution: {integrity: sha512-BqStZ3HX8Yz6LvsF5ByXYrtigrV5AXADWLAGc7PH/1SxOb7/FIYYMszZZWiUou/GB9P2lXWk2SV4d+Z8h0nknw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + dev: true + + /@eslint/object-schema@2.1.6: + resolution: {integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + dev: true + + /@eslint/plugin-kit@0.2.7: + resolution: {integrity: sha512-JubJ5B2pJ4k4yGxaNLdbjrnk9d/iDz6/q8wOilpIowd6PJPgaxCuHBnBszq7Ce2TyMrywm5r4PnKm6V3iiZF+g==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + dependencies: + '@eslint/core': 0.12.0 + levn: 0.4.1 dev: true /@floating-ui/core@1.6.9: @@ -1581,6 +1788,17 @@ packages: '@floating-ui/utils': 0.2.9 dev: false + /@floating-ui/react-dom@2.1.2(react-dom@19.0.0)(react@19.0.0): + resolution: {integrity: sha512-06okr5cgPzMNBy+Ycse2A6udMi4bqwW/zgBF/rwjcNqWkyr82Mcg8b0vjX8OJpZFy/FKjJmw6wV7t44kK6kW7A==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + dependencies: + '@floating-ui/dom': 1.6.13 + react: 19.0.0 + react-dom: 19.0.0(react@19.0.0) + dev: false + /@floating-ui/react-dom@2.1.2(react-dom@19.0.0-rc-02c0e824-20241028)(react@19.0.0-rc-02c0e824-20241028): resolution: {integrity: sha512-06okr5cgPzMNBy+Ycse2A6udMi4bqwW/zgBF/rwjcNqWkyr82Mcg8b0vjX8OJpZFy/FKjJmw6wV7t44kK6kW7A==} peerDependencies: @@ -1592,19 +1810,32 @@ packages: react-dom: 19.0.0-rc-02c0e824-20241028(react@19.0.0-rc-02c0e824-20241028) dev: false + /@floating-ui/react@0.26.28(react-dom@19.0.0)(react@19.0.0): + resolution: {integrity: sha512-yORQuuAtVpiRjpMhdc0wJj06b9JFjrYF4qp96j++v2NBpbi6SEGF7donUJ3TMieerQ6qVkAv1tgr7L4r5roTqw==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + dependencies: + '@floating-ui/react-dom': 2.1.2(react-dom@19.0.0)(react@19.0.0) + '@floating-ui/utils': 0.2.9 + react: 19.0.0 + react-dom: 19.0.0(react@19.0.0) + tabbable: 6.2.0 + dev: false + /@floating-ui/utils@0.2.9: resolution: {integrity: sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==} dev: false - /@happykit/flags@3.3.0(next@15.1.4)(react@18.3.1): + /@happykit/flags@3.3.0(next@15.1.7)(react@19.0.0): resolution: {integrity: sha512-QyywkKYctdo0bnNf+bBd+3B/3Rsnjdaz+jtVA+jSqLxm0/lw51Z1+q2sEfc62MyNwQnY6w7eqajdwhuvH3VWAw==} peerDependencies: next: '>=12.0.2' react: '>=16.13.1' dependencies: nanoid: 3.2.0 - next: 15.1.4(@babel/core@7.26.9)(react-dom@18.3.1)(react@18.3.1) - react: 18.3.1 + next: 15.1.7(@babel/core@7.26.9)(react-dom@19.0.0)(react@19.0.0) + react: 19.0.0 dev: false /@headlessui/react@1.7.19(react-dom@18.3.1)(react@18.3.1): @@ -1620,6 +1851,21 @@ packages: react-dom: 18.3.1(react@18.3.1) dev: false + /@headlessui/react@2.2.0(react-dom@19.0.0)(react@19.0.0): + resolution: {integrity: sha512-RzCEg+LXsuI7mHiSomsu/gBJSjpupm6A1qIZ5sWjd7JhARNlMiSA4kKfJpCKwU9tE+zMRterhhrP74PvfJrpXQ==} + engines: {node: '>=10'} + peerDependencies: + react: ^18 || ^19 || ^19.0.0-rc + react-dom: ^18 || ^19 || ^19.0.0-rc + dependencies: + '@floating-ui/react': 0.26.28(react-dom@19.0.0)(react@19.0.0) + '@react-aria/focus': 3.19.1(react-dom@19.0.0)(react@19.0.0) + '@react-aria/interactions': 3.23.0(react-dom@19.0.0)(react@19.0.0) + '@tanstack/react-virtual': 3.13.2(react-dom@19.0.0)(react@19.0.0) + react: 19.0.0 + react-dom: 19.0.0(react@19.0.0) + dev: false + /@heroicons/react@2.1.1(react@18.3.1): resolution: {integrity: sha512-JyyN9Lo66kirbCMuMMRPtJxtKJoIsXKS569ebHGGRKbl8s4CtUfLnyKJxteA+vIKySocO4s1SkTkGS4xtG/yEA==} peerDependencies: @@ -1628,6 +1874,27 @@ packages: react: 18.3.1 dev: false + /@heroicons/react@2.2.0(react@19.0.0): + resolution: {integrity: sha512-LMcepvRaS9LYHJGsF0zzmgKCUim/X3N/DQKc4jepAXJ7l8QxJ1PmxJzqplF2Z3FE4PqBAIGyJAQ/w4B5dsqbtQ==} + peerDependencies: + react: '>= 16 || ^19.0.0-rc' + dependencies: + react: 19.0.0 + dev: false + + /@humanfs/core@0.19.1: + resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} + engines: {node: '>=18.18.0'} + dev: true + + /@humanfs/node@0.16.6: + resolution: {integrity: sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==} + engines: {node: '>=18.18.0'} + dependencies: + '@humanfs/core': 0.19.1 + '@humanwhocodes/retry': 0.3.1 + dev: true + /@humanwhocodes/config-array@0.11.14: resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} engines: {node: '>=10.10.0'} @@ -1647,6 +1914,16 @@ packages: resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} deprecated: Use @eslint/object-schema instead + /@humanwhocodes/retry@0.3.1: + resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==} + engines: {node: '>=18.18'} + dev: true + + /@humanwhocodes/retry@0.4.2: + resolution: {integrity: sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==} + engines: {node: '>=18.18'} + dev: true + /@img/sharp-darwin-arm64@0.33.5: resolution: {integrity: sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} @@ -2167,6 +2444,10 @@ packages: /@next/env@15.1.4: resolution: {integrity: sha512-2fZ5YZjedi5AGaeoaC0B20zGntEHRhi2SdWcu61i48BllODcAmmtj8n7YarSPt4DaTsJaBFdxQAVEVzgmx2Zpw==} + /@next/env@15.1.7: + resolution: {integrity: sha512-d9jnRrkuOH7Mhi+LHav2XW91HOgTAWHxjMPkXMGBc9B2b7614P7kjt8tAplRvJpbSt4nbO1lugcT/kAaWzjlLQ==} + dev: false + /@next/env@15.2.0-canary.3: resolution: {integrity: sha512-bgw4ccAnA84CyXS0L0pR25Yoj/hbo9UtwaGw7KvQW75xAf4qDN49r/MpnHPkrcG/I8JTkTjlynD4EMjEyVDkVg==} dev: false @@ -2212,6 +2493,15 @@ packages: requiresBuild: true optional: true + /@next/swc-darwin-arm64@15.1.7: + resolution: {integrity: sha512-hPFwzPJDpA8FGj7IKV3Yf1web3oz2YsR8du4amKw8d+jAOHfYHYFpMkoF6vgSY4W6vB29RtZEklK9ayinGiCmQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + /@next/swc-darwin-arm64@15.2.0-canary.3: resolution: {integrity: sha512-AZGuB/GhadqgObOWaCcl/D8FmUK9cjwXEInpOzDYcGIlSVfJxFuGd9Mveb4M96wmTk/AI7ypPkVAsu1UXLys6A==} engines: {node: '>= 10'} @@ -2256,6 +2546,15 @@ packages: requiresBuild: true optional: true + /@next/swc-darwin-x64@15.1.7: + resolution: {integrity: sha512-2qoas+fO3OQKkU0PBUfwTiw/EYpN+kdAx62cePRyY1LqKtP09Vp5UcUntfZYajop5fDFTjSxCHfZVRxzi+9FYQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + /@next/swc-darwin-x64@15.2.0-canary.3: resolution: {integrity: sha512-WgXW82ZAUUlX4qj6xAXXDXt6KeZfe6euLL/MS0aTkz94dX31WQPC6yUTsXTiYn761D553mtS74lTeD2ZaerazA==} engines: {node: '>= 10'} @@ -2300,6 +2599,15 @@ packages: requiresBuild: true optional: true + /@next/swc-linux-arm64-gnu@15.1.7: + resolution: {integrity: sha512-sKLLwDX709mPdzxMnRIXLIT9zaX2w0GUlkLYQnKGoXeWUhcvpCrK+yevcwCJPdTdxZEUA0mOXGLdPsGkudGdnA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + /@next/swc-linux-arm64-gnu@15.2.0-canary.3: resolution: {integrity: sha512-T0XTeo6ZLTK86BHvnJBPdjotuGFPYz6wT+Q/m2DCnhcFM1NwTcOH5VPuI46XRTEtmGPw+pbiIA89yHqy33jGSA==} engines: {node: '>= 10'} @@ -2344,6 +2652,15 @@ packages: requiresBuild: true optional: true + /@next/swc-linux-arm64-musl@15.1.7: + resolution: {integrity: sha512-zblK1OQbQWdC8fxdX4fpsHDw+VSpBPGEUX4PhSE9hkaWPrWoeIJn+baX53vbsbDRaDKd7bBNcXRovY1hEhFd7w==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + /@next/swc-linux-arm64-musl@15.2.0-canary.3: resolution: {integrity: sha512-x6m3CwWppaLdbmLuO5PRt3/jVCPdTd98ToNf7dltiotFK6JYCOdVChiwXyG6l4ArgSQuRmgK8FrMvzzQswbwYA==} engines: {node: '>= 10'} @@ -2388,6 +2705,15 @@ packages: requiresBuild: true optional: true + /@next/swc-linux-x64-gnu@15.1.7: + resolution: {integrity: sha512-GOzXutxuLvLHFDAPsMP2zDBMl1vfUHHpdNpFGhxu90jEzH6nNIgmtw/s1MDwpTOiM+MT5V8+I1hmVFeAUhkbgQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + /@next/swc-linux-x64-gnu@15.2.0-canary.3: resolution: {integrity: sha512-Yc02PyDtPX4QpbbxYEOlFRIMR2Zab1PlbRU1aZqhmMChuuB+imGx9G6DihMnZLEx4pTG2q2bTUBBgRyqQoruGw==} engines: {node: '>= 10'} @@ -2432,6 +2758,15 @@ packages: requiresBuild: true optional: true + /@next/swc-linux-x64-musl@15.1.7: + resolution: {integrity: sha512-WrZ7jBhR7ATW1z5iEQ0ZJfE2twCNSXbpCSaAunF3BKcVeHFADSI/AW1y5Xt3DzTqPF1FzQlwQTewqetAABhZRQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + /@next/swc-linux-x64-musl@15.2.0-canary.3: resolution: {integrity: sha512-gjD6p3N3UDIJzuE7pgfMdSt+GDvEeR/Ij5uArbXZ87NPLqSzSWo76cX+TLjJ/23zXoMy/5WbjfD3XoWQU47pHQ==} engines: {node: '>= 10'} @@ -2476,6 +2811,15 @@ packages: requiresBuild: true optional: true + /@next/swc-win32-arm64-msvc@15.1.7: + resolution: {integrity: sha512-LDnj1f3OVbou1BqvvXVqouJZKcwq++mV2F+oFHptToZtScIEnhNRJAhJzqAtTE2dB31qDYL45xJwrc+bLeKM2Q==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: false + optional: true + /@next/swc-win32-arm64-msvc@15.2.0-canary.3: resolution: {integrity: sha512-TjF1jb/bE+0yvHcxUqvXN/iEY/AnwQzIviqeksKnSPNCVWvOV5I6QHke9rdT0SprOlYJJ3Mp/m60hg4mcdEuiw==} engines: {node: '>= 10'} @@ -2538,6 +2882,15 @@ packages: requiresBuild: true optional: true + /@next/swc-win32-x64-msvc@15.1.7: + resolution: {integrity: sha512-dC01f1quuf97viOfW05/K8XYv2iuBgAxJZl7mbCKEjMgdQl5JjAKJ0D2qMKZCgPWDeFbFT0Q0nYWwytEW0DWTQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: false + optional: true + /@next/swc-win32-x64-msvc@15.2.0-canary.3: resolution: {integrity: sha512-DpmSW5JCnWwPhYnCTc0Bj9w+//Klk5pKJUBq7fQxTpSUD+uKmBOpLjXGY1jzhclBerroDNDMXHd4zCv+BsUzfg==} engines: {node: '>= 10'} @@ -2667,7 +3020,7 @@ packages: resolution: {integrity: sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==} peerDependencies: '@types/react': '*' - react: 19.0.0-rc-380f5d67-20241113 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc peerDependenciesMeta: '@types/react': optional: true @@ -2942,7 +3295,7 @@ packages: resolution: {integrity: sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==} peerDependencies: '@types/react': '*' - react: 19.0.0-rc.0 || 19.0.0-beta-4508873393-20240430 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc peerDependenciesMeta: '@types/react': optional: true @@ -2983,7 +3336,7 @@ packages: resolution: {integrity: sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==} peerDependencies: '@types/react': '*' - react: 19.0.0-rc.0 || 19.0.0-beta-4508873393-20240430 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc peerDependenciesMeta: '@types/react': optional: true @@ -3044,6 +3397,77 @@ packages: resolution: {integrity: sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg==} dev: false + /@react-aria/focus@3.19.1(react-dom@19.0.0)(react@19.0.0): + resolution: {integrity: sha512-bix9Bu1Ue7RPcYmjwcjhB14BMu2qzfJ3tMQLqDc9pweJA66nOw8DThy3IfVr8Z7j2PHktOLf9kcbiZpydKHqzg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + dependencies: + '@react-aria/interactions': 3.23.0(react-dom@19.0.0)(react@19.0.0) + '@react-aria/utils': 3.27.0(react-dom@19.0.0)(react@19.0.0) + '@react-types/shared': 3.27.0(react@19.0.0) + '@swc/helpers': 0.5.15 + clsx: 2.1.1 + react: 19.0.0 + react-dom: 19.0.0(react@19.0.0) + dev: false + + /@react-aria/interactions@3.23.0(react-dom@19.0.0)(react@19.0.0): + resolution: {integrity: sha512-0qR1atBIWrb7FzQ+Tmr3s8uH5mQdyRH78n0krYaG8tng9+u1JlSi8DGRSaC9ezKyNB84m7vHT207xnHXGeJ3Fg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + dependencies: + '@react-aria/ssr': 3.9.7(react@19.0.0) + '@react-aria/utils': 3.27.0(react-dom@19.0.0)(react@19.0.0) + '@react-types/shared': 3.27.0(react@19.0.0) + '@swc/helpers': 0.5.15 + react: 19.0.0 + react-dom: 19.0.0(react@19.0.0) + dev: false + + /@react-aria/ssr@3.9.7(react@19.0.0): + resolution: {integrity: sha512-GQygZaGlmYjmYM+tiNBA5C6acmiDWF52Nqd40bBp0Znk4M4hP+LTmI0lpI1BuKMw45T8RIhrAsICIfKwZvi2Gg==} + engines: {node: '>= 12'} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + dependencies: + '@swc/helpers': 0.5.15 + react: 19.0.0 + dev: false + + /@react-aria/utils@3.27.0(react-dom@19.0.0)(react@19.0.0): + resolution: {integrity: sha512-p681OtApnKOdbeN8ITfnnYqfdHS0z7GE+4l8EXlfLnr70Rp/9xicBO6d2rU+V/B3JujDw2gPWxYKEnEeh0CGCw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + dependencies: + '@react-aria/ssr': 3.9.7(react@19.0.0) + '@react-stately/utils': 3.10.5(react@19.0.0) + '@react-types/shared': 3.27.0(react@19.0.0) + '@swc/helpers': 0.5.15 + clsx: 2.1.1 + react: 19.0.0 + react-dom: 19.0.0(react@19.0.0) + dev: false + + /@react-stately/utils@3.10.5(react@19.0.0): + resolution: {integrity: sha512-iMQSGcpaecghDIh3mZEpZfoFH3ExBwTtuBEcvZ2XnGzCgQjeYXcMdIUwAfVQLXFTdHUHGF6Gu6/dFrYsCzySBQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + dependencies: + '@swc/helpers': 0.5.15 + react: 19.0.0 + dev: false + + /@react-types/shared@3.27.0(react@19.0.0): + resolution: {integrity: sha512-gvznmLhi6JPEf0bsq7SwRYTHAKKq/wcmKqFez9sRdbED+SPMUmK5omfZ6w3EwUFQHbYUa4zPBYedQ7Knv70RMw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + dependencies: + react: 19.0.0 + dev: false + /@rollup/rollup-android-arm-eabi@4.34.8: resolution: {integrity: sha512-q217OSE8DTp8AFHuNHXo0Y86e1wtlfVrXiAlwkIvGRQv9zbc6mE3sjIVfwI8sYUyNxwOg0j/Vm1RKM04JcWLJw==} cpu: [arm] @@ -3269,7 +3693,7 @@ packages: set-cookie-parser: 2.7.1 sirv: 3.0.1 svelte: 4.2.19 - vite: 5.1.1(@types/node@20.11.17) + vite: 5.1.1(@types/node@22.9.0) /@sveltejs/vite-plugin-svelte-inspector@2.1.0(@sveltejs/vite-plugin-svelte@3.1.2)(svelte@4.2.19)(vite@5.1.1): resolution: {integrity: sha512-9QX28IymvBlSCqsCll5t0kQVxipsfhFFL+L2t3nTWfXnddYwxBuAEtTtlaVQpRz9c37BhJjltSeY4AJSC03SSg==} @@ -3282,7 +3706,7 @@ packages: '@sveltejs/vite-plugin-svelte': 3.1.2(svelte@4.2.19)(vite@5.1.1) debug: 4.4.0 svelte: 4.2.19 - vite: 5.1.1(@types/node@20.11.17) + vite: 5.1.1(@types/node@22.9.0) transitivePeerDependencies: - supports-color @@ -3300,7 +3724,7 @@ packages: magic-string: 0.30.17 svelte: 4.2.19 svelte-hmr: 0.16.0(svelte@4.2.19) - vite: 5.1.1(@types/node@20.11.17) + vite: 5.1.1(@types/node@22.9.0) vitefu: 0.2.5(vite@5.1.1) transitivePeerDependencies: - supports-color @@ -3340,6 +3764,23 @@ packages: tailwindcss: 3.4.17 dev: false + /@tailwindcss/aspect-ratio@0.4.2(tailwindcss@4.0.9): + resolution: {integrity: sha512-8QPrypskfBa7QIMuKHg2TA7BqES6vhBrDLOv8Unb6FcFyd3TjKbc6lcmb9UPQHxfl24sXoJ41ux/H7qQQvfaSQ==} + peerDependencies: + tailwindcss: '>=2.0.0 || >=3.0.0 || >=3.0.0-alpha.1' + dependencies: + tailwindcss: 4.0.9 + dev: false + + /@tailwindcss/forms@0.5.10(tailwindcss@4.0.9): + resolution: {integrity: sha512-utI1ONF6uf/pPNO68kmN1b8rEwNXv3czukalo8VtJH8ksIkZXr3Q3VYudZLkCsDd4Wku120uF02hYK25XGPorw==} + peerDependencies: + tailwindcss: '>=3.0.0 || >= 3.0.0-alpha.1 || >= 4.0.0-alpha.20 || >= 4.0.0-beta.1' + dependencies: + mini-svg-data-uri: 1.4.4 + tailwindcss: 4.0.9 + dev: false + /@tailwindcss/forms@0.5.7(tailwindcss@3.4.17): resolution: {integrity: sha512-QE7X69iQI+ZXwldE+rzasvbJiyV/ju1FGHH0Qn2W3FKbuYtqp8LKcy6iSw79fVUT5/Vvf+0XgLCeYVG+UV6hOw==} peerDependencies: @@ -3349,6 +3790,141 @@ packages: tailwindcss: 3.4.17 dev: false + /@tailwindcss/node@4.0.9: + resolution: {integrity: sha512-tOJvdI7XfJbARYhxX+0RArAhmuDcczTC46DGCEziqxzzbIaPnfYaIyRT31n4u8lROrsO7Q6u/K9bmQHL2uL1bQ==} + dependencies: + enhanced-resolve: 5.18.1 + jiti: 2.4.2 + tailwindcss: 4.0.9 + dev: false + + /@tailwindcss/oxide-android-arm64@4.0.9: + resolution: {integrity: sha512-YBgy6+2flE/8dbtrdotVInhMVIxnHJPbAwa7U1gX4l2ThUIaPUp18LjB9wEH8wAGMBZUb//SzLtdXXNBHPUl6Q==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: false + optional: true + + /@tailwindcss/oxide-darwin-arm64@4.0.9: + resolution: {integrity: sha512-pWdl4J2dIHXALgy2jVkwKBmtEb73kqIfMpYmcgESr7oPQ+lbcQ4+tlPeVXaSAmang+vglAfFpXQCOvs/aGSqlw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@tailwindcss/oxide-darwin-x64@4.0.9: + resolution: {integrity: sha512-4Dq3lKp0/C7vrRSkNPtBGVebEyWt9QPPlQctxJ0H3MDyiQYvzVYf8jKow7h5QkWNe8hbatEqljMj/Y0M+ERYJg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@tailwindcss/oxide-freebsd-x64@4.0.9: + resolution: {integrity: sha512-k7U1RwRODta8x0uealtVt3RoWAWqA+D5FAOsvVGpYoI6ObgmnzqWW6pnVwz70tL8UZ/QXjeMyiICXyjzB6OGtQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: false + optional: true + + /@tailwindcss/oxide-linux-arm-gnueabihf@4.0.9: + resolution: {integrity: sha512-NDDjVweHz2zo4j+oS8y3KwKL5wGCZoXGA9ruJM982uVJLdsF8/1AeKvUwKRlMBpxHt1EdWJSAh8a0Mfhl28GlQ==} + engines: {node: '>= 10'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@tailwindcss/oxide-linux-arm64-gnu@4.0.9: + resolution: {integrity: sha512-jk90UZ0jzJl3Dy1BhuFfRZ2KP9wVKMXPjmCtY4U6fF2LvrjP5gWFJj5VHzfzHonJexjrGe1lMzgtjriuZkxagg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@tailwindcss/oxide-linux-arm64-musl@4.0.9: + resolution: {integrity: sha512-3eMjyTC6HBxh9nRgOHzrc96PYh1/jWOwHZ3Kk0JN0Kl25BJ80Lj9HEvvwVDNTgPg154LdICwuFLuhfgH9DULmg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@tailwindcss/oxide-linux-x64-gnu@4.0.9: + resolution: {integrity: sha512-v0D8WqI/c3WpWH1kq/HP0J899ATLdGZmENa2/emmNjubT0sWtEke9W9+wXeEoACuGAhF9i3PO5MeyditpDCiWQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@tailwindcss/oxide-linux-x64-musl@4.0.9: + resolution: {integrity: sha512-Kvp0TCkfeXyeehqLJr7otsc4hd/BUPfcIGrQiwsTVCfaMfjQZCG7DjI+9/QqPZha8YapLA9UoIcUILRYO7NE1Q==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@tailwindcss/oxide-win32-arm64-msvc@4.0.9: + resolution: {integrity: sha512-m3+60T/7YvWekajNq/eexjhV8z10rswcz4BC9bioJ7YaN+7K8W2AmLmG0B79H14m6UHE571qB0XsPus4n0QVgQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@tailwindcss/oxide-win32-x64-msvc@4.0.9: + resolution: {integrity: sha512-dpc05mSlqkwVNOUjGu/ZXd5U1XNch1kHFJ4/cHkZFvaW1RzbHmRt24gvM8/HC6IirMxNarzVw4IXVtvrOoZtxA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@tailwindcss/oxide@4.0.9: + resolution: {integrity: sha512-eLizHmXFqHswJONwfqi/WZjtmWZpIalpvMlNhTM99/bkHtUs6IqgI1XQ0/W5eO2HiRQcIlXUogI2ycvKhVLNcA==} + engines: {node: '>= 10'} + optionalDependencies: + '@tailwindcss/oxide-android-arm64': 4.0.9 + '@tailwindcss/oxide-darwin-arm64': 4.0.9 + '@tailwindcss/oxide-darwin-x64': 4.0.9 + '@tailwindcss/oxide-freebsd-x64': 4.0.9 + '@tailwindcss/oxide-linux-arm-gnueabihf': 4.0.9 + '@tailwindcss/oxide-linux-arm64-gnu': 4.0.9 + '@tailwindcss/oxide-linux-arm64-musl': 4.0.9 + '@tailwindcss/oxide-linux-x64-gnu': 4.0.9 + '@tailwindcss/oxide-linux-x64-musl': 4.0.9 + '@tailwindcss/oxide-win32-arm64-msvc': 4.0.9 + '@tailwindcss/oxide-win32-x64-msvc': 4.0.9 + dev: false + + /@tailwindcss/postcss@4.0.9: + resolution: {integrity: sha512-BT/E+pdMqulavEAVM5NCpxmGEwHiLDPpkmg/c/X25ZBW+izTe+aZ+v1gf/HXTrihRoCxrUp5U4YyHsBTzspQKQ==} + dependencies: + '@alloc/quick-lru': 5.2.0 + '@tailwindcss/node': 4.0.9 + '@tailwindcss/oxide': 4.0.9 + lightningcss: 1.29.1 + postcss: 8.5.3 + tailwindcss: 4.0.9 + dev: false + /@tailwindcss/typography@0.5.10(tailwindcss@3.4.17): resolution: {integrity: sha512-Pe8BuPJQJd3FfRnm6H0ulKIGoMEQS+Vq01R6M5aCrFB/ccR/shT+0kXLjouGC1gFLm9hopTFN+DMP0pfwRWzPw==} peerDependencies: @@ -3360,6 +3936,18 @@ packages: postcss-selector-parser: 6.0.10 tailwindcss: 3.4.17 + /@tailwindcss/typography@0.5.16(tailwindcss@4.0.9): + resolution: {integrity: sha512-0wDLwCVF5V3x3b1SGXPCDcdsbDHMBe+lkFzBRaHeLvNi+nrrnZ1lA18u+OTWO8iSWU2GxUOCvlXtDuqftc1oiA==} + peerDependencies: + tailwindcss: '>=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1' + dependencies: + lodash.castarray: 4.4.0 + lodash.isplainobject: 4.0.6 + lodash.merge: 4.6.2 + postcss-selector-parser: 6.0.10 + tailwindcss: 4.0.9 + dev: false + /@tanstack/react-virtual@3.13.2(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-LceSUgABBKF6HSsHK2ZqHzQ37IKV/jlaWbHm+NyTa3/WNb/JZVcThDuTainf+PixltOOcFCYXwxbLpOX9sCx+g==} peerDependencies: @@ -3371,6 +3959,17 @@ packages: react-dom: 18.3.1(react@18.3.1) dev: false + /@tanstack/react-virtual@3.13.2(react-dom@19.0.0)(react@19.0.0): + resolution: {integrity: sha512-LceSUgABBKF6HSsHK2ZqHzQ37IKV/jlaWbHm+NyTa3/WNb/JZVcThDuTainf+PixltOOcFCYXwxbLpOX9sCx+g==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + dependencies: + '@tanstack/virtual-core': 3.13.2 + react: 19.0.0 + react-dom: 19.0.0(react@19.0.0) + dev: false + /@tanstack/virtual-core@3.13.2: resolution: {integrity: sha512-Qzz4EgzMbO5gKrmqUondCjiHcuu4B1ftHb0pjCut661lXZdGoHeze9f/M8iwsK1t5LGR6aNuNGU7mxkowaW6RQ==} dev: false @@ -3566,6 +4165,12 @@ packages: dependencies: undici-types: 5.26.5 + /@types/node@22.13.5: + resolution: {integrity: sha512-+lTU0PxZXn0Dr1NBtC7Y8cR21AJr87dLLU953CWA6pMxxv/UDc7jYAY90upcrie1nRcD6XNG5HOYEDtgW5TxAg==} + dependencies: + undici-types: 6.20.0 + dev: true + /@types/node@22.9.0: resolution: {integrity: sha512-vuyHg81vvWA1Z1ELfvLko2c8f34gyA0zaic0+Rllc5lbCnbSyuvb2Oxpm6TAUAC/2xZN3QGqxBNggD1nNR2AfQ==} dependencies: @@ -3588,6 +4193,14 @@ packages: dependencies: '@types/react': 18.2.55 + /@types/react-dom@19.0.4(@types/react@19.0.10): + resolution: {integrity: sha512-4fSQ8vWFkg+TGhePfUzVmat3eC14TXYSsiiDSLI0dVLsrm9gZFABjPy/Qu6TKgl1tq1Bu1yDsuQgY3A3DOjCcg==} + peerDependencies: + '@types/react': ^19.0.0 + dependencies: + '@types/react': 19.0.10 + dev: true + /@types/react@18.2.55: resolution: {integrity: sha512-Y2Tz5P4yz23brwm2d7jNon39qoAtMMmalOQv6+fEFt1mT+FcM3D841wDpoUvFXhaYenuROCy3FZYqdTjM7qVyA==} dependencies: @@ -3595,6 +4208,12 @@ packages: '@types/scheduler': 0.23.0 csstype: 3.1.3 + /@types/react@19.0.10: + resolution: {integrity: sha512-JuRQ9KXLEjaUNjTWpzuR231Z2WpIwczOkBEIvbHNCzQefFIT0L8IqE6NV6ULLyC1SI/i234JnDoMkfg+RjQj2g==} + dependencies: + csstype: 3.1.3 + dev: true + /@types/scheduler@0.23.0: resolution: {integrity: sha512-YIoDCTH3Af6XM5VuwGG/QL/CJqga1Zm3NkU3HZ4ZHK2fRMPYP1VczsTUqtsf43PH/iJNVlPHAo2oWX7BSdB2Hw==} @@ -3794,7 +4413,6 @@ packages: typescript: 5.6.3 transitivePeerDependencies: - supports-color - dev: true /@typescript-eslint/parser@8.25.0(eslint@8.56.0)(typescript@5.6.3): resolution: {integrity: sha512-4gbs64bnbSzu4FpgMiQ1A+D+urxkoJk/kqlDJ2W//5SygaEiAP2B4GoS7TEdxgwol2el03gckFV9lJ4QOMiiHg==} @@ -4184,7 +4802,36 @@ packages: /@ungap/structured-clone@1.3.0: resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} - dev: true + + /@vercel/analytics@1.5.0(next@15.1.7)(react@19.0.0): + resolution: {integrity: sha512-MYsBzfPki4gthY5HnYN7jgInhAZ7Ac1cYDoRWFomwGHWEX7odTEzbtg9kf/QSo7XEsEAqlQugA6gJ2WS2DEa3g==} + peerDependencies: + '@remix-run/react': ^2 + '@sveltejs/kit': ^1 || ^2 + next: '>= 13' + react: ^18 || ^19 || ^19.0.0-rc + svelte: '>= 4' + vue: ^3 + vue-router: ^4 + peerDependenciesMeta: + '@remix-run/react': + optional: true + '@sveltejs/kit': + optional: true + next: + optional: true + react: + optional: true + svelte: + optional: true + vue: + optional: true + vue-router: + optional: true + dependencies: + next: 15.1.7(@babel/core@7.26.9)(react-dom@19.0.0)(react@19.0.0) + react: 19.0.0 + dev: false /@vercel/edge-config-fs@0.1.0: resolution: {integrity: sha512-NRIBwfcS0bUoUbRWlNGetqjvLSwgYH/BqKqDN7vK1g32p7dN96k0712COgaz6VFizAm9b0g6IG6hR6+hc0KCPg==} @@ -4200,10 +4847,26 @@ packages: dependencies: '@vercel/edge-config-fs': 0.1.0 + /@vercel/edge-config@1.4.0: + resolution: {integrity: sha512-69Wg5gw9DzwnyUmnjToSeLRm1nm8mCPgN0kflX8EHRHyqvzH80wPem5A8rI2LXPb2Y9tJNoqN3vXPcQhS2Wh5g==} + engines: {node: '>=14.6'} + peerDependencies: + '@opentelemetry/api': ^1.7.0 + peerDependenciesMeta: + '@opentelemetry/api': + optional: true + dependencies: + '@vercel/edge-config-fs': 0.1.0 + dev: false + /@vercel/edge@1.1.1: resolution: {integrity: sha512-NtKiIbn9Cq6HWGy+qRudz28mz5nxfOJWls5Pnckjw1yCfSX8rhXdvY/il3Sy3Zd5n/sKCM2h7VSCCpJF/oaDrQ==} dev: false + /@vercel/edge@1.2.1: + resolution: {integrity: sha512-1++yncEyIAi68D3UEOlytYb1IUcIulMWdoSzX2h9LuSeeyR7JtaIgR8DcTQ6+DmYOQn+5MCh6LY+UmK6QBByNA==} + dev: false + /@vercel/functions@1.6.0: resolution: {integrity: sha512-R6FKQrYT5MZs5IE1SqeCJWxMuBdHawFcCZboKKw8p7s+6/mcd55Gx6tWmyKnQTyrSEA04NH73Tc9CbqpEle8RA==} engines: {node: '>= 16'} @@ -4214,6 +4877,77 @@ packages: optional: true dev: false + /@vercel/microfrontends@1.0.0(@vercel/analytics@1.5.0)(next@15.1.7)(react-dom@19.0.0)(react@19.0.0): + resolution: {integrity: sha512-83ikhvV/k9F48zu/J7KtIi6ly1hZ5vSAosBBdkb9hmFgz8iL7iifjEpNp9cREjYa/8hajpbuVhqzsL23Cc+70Q==} + hasBin: true + peerDependencies: + '@vercel/analytics': '>=1.5.0' + '@vercel/speed-insights': '>=1.2.0' + next: '>=13' + react: '>=17.0.0' + react-dom: '>=17.0.0' + peerDependenciesMeta: + '@vercel/analytics': + optional: true + '@vercel/speed-insights': + optional: true + next: + optional: true + react: + optional: true + react-dom: + optional: true + dependencies: + '@vercel/analytics': 1.5.0(next@15.1.7)(react@19.0.0) + ajv: 8.17.1 + commander: 12.1.0 + cookie: 0.4.0 + fast-glob: 3.3.3 + http-proxy: 1.18.1 + jsonc-parser: 3.3.1 + next: 15.1.7(@babel/core@7.26.9)(react-dom@19.0.0)(react@19.0.0) + path-to-regexp: 6.2.1 + react: 19.0.0 + react-dom: 19.0.0(react@19.0.0) + transitivePeerDependencies: + - debug + dev: false + + /@vercel/microfrontends@1.0.0(next@15.1.7)(react-dom@19.0.0)(react@19.0.0): + resolution: {integrity: sha512-83ikhvV/k9F48zu/J7KtIi6ly1hZ5vSAosBBdkb9hmFgz8iL7iifjEpNp9cREjYa/8hajpbuVhqzsL23Cc+70Q==} + hasBin: true + peerDependencies: + '@vercel/analytics': '>=1.5.0' + '@vercel/speed-insights': '>=1.2.0' + next: '>=13' + react: '>=17.0.0' + react-dom: '>=17.0.0' + peerDependenciesMeta: + '@vercel/analytics': + optional: true + '@vercel/speed-insights': + optional: true + next: + optional: true + react: + optional: true + react-dom: + optional: true + dependencies: + ajv: 8.17.1 + commander: 12.1.0 + cookie: 0.4.0 + fast-glob: 3.3.3 + http-proxy: 1.18.1 + jsonc-parser: 3.3.1 + next: 15.1.7(@babel/core@7.26.9)(react-dom@19.0.0)(react@19.0.0) + path-to-regexp: 6.2.1 + react: 19.0.0 + react-dom: 19.0.0(react@19.0.0) + transitivePeerDependencies: + - debug + dev: false + /@vercel/style-guide@5.2.0(eslint@8.48.0)(jest@29.7.0)(prettier@3.2.5)(typescript@5.3.3): resolution: {integrity: sha512-fNSKEaZvSkiBoF6XEefs8CcgAV9K9e+MbcsDZjUsktHycKdA0jvjAzQi1W/FzLS+Nr5zZ6oejCwq/97dHUKe0g==} engines: {node: '>=16'} @@ -4379,8 +5113,55 @@ packages: strip-ansi: 6.0.1 dev: false - /@vercel/toolbar@0.1.15(vite@5.1.1): - resolution: {integrity: sha512-YDwRdYM6ij5CbkZm9NgoO1H7uXPuoM5nnzoHYMAZtF0sJylhQ7JIgwLniW71V6RNCKCrJGS1B23BvrQQl8WyrQ==} + /@vercel/toolbar@0.1.15(vite@5.1.1): + resolution: {integrity: sha512-YDwRdYM6ij5CbkZm9NgoO1H7uXPuoM5nnzoHYMAZtF0sJylhQ7JIgwLniW71V6RNCKCrJGS1B23BvrQQl8WyrQ==} + peerDependencies: + next: '>=11.0.0' + react: '>=17' + vite: '>=5' + peerDependenciesMeta: + next: + optional: true + react: + optional: true + vite: + optional: true + dependencies: + '@tinyhttp/app': 1.3.0 + chokidar: 3.6.0 + execa: 5.1.1 + find-up: 5.0.0 + get-port: 5.1.1 + strip-ansi: 6.0.1 + vite: 5.1.1(@types/node@22.9.0) + dev: false + + /@vercel/toolbar@0.1.27(next@15.2.0-canary.3)(react@19.0.0-rc-02c0e824-20241028): + resolution: {integrity: sha512-AxPeZKFFIMr9OGy7ZcgSsKWX7VhZQvO6xpI3iv6j3ALI0CTVFjnu0HCBWLHjRH6YD59W5X+83uCXkKWWol+S3Q==} + peerDependencies: + next: '>=11.0.0' + react: '>=17' + vite: '>=5' + peerDependenciesMeta: + next: + optional: true + react: + optional: true + vite: + optional: true + dependencies: + '@tinyhttp/app': 1.3.0 + chokidar: 3.6.0 + execa: 5.1.1 + find-up: 5.0.0 + get-port: 5.1.1 + next: 15.2.0-canary.3(@babel/core@7.26.9)(react-dom@19.0.0-rc-02c0e824-20241028)(react@19.0.0-rc-02c0e824-20241028) + react: 19.0.0-rc-02c0e824-20241028 + strip-ansi: 6.0.1 + dev: false + + /@vercel/toolbar@0.1.33(@vercel/analytics@1.5.0)(next@15.1.7)(react-dom@19.0.0)(react@19.0.0): + resolution: {integrity: sha512-92NzgxXRwiQ1frekzrTDFl93uslB5f9PT9QOeduLB9VHhThJ49OdRsddJgsVGJ4oW31EeOpCVyap3tHpA1sWzA==} peerDependencies: next: '>=11.0.0' react: '>=17' @@ -4394,16 +5175,25 @@ packages: optional: true dependencies: '@tinyhttp/app': 1.3.0 + '@vercel/microfrontends': 1.0.0(@vercel/analytics@1.5.0)(next@15.1.7)(react-dom@19.0.0)(react@19.0.0) chokidar: 3.6.0 execa: 5.1.1 + fast-glob: 3.3.3 find-up: 5.0.0 get-port: 5.1.1 + jsonc-parser: 3.3.1 + next: 15.1.7(@babel/core@7.26.9)(react-dom@19.0.0)(react@19.0.0) + react: 19.0.0 strip-ansi: 6.0.1 - vite: 5.1.1(@types/node@22.9.0) + transitivePeerDependencies: + - '@vercel/analytics' + - '@vercel/speed-insights' + - debug + - react-dom dev: false - /@vercel/toolbar@0.1.27(next@15.2.0-canary.3)(react@19.0.0-rc-02c0e824-20241028): - resolution: {integrity: sha512-AxPeZKFFIMr9OGy7ZcgSsKWX7VhZQvO6xpI3iv6j3ALI0CTVFjnu0HCBWLHjRH6YD59W5X+83uCXkKWWol+S3Q==} + /@vercel/toolbar@0.1.33(next@15.1.7)(react-dom@19.0.0)(react@19.0.0): + resolution: {integrity: sha512-92NzgxXRwiQ1frekzrTDFl93uslB5f9PT9QOeduLB9VHhThJ49OdRsddJgsVGJ4oW31EeOpCVyap3tHpA1sWzA==} peerDependencies: next: '>=11.0.0' react: '>=17' @@ -4417,13 +5207,21 @@ packages: optional: true dependencies: '@tinyhttp/app': 1.3.0 + '@vercel/microfrontends': 1.0.0(next@15.1.7)(react-dom@19.0.0)(react@19.0.0) chokidar: 3.6.0 execa: 5.1.1 + fast-glob: 3.3.3 find-up: 5.0.0 get-port: 5.1.1 - next: 15.2.0-canary.3(@babel/core@7.26.9)(react-dom@19.0.0-rc-02c0e824-20241028)(react@19.0.0-rc-02c0e824-20241028) - react: 19.0.0-rc-02c0e824-20241028 + jsonc-parser: 3.3.1 + next: 15.1.7(@babel/core@7.26.9)(react-dom@19.0.0)(react@19.0.0) + react: 19.0.0 strip-ansi: 6.0.1 + transitivePeerDependencies: + - '@vercel/analytics' + - '@vercel/speed-insights' + - debug + - react-dom dev: false /@vitejs/plugin-react@4.2.1(vite@5.1.1): @@ -4508,6 +5306,15 @@ packages: json-schema-traverse: 0.4.1 uri-js: 4.4.1 + /ajv@8.17.1: + resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} + dependencies: + fast-deep-equal: 3.1.3 + fast-uri: 3.0.6 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + dev: false + /ansi-colors@4.1.3: resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} engines: {node: '>=6'} @@ -5182,6 +5989,11 @@ packages: engines: {node: '>=16'} dev: true + /commander@12.1.0: + resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} + engines: {node: '>=18'} + dev: false + /commander@4.1.1: resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} engines: {node: '>= 6'} @@ -5196,6 +6008,11 @@ packages: /convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + /cookie@0.4.0: + resolution: {integrity: sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==} + engines: {node: '>= 0.6'} + dev: false + /cookie@0.6.0: resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==} engines: {node: '>= 0.6'} @@ -5407,6 +6224,12 @@ packages: resolution: {integrity: sha512-Mc7QhQ8s+cLrnUfU/Ji94vG/r8M26m8f++vyres4ZoojaRDpZ1eSIh/EpzLNwlWuvzSZ3UbDFspjFvTDXe6e/g==} engines: {node: '>=12.20'} + /detect-libc@1.0.3: + resolution: {integrity: sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==} + engines: {node: '>=0.10'} + hasBin: true + dev: false + /detect-libc@2.0.3: resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==} engines: {node: '>=8'} @@ -5777,7 +6600,7 @@ packages: peerDependencies: eslint-plugin-import: '>=1.4.0' dependencies: - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-typescript@3.8.3)(eslint@8.48.0) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-typescript@3.8.3)(eslint@8.56.0) /eslint-import-resolver-node@0.3.9: resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} @@ -5830,14 +6653,13 @@ packages: debug: 4.4.0 enhanced-resolve: 5.18.1 eslint: 8.56.0 - eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.25.0)(eslint-import-resolver-typescript@3.8.3)(eslint@8.56.0) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-typescript@3.8.3)(eslint@8.56.0) get-tsconfig: 4.10.0 is-bun-module: 1.3.0 stable-hash: 0.0.4 tinyglobby: 0.2.12 transitivePeerDependencies: - supports-color - dev: true /eslint-module-utils@2.12.0(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.8.3)(eslint@8.48.0): resolution: {integrity: sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==} @@ -5896,7 +6718,6 @@ packages: eslint-import-resolver-typescript: 3.8.3(eslint-plugin-import@2.31.0)(eslint@8.56.0) transitivePeerDependencies: - supports-color - dev: true /eslint-module-utils@2.12.0(@typescript-eslint/parser@8.25.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.8.3)(eslint@8.56.0): resolution: {integrity: sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==} @@ -6020,7 +6841,6 @@ packages: - eslint-import-resolver-typescript - eslint-import-resolver-webpack - supports-color - dev: true /eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.25.0)(eslint-import-resolver-typescript@3.8.3)(eslint@8.56.0): resolution: {integrity: sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==} @@ -6390,6 +7210,14 @@ packages: esrecurse: 4.3.0 estraverse: 5.3.0 + /eslint-scope@8.2.0: + resolution: {integrity: sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + dev: true + /eslint-visitor-keys@2.1.0: resolution: {integrity: sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==} engines: {node: '>=10'} @@ -6495,11 +7323,67 @@ packages: text-table: 0.2.0 transitivePeerDependencies: - supports-color + + /eslint@9.21.0: + resolution: {integrity: sha512-KjeihdFqTPhOMXTt7StsDxriV4n66ueuF/jfPNC3j/lduHwr/ijDwJMsF+wyMJethgiKi5wniIE243vi07d3pg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true + dependencies: + '@eslint-community/eslint-utils': 4.4.1(eslint@9.21.0) + '@eslint-community/regexpp': 4.12.1 + '@eslint/config-array': 0.19.2 + '@eslint/core': 0.12.0 + '@eslint/eslintrc': 3.3.0 + '@eslint/js': 9.21.0 + '@eslint/plugin-kit': 0.2.7 + '@humanfs/node': 0.16.6 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.4.2 + '@types/estree': 1.0.6 + '@types/json-schema': 7.0.15 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.4.0 + escape-string-regexp: 4.0.0 + eslint-scope: 8.2.0 + eslint-visitor-keys: 4.2.0 + espree: 10.3.0 + esquery: 1.6.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.4 + transitivePeerDependencies: + - supports-color dev: true /esm-env@1.2.2: resolution: {integrity: sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==} + /espree@10.3.0: + resolution: {integrity: sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + dependencies: + acorn: 8.14.0 + acorn-jsx: 5.3.2(acorn@8.14.0) + eslint-visitor-keys: 4.2.0 + dev: true + /espree@9.6.1: resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -6542,6 +7426,10 @@ packages: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} + /eventemitter3@4.0.7: + resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} + dev: false + /eventemitter3@5.0.1: resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} dev: true @@ -6632,6 +7520,10 @@ packages: /fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + /fast-uri@3.0.6: + resolution: {integrity: sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==} + dev: false + /fastq@1.19.0: resolution: {integrity: sha512-7SFSRCNjBQIZH/xZR3iy5iQYR8aGBE0h3VG6/cwlbrpdciNYBMotQav8c1XI3HjHH+NikUpP53nPdlZSdWmFzA==} dependencies: @@ -6662,6 +7554,13 @@ packages: dependencies: flat-cache: 3.2.0 + /file-entry-cache@8.0.0: + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} + engines: {node: '>=16.0.0'} + dependencies: + flat-cache: 4.0.1 + dev: true + /fill-range@7.1.1: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} @@ -6697,9 +7596,27 @@ packages: keyv: 4.5.4 rimraf: 3.0.2 + /flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} + engines: {node: '>=16'} + dependencies: + flatted: 3.3.3 + keyv: 4.5.4 + dev: true + /flatted@3.3.3: resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} + /follow-redirects@1.15.9: + resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + dev: false + /for-each@0.3.5: resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} engines: {node: '>= 0.4'} @@ -6924,6 +7841,11 @@ packages: dependencies: type-fest: 0.20.2 + /globals@14.0.0: + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} + engines: {node: '>=18'} + dev: true + /globalthis@1.0.4: resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} engines: {node: '>= 0.4'} @@ -7046,6 +7968,17 @@ packages: resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} dev: true + /http-proxy@1.18.1: + resolution: {integrity: sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==} + engines: {node: '>=8.0.0'} + dependencies: + eventemitter3: 4.0.7 + follow-redirects: 1.15.9 + requires-port: 1.0.0 + transitivePeerDependencies: + - debug + dev: false + /human-id@1.0.2: resolution: {integrity: sha512-UNopramDEhHJD+VR+ehk8rOslwSfByxPIZyJRfV739NDhN5LF1fa1MqnzKm2lGTQRjNrjK19Q5fhkgIfjlVUKw==} dev: true @@ -7884,6 +8817,11 @@ packages: resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==} hasBin: true + /jiti@2.4.2: + resolution: {integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==} + hasBin: true + dev: false + /jju@1.4.0: resolution: {integrity: sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==} @@ -7903,6 +8841,11 @@ packages: resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==} dev: true + /js-xxhash@4.0.0: + resolution: {integrity: sha512-3Q2eIqG6s1KEBBmkj9tGM9lef8LJbuRyTVBdI3GpTnrvtytunjLPO0wqABp5qhtMzfA32jYn1FlnIV7GH1RAHQ==} + engines: {node: '>=18.0.0'} + dev: false + /js-yaml@3.14.1: resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} hasBin: true @@ -7934,6 +8877,10 @@ packages: /json-schema-traverse@0.4.1: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + /json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + dev: false + /json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} @@ -7948,6 +8895,10 @@ packages: engines: {node: '>=6'} hasBin: true + /jsonc-parser@3.3.1: + resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==} + dev: false + /jsonfile@4.0.0: resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} optionalDependencies: @@ -8001,6 +8952,114 @@ packages: prelude-ls: 1.2.1 type-check: 0.4.0 + /lightningcss-darwin-arm64@1.29.1: + resolution: {integrity: sha512-HtR5XJ5A0lvCqYAoSv2QdZZyoHNttBpa5EP9aNuzBQeKGfbyH5+UipLWvVzpP4Uml5ej4BYs5I9Lco9u1fECqw==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /lightningcss-darwin-x64@1.29.1: + resolution: {integrity: sha512-k33G9IzKUpHy/J/3+9MCO4e+PzaFblsgBjSGlpAaFikeBFm8B/CkO3cKU9oI4g+fjS2KlkLM/Bza9K/aw8wsNA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /lightningcss-freebsd-x64@1.29.1: + resolution: {integrity: sha512-0SUW22fv/8kln2LnIdOCmSuXnxgxVC276W5KLTwoehiO0hxkacBxjHOL5EtHD8BAXg2BvuhsJPmVMasvby3LiQ==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: false + optional: true + + /lightningcss-linux-arm-gnueabihf@1.29.1: + resolution: {integrity: sha512-sD32pFvlR0kDlqsOZmYqH/68SqUMPNj+0pucGxToXZi4XZgZmqeX/NkxNKCPsswAXU3UeYgDSpGhu05eAufjDg==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /lightningcss-linux-arm64-gnu@1.29.1: + resolution: {integrity: sha512-0+vClRIZ6mmJl/dxGuRsE197o1HDEeeRk6nzycSy2GofC2JsY4ifCRnvUWf/CUBQmlrvMzt6SMQNMSEu22csWQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /lightningcss-linux-arm64-musl@1.29.1: + resolution: {integrity: sha512-UKMFrG4rL/uHNgelBsDwJcBqVpzNJbzsKkbI3Ja5fg00sgQnHw/VrzUTEc4jhZ+AN2BvQYz/tkHu4vt1kLuJyw==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /lightningcss-linux-x64-gnu@1.29.1: + resolution: {integrity: sha512-u1S+xdODy/eEtjADqirA774y3jLcm8RPtYztwReEXoZKdzgsHYPl0s5V52Tst+GKzqjebkULT86XMSxejzfISw==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /lightningcss-linux-x64-musl@1.29.1: + resolution: {integrity: sha512-L0Tx0DtaNUTzXv0lbGCLB/c/qEADanHbu4QdcNOXLIe1i8i22rZRpbT3gpWYsCh9aSL9zFujY/WmEXIatWvXbw==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /lightningcss-win32-arm64-msvc@1.29.1: + resolution: {integrity: sha512-QoOVnkIEFfbW4xPi+dpdft/zAKmgLgsRHfJalEPYuJDOWf7cLQzYg0DEh8/sn737FaeMJxHZRc1oBreiwZCjog==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /lightningcss-win32-x64-msvc@1.29.1: + resolution: {integrity: sha512-NygcbThNBe4JElP+olyTI/doBNGJvLs3bFCRPdvuCcxZCcCZ71B858IHpdm7L1btZex0FvCmM17FK98Y9MRy1Q==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /lightningcss@1.29.1: + resolution: {integrity: sha512-FmGoeD4S05ewj+AkhTY+D+myDvXI6eL27FjHIjoyUkO/uw7WZD1fBVs0QxeYWa7E17CUHJaYX/RUGISCtcrG4Q==} + engines: {node: '>= 12.0.0'} + dependencies: + detect-libc: 1.0.3 + optionalDependencies: + lightningcss-darwin-arm64: 1.29.1 + lightningcss-darwin-x64: 1.29.1 + lightningcss-freebsd-x64: 1.29.1 + lightningcss-linux-arm-gnueabihf: 1.29.1 + lightningcss-linux-arm64-gnu: 1.29.1 + lightningcss-linux-arm64-musl: 1.29.1 + lightningcss-linux-x64-gnu: 1.29.1 + lightningcss-linux-x64-musl: 1.29.1 + lightningcss-win32-arm64-msvc: 1.29.1 + lightningcss-win32-x64-msvc: 1.29.1 + dev: false + /lilconfig@3.0.0: resolution: {integrity: sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g==} engines: {node: '>=14'} @@ -8462,6 +9521,12 @@ packages: hasBin: true dev: false + /nanoid@5.1.2: + resolution: {integrity: sha512-b+CiXQCNMUGe0Ri64S9SXFcP9hogjAJ2Rd6GdVxhPLRm7mhGaM7VgOvCAJ1ZshfHbqVDI3uqTI5C8/GaKuLI7g==} + engines: {node: ^18 || >=20} + hasBin: true + dev: false + /natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} @@ -8607,7 +9672,7 @@ packages: - babel-plugin-macros dev: false - /next@15.1.4(@babel/core@7.26.9)(@opentelemetry/api@1.9.0)(react-dom@18.3.1)(react@19.1.0-canary-22e39ea7-20250225): + /next@15.1.4(@babel/core@7.26.9)(@opentelemetry/api@1.9.0)(react-dom@18.3.1)(react@19.1.0-canary-ebc22ef7-20250225): resolution: {integrity: sha512-mTaq9dwaSuwwOrcu3ebjDYObekkxRnXpuVL21zotM8qE2W0HBOdVIdg2Li9QjMEZrj73LN96LcWcz62V19FjAg==} engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0} hasBin: true @@ -8635,9 +9700,9 @@ packages: busboy: 1.6.0 caniuse-lite: 1.0.30001701 postcss: 8.4.31 - react: 19.1.0-canary-22e39ea7-20250225 - react-dom: 18.3.1(react@19.1.0-canary-22e39ea7-20250225) - styled-jsx: 5.1.6(@babel/core@7.26.9)(react@19.1.0-canary-22e39ea7-20250225) + react: 19.1.0-canary-ebc22ef7-20250225 + react-dom: 18.3.1(react@19.1.0-canary-ebc22ef7-20250225) + styled-jsx: 5.1.6(@babel/core@7.26.9)(react@19.1.0-canary-ebc22ef7-20250225) optionalDependencies: '@next/swc-darwin-arm64': 15.1.4 '@next/swc-darwin-x64': 15.1.4 @@ -8699,8 +9764,8 @@ packages: - babel-plugin-macros dev: false - /next@15.1.4(@babel/core@7.26.9)(react-dom@18.3.1)(react@18.3.1): - resolution: {integrity: sha512-mTaq9dwaSuwwOrcu3ebjDYObekkxRnXpuVL21zotM8qE2W0HBOdVIdg2Li9QjMEZrj73LN96LcWcz62V19FjAg==} + /next@15.1.7(@babel/core@7.26.9)(react-dom@19.0.0)(react@19.0.0): + resolution: {integrity: sha512-GNeINPGS9c6OZKCvKypbL8GTsT5GhWPp4DM0fzkXJuXMilOO2EeFxuAY6JZbtk6XIl6Ws10ag3xRINDjSO5+wg==} engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0} hasBin: true peerDependencies: @@ -8720,24 +9785,24 @@ packages: sass: optional: true dependencies: - '@next/env': 15.1.4 + '@next/env': 15.1.7 '@swc/counter': 0.1.3 '@swc/helpers': 0.5.15 busboy: 1.6.0 caniuse-lite: 1.0.30001701 postcss: 8.4.31 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - styled-jsx: 5.1.6(@babel/core@7.26.9)(react@18.3.1) + react: 19.0.0 + react-dom: 19.0.0(react@19.0.0) + styled-jsx: 5.1.6(@babel/core@7.26.9)(react@19.0.0) optionalDependencies: - '@next/swc-darwin-arm64': 15.1.4 - '@next/swc-darwin-x64': 15.1.4 - '@next/swc-linux-arm64-gnu': 15.1.4 - '@next/swc-linux-arm64-musl': 15.1.4 - '@next/swc-linux-x64-gnu': 15.1.4 - '@next/swc-linux-x64-musl': 15.1.4 - '@next/swc-win32-arm64-msvc': 15.1.4 - '@next/swc-win32-x64-msvc': 15.1.4 + '@next/swc-darwin-arm64': 15.1.7 + '@next/swc-darwin-x64': 15.1.7 + '@next/swc-linux-arm64-gnu': 15.1.7 + '@next/swc-linux-arm64-musl': 15.1.7 + '@next/swc-linux-x64-gnu': 15.1.7 + '@next/swc-linux-x64-musl': 15.1.7 + '@next/swc-win32-arm64-msvc': 15.1.7 + '@next/swc-win32-x64-msvc': 15.1.7 sharp: 0.33.5 transitivePeerDependencies: - '@babel/core' @@ -9110,6 +10175,10 @@ packages: minipass: 7.1.2 dev: true + /path-to-regexp@6.2.1: + resolution: {integrity: sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==} + dev: false + /path-to-regexp@6.3.0: resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==} dev: true @@ -9408,15 +10477,24 @@ packages: scheduler: 0.23.2 dev: false - /react-dom@18.3.1(react@19.1.0-canary-22e39ea7-20250225): + /react-dom@18.3.1(react@19.1.0-canary-ebc22ef7-20250225): resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==} peerDependencies: react: ^18.3.1 dependencies: loose-envify: 1.4.0 - react: 19.1.0-canary-22e39ea7-20250225 + react: 19.1.0-canary-ebc22ef7-20250225 scheduler: 0.23.2 + /react-dom@19.0.0(react@19.0.0): + resolution: {integrity: sha512-4GV5sHFG0e/0AD4X+ySy6UJd3jVl1iNsNHdpad0qhABJ11twS3TTBnseqsKurKcsNqCEFeGL3uLpVChpIO3QfQ==} + peerDependencies: + react: ^19.0.0 + dependencies: + react: 19.0.0 + scheduler: 0.25.0 + dev: false + /react-dom@19.0.0-rc-02c0e824-20241028(react@19.0.0-rc-02c0e824-20241028): resolution: {integrity: sha512-LrZf3DfHL6Fs07wwlUCHrzFTCMM19yA99MvJpfLokN4I2nBAZvREGZjZAn8VPiSfN72+i9j1eL4wB8gC695F3Q==} peerDependencies: @@ -9495,13 +10573,18 @@ packages: loose-envify: 1.4.0 dev: false + /react@19.0.0: + resolution: {integrity: sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==} + engines: {node: '>=0.10.0'} + dev: false + /react@19.0.0-rc-02c0e824-20241028: resolution: {integrity: sha512-GbZ7hpPHQMiEu53BqEaPQVM/4GG4hARo+mqEEnx4rYporDvNvUjutiAFxYFSbu6sgHwcr7LeFv8htEOwALVA2A==} engines: {node: '>=0.10.0'} dev: false - /react@19.1.0-canary-22e39ea7-20250225: - resolution: {integrity: sha512-9Pjd0zY+ldEFLg5fyMAYeUUiqpz5IWVKwrRYK5KCmSK8OMtLqSSi/WHQB6ATH/Zq71EcQynJ4IeplLR1q8umFQ==} + /react@19.1.0-canary-ebc22ef7-20250225: + resolution: {integrity: sha512-NzAUJ9SyCPya6q6D10Q/YI6jkcmKcjbNP8z0ahte3CSaoE+D69uYUUTBMXG0Wo2zT4mwMCvRcK9kxOOg/oeBag==} engines: {node: '>=0.10.0'} /read-cache@1.0.0: @@ -9613,13 +10696,17 @@ packages: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} + /require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + dev: false + /require-main-filename@2.0.0: resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} dev: true /requires-port@1.0.0: resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} - dev: true /resolve-cwd@3.0.0: resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} @@ -9787,6 +10874,10 @@ packages: dependencies: loose-envify: 1.4.0 + /scheduler@0.25.0: + resolution: {integrity: sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA==} + dev: false + /scheduler@0.25.0-rc-02c0e824-20241028: resolution: {integrity: sha512-GysnKjmMSaWcwsKTLzeJO0IhU3EyIiC0ivJKE6yDNLqt3IMxDByx8b6lSNXRNdN+ULUY0WLLjSPaZ0LuU/GnTg==} dev: false @@ -10340,6 +11431,24 @@ packages: react: 18.3.1 dev: false + /styled-jsx@5.1.6(@babel/core@7.26.9)(react@19.0.0): + resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==} + engines: {node: '>= 12.0.0'} + peerDependencies: + '@babel/core': '*' + babel-plugin-macros: '*' + react: '>= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0' + peerDependenciesMeta: + '@babel/core': + optional: true + babel-plugin-macros: + optional: true + dependencies: + '@babel/core': 7.26.9 + client-only: 0.0.1 + react: 19.0.0 + dev: false + /styled-jsx@5.1.6(@babel/core@7.26.9)(react@19.0.0-rc-02c0e824-20241028): resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==} engines: {node: '>= 12.0.0'} @@ -10358,7 +11467,7 @@ packages: react: 19.0.0-rc-02c0e824-20241028 dev: false - /styled-jsx@5.1.6(@babel/core@7.26.9)(react@19.1.0-canary-22e39ea7-20250225): + /styled-jsx@5.1.6(@babel/core@7.26.9)(react@19.1.0-canary-ebc22ef7-20250225): resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==} engines: {node: '>= 12.0.0'} peerDependencies: @@ -10373,7 +11482,7 @@ packages: dependencies: '@babel/core': 7.26.9 client-only: 0.0.1 - react: 19.1.0-canary-22e39ea7-20250225 + react: 19.1.0-canary-ebc22ef7-20250225 dev: true /sucrase@3.35.0: @@ -10431,8 +11540,8 @@ packages: picocolors: 1.1.1 sade: 1.8.1 svelte: 4.2.19 - svelte-preprocess: 5.1.4(@babel/core@7.26.9)(svelte@4.2.19)(typescript@5.6.3) - typescript: 5.6.3 + svelte-preprocess: 5.1.4(@babel/core@7.26.9)(svelte@4.2.19)(typescript@5.7.3) + typescript: 5.7.3 transitivePeerDependencies: - '@babel/core' - coffeescript @@ -10453,7 +11562,7 @@ packages: dependencies: svelte: 4.2.19 - /svelte-preprocess@5.1.4(@babel/core@7.26.9)(svelte@4.2.19)(typescript@5.6.3): + /svelte-preprocess@5.1.4(@babel/core@7.26.9)(svelte@4.2.19)(typescript@5.7.3): resolution: {integrity: sha512-IvnbQ6D6Ao3Gg6ftiM5tdbR6aAETwjhHV+UKGf5bHGYR69RQvF1ho0JKPcbUON4vy4R7zom13jPjgdOWCQ5hDA==} engines: {node: '>= 16.0.0'} requiresBuild: true @@ -10498,7 +11607,7 @@ packages: sorcery: 0.11.1 strip-indent: 3.0.0 svelte: 4.2.19 - typescript: 5.6.3 + typescript: 5.7.3 dev: true /svelte@4.2.19: @@ -10527,6 +11636,10 @@ packages: '@pkgr/core': 0.1.1 tslib: 2.8.1 + /tabbable@6.2.0: + resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==} + dev: false + /tailwind-merge@2.5.5: resolution: {integrity: sha512-0LXunzzAZzo0tEPxV3I297ffKZPlKDrjj7NXphC8V5ak9yHC5zRmxnOe2m/Rd/7ivsOMJe3JZ2JVocoDdQTRBA==} dev: false @@ -10569,6 +11682,9 @@ packages: transitivePeerDependencies: - ts-node + /tailwindcss@4.0.9: + resolution: {integrity: sha512-12laZu+fv1ONDRoNR9ipTOpUD7RN9essRVkX36sjxuRUInpN7hIiHN4lBd/SIFjbISvnXzp8h/hXzmU8SQQYhw==} + /tapable@2.2.1: resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} engines: {node: '>=6'} @@ -10983,6 +12099,12 @@ packages: engines: {node: '>=14.17'} hasBin: true + /typescript@5.7.3: + resolution: {integrity: sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==} + engines: {node: '>=14.17'} + hasBin: true + dev: true + /ua-parser-js@1.0.40: resolution: {integrity: sha512-z6PJ8Lml+v3ichVojCiB8toQJBuwR42ySM4ezjXIqXK3M0HczmKQ3LF4rhU55PfD99KEEXQG6yb7iOMyvYuHew==} hasBin: true @@ -11007,6 +12129,10 @@ packages: /undici-types@6.19.8: resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} + /undici-types@6.20.0: + resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==} + dev: true + /unicode-emoji-modifier-base@1.0.0: resolution: {integrity: sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g==} engines: {node: '>=4'} @@ -11204,6 +12330,7 @@ packages: rollup: 4.34.8 optionalDependencies: fsevents: 2.3.3 + dev: true /vite@5.1.1(@types/node@22.9.0): resolution: {integrity: sha512-wclpAgY3F1tR7t9LL5CcHC41YPkQIpKUGeIuT8MdNwNZr6OqOTLs7JX5vIHAtzqLWXts0T+GDrh9pN2arneKqg==} @@ -11248,7 +12375,7 @@ packages: vite: optional: true dependencies: - vite: 5.1.1(@types/node@20.11.17) + vite: 5.1.1(@types/node@22.9.0) /vitest@1.4.0(@types/node@20.11.17): resolution: {integrity: sha512-gujzn0g7fmwf83/WzrDTnncZt2UiXP41mHuFYFrdwaLRVQ6JYQEiME2IfEjU3vcFL3VKa75XhI3lFgn+hfVsQw==}