From 4be94b8ca1e5240d51cf07145955251a882aebf4 Mon Sep 17 00:00:00 2001 From: ak Date: Thu, 24 Sep 2026 16:59:16 +0300 Subject: [PATCH] feat(website): add the Amp landing page under website/ Vite + React SPA for the Amp landing page, built on EDS. Co-Authored-By: Claude Opus 5.5 (1M context) --- website/.gitignore | 6 + website/README.md | 34 + website/app/globals.css | 125 + website/app/main.tsx | 26 + website/components/CodeBlock.tsx | 33 + website/components/Dots.tsx | 28 + website/components/Live.tsx | 221 ++ website/components/Page.tsx | 192 ++ website/components/Providers.tsx | 7 + website/components/Reveal.tsx | 32 + website/components/Section.tsx | 35 + website/components/index.ts | 3 + website/components/sections/cost.tsx | 117 + website/components/sections/cta.tsx | 64 + website/components/sections/docs.tsx | 93 + website/components/sections/engine.tsx | 426 +++ website/components/sections/features.tsx | 173 ++ website/components/sections/freshness.tsx | 105 + website/components/sections/hero.tsx | 64 + website/components/sections/how.tsx | 249 ++ website/components/sections/index.ts | 14 + website/components/sections/integrations.tsx | 58 + website/components/sections/license.tsx | 59 + website/components/sections/live.tsx | 17 + website/components/sections/proof.tsx | 274 ++ website/components/sections/storage.tsx | 55 + website/components/sections/try.tsx | 209 ++ website/data/constants.ts | 8 + website/data/integrations.ts | 79 + website/index.html | 32 + website/lib/amp-api.ts | 144 + website/lib/amp-client.ts | 5 + website/lib/cn.ts | 3 + website/lib/use-heads.ts | 15 + website/package.json | 31 + website/pnpm-lock.yaml | 2621 +++++++++++++++++ website/pnpm-workspace.yaml | 2 + .../public/fonts/MessinaSans-Regular.woff2 | Bin 0 -> 18448 bytes .../public/fonts/MessinaSans-SemiBold.woff2 | Bin 0 -> 18188 bytes website/public/logo-amp.svg | 14 + website/tsconfig.json | 20 + website/vite.config.ts | 10 + 42 files changed, 5703 insertions(+) create mode 100644 website/.gitignore create mode 100644 website/README.md create mode 100644 website/app/globals.css create mode 100644 website/app/main.tsx create mode 100644 website/components/CodeBlock.tsx create mode 100644 website/components/Dots.tsx create mode 100644 website/components/Live.tsx create mode 100644 website/components/Page.tsx create mode 100644 website/components/Providers.tsx create mode 100644 website/components/Reveal.tsx create mode 100644 website/components/Section.tsx create mode 100644 website/components/index.ts create mode 100644 website/components/sections/cost.tsx create mode 100644 website/components/sections/cta.tsx create mode 100644 website/components/sections/docs.tsx create mode 100644 website/components/sections/engine.tsx create mode 100644 website/components/sections/features.tsx create mode 100644 website/components/sections/freshness.tsx create mode 100644 website/components/sections/hero.tsx create mode 100644 website/components/sections/how.tsx create mode 100644 website/components/sections/index.ts create mode 100644 website/components/sections/integrations.tsx create mode 100644 website/components/sections/license.tsx create mode 100644 website/components/sections/live.tsx create mode 100644 website/components/sections/proof.tsx create mode 100644 website/components/sections/storage.tsx create mode 100644 website/components/sections/try.tsx create mode 100644 website/data/constants.ts create mode 100644 website/data/integrations.ts create mode 100644 website/index.html create mode 100644 website/lib/amp-api.ts create mode 100644 website/lib/amp-client.ts create mode 100644 website/lib/cn.ts create mode 100644 website/lib/use-heads.ts create mode 100644 website/package.json create mode 100644 website/pnpm-lock.yaml create mode 100644 website/pnpm-workspace.yaml create mode 100644 website/public/fonts/MessinaSans-Regular.woff2 create mode 100644 website/public/fonts/MessinaSans-SemiBold.woff2 create mode 100644 website/public/logo-amp.svg create mode 100644 website/tsconfig.json create mode 100644 website/vite.config.ts diff --git a/website/.gitignore b/website/.gitignore new file mode 100644 index 0000000..da2f557 --- /dev/null +++ b/website/.gitignore @@ -0,0 +1,6 @@ +/node_modules +/dist +*.tsbuildinfo +.env* +.DS_Store +*.log diff --git a/website/README.md b/website/README.md new file mode 100644 index 0000000..05e17d1 --- /dev/null +++ b/website/README.md @@ -0,0 +1,34 @@ +# ampup + +Landing page for [Amp](https://github.com/edgeandnode/amp), aimed at data engineers and data scientists. + +Vite 8, React 19, React Router 7, Tailwind 4 (via `@tailwindcss/vite`), Motion, pnpm. A static single-page app: `index.html` carries the metadata and the Google Fonts link, `app/main.tsx` mounts the router. Code blocks are the EDS `CodeBlock` from `@edgeandnode/eds-react` (Shiki highlighting, copy button, dark and light themes). + +## EDS + +`app/globals.css` imports `@edgeandnode/eds-react` in place of `tailwindcss`, registers the source directories with `@source` (EDS turns off automatic scanning), and then layers the house tokens on top. `components/Providers.tsx` mounts the one `EDSProvider` with `theme="light"`. The `.eds` class in `globals.css` points EDS's `font-sans` and `font-mono` at Messina Sans and Geist Mono and maps `font-medium` to 600, the only heavier weight Messina has. `components/CodeBlock.tsx` is the one wrapper every page uses. + +```sh +pnpm install +pnpm dev # http://localhost:3000 +pnpm build # typecheck, then vite build into dist/ +pnpm preview # serve dist/ with the SPA fallback +``` + +## Routes + +| Route | What | Code | +|---|---|---| +| `/` | The site. EDS tokens, Messina, light only. All new work happens here. | `components/Page.tsx` composes one file per section in `components/sections/`. Each section keeps its own copy as consts at the bottom of the file. | + +## Copy rules + +Copy follows `../amp-comms/DESIGN.md` §12 (no dashes, no flagged words, no "X, not Y", sentence case, one italic word per page at most). Claims come from `../amp-comms/content/FACTS.md` and the `../amp` repo docs. The build output can be linted with the same dash and word check `amp-comms/tools/build.py` runs. + +Fonts: Messina Sans (licensed, in `public/fonts`, declared with `@font-face` in `globals.css`), Newsreader and Geist Mono (Google Fonts, linked from `index.html`). + +Hosting: the site is a client-routed SPA, so the host must serve `index.html` for unknown paths (the usual SPA fallback). The security headers the Next config used to set now belong in the host's config. + +## Live data + +The preview and "Try the flow" sections on `/` render from `lib/amp-api.ts`. `createMockClient()` fabricates chain heads, a streaming feed, a 30-day series, and a dataset catalog behind the `AmpClient` interface. To go live, implement `AmpClient` against the real API and change the one `createMockClient()` call at the top of `components/Live.tsx`, and the `ampClient` singleton in `lib/amp-client.ts` that the figures read. diff --git a/website/app/globals.css b/website/app/globals.css new file mode 100644 index 0000000..b424e08 --- /dev/null +++ b/website/app/globals.css @@ -0,0 +1,125 @@ +@import "@edgeandnode/eds-react"; +@source "../app"; +@source "../components"; +@source "../data"; + + +@theme { + --color-brand-500: #2347e5; + + --font-serif: "Newsreader", ui-serif, Georgia, "Times New Roman", serif; + --font-sans: "Messina Sans", ui-sans-serif, system-ui, sans-serif; + --font-mono: var(--font-geist-mono, "Geist Mono"), ui-monospace, "SF Mono", Menlo, monospace; +} + +@utility dotgrid { + @apply bg-[radial-gradient(color-mix(in_oklab,var(--border-color-default)_30%,transparent)_1.2px,transparent_1.8px)] bg-size-[12px_12px] bg-position-[-6px_-6px] bg-repeat +} + +@utility container { + @apply mx-auto max-w-5xl px-4 sm:px-6 lg:px-8 +} + +@theme static { + --color-on-dark: rgba(255, 255, 255, 0.95); + --color-on-dark-muted: rgba(255, 255, 255, 0.8); + --color-on-dark-faint: rgba(255, 255, 255, 0.65); + --color-success: #087443; + + --spacing-section: clamp(4.5rem, 3.5rem + 4vw, 8rem); + --spacing-hero-top: clamp(8rem, 6.8rem + 4vw, 10rem); + + --ease-smooth: cubic-bezier(0.4, 0, 0.2, 1); +} + +html { + scroll-behavior: smooth; +} + +[data-section] { + scroll-margin-top: 5.5rem; +} + +body { + @apply text-pretty; + h1, h2, h3, h4, h5, h6 { + font-family: var(--font-serif); + } +} + +@media (prefers-reduced-motion: reduce) { + html { + scroll-behavior: auto; + } + *, + *::before, + *::after { + animation-duration: 0.001ms !important; + animation-iteration-count: 1 !important; + transition-duration: 0.001ms !important; + } +} + +@keyframes hero-enter { + from { + opacity: 0; + transform: translateY(var(--hero-y, 16px)); + } + to { + opacity: 1; + transform: translateY(0); + } +} +.hero-enter { + animation: hero-enter 0.7s var(--ease-smooth) both; + animation-delay: var(--hero-delay, 0s); +} +@keyframes hero-rise { + from { + transform: translateY(var(--hero-y, 16px)); + } + to { + transform: translateY(0); + } +} +.hero-enter-rise { + animation-name: hero-rise; +} +@media (prefers-reduced-motion: reduce) { + .hero-enter { + animation-delay: 0s !important; + } +} + +@font-face { + font-family: "Messina Sans"; + src: url("/fonts/MessinaSans-Regular.woff2") format("woff2"); + font-weight: 400; + font-style: normal; + font-display: swap; +} +@font-face { + font-family: "Messina Sans"; + src: url("/fonts/MessinaSans-SemiBold.woff2") format("woff2"); + font-weight: 600; + font-style: normal; + font-display: swap; +} + + +::selection { + @apply bg-brand-500 text-inverse-default +} + +.elevated { box-shadow: 0 2px 4px rgba(15, 18, 22, 0.05), 0 12px 24px -8px rgba(15, 18, 22, 0.12); } + +.crosshair { width: 9px; height: 9px; margin: -4px; } +.crosshair::before, .crosshair::after { content: ""; position: absolute; background: var(--border-color-default); } +.crosshair::before { left: 0; right: 0; top: 4px; height: 1px; } +.crosshair::after { top: 0; bottom: 0; left: 4px; width: 1px; } + + +/* Display step between EDS's 64 and 96. */ +@media (min-width: 64rem) { + .lg\:text-80 { font-size: 5rem; line-height: 1.02; } +} diff --git a/website/app/main.tsx b/website/app/main.tsx new file mode 100644 index 0000000..1926f68 --- /dev/null +++ b/website/app/main.tsx @@ -0,0 +1,26 @@ +import { StrictMode } from "react"; +import { createRoot } from "react-dom/client"; +import { BrowserRouter, Route, Routes } from "react-router"; +import "./globals.css"; +import Providers from "@/components/Providers"; +import Page from "@/components/Page"; + +function App() { + return ( + +
+ + } /> + +
+
+ ); +} + +createRoot(document.getElementById("root")!).render( + + + + + , +); diff --git a/website/components/CodeBlock.tsx b/website/components/CodeBlock.tsx new file mode 100644 index 0000000..bfc95d9 --- /dev/null +++ b/website/components/CodeBlock.tsx @@ -0,0 +1,33 @@ +import { CodeBlock as EdsCodeBlock } from "@edgeandnode/eds-react"; +import { cn } from "@/lib/cn"; + +export type Lang = "sh" | "sql" | "toml" | "json" | "py"; + +/** The EDS CodeBlock with this site's line-array interface. Square corners per the + * house system; Shiki highlighting and the copy button come from EDS. */ +export default function CodeBlock({ + lines, + lang, + label, + copy, + className, +}: { + lines: string[]; + lang: Lang; + /** Header label; with one set, the copy button is always visible. */ + label?: string; + /** Text to copy instead of the rendered code (for prompts and comments). */ + copy?: string; + className?: string; +}) { + return ( + + {lines.join("\n")} + + ); +} diff --git a/website/components/Dots.tsx b/website/components/Dots.tsx new file mode 100644 index 0000000..d9ef2ce --- /dev/null +++ b/website/components/Dots.tsx @@ -0,0 +1,28 @@ +interface Props { + corner?: "tl" | "tr" | "bl" | "br"; + className?: string; +} + +export function Dots({ corner = "tr", className }: Props) { + const at = { tl: "0% 0%", tr: "100% 0%", bl: "0% 100%", br: "100% 100%" }[ + corner + ]; + const fade = `radial-gradient(120% 120% at ${at}, black 0%, transparent 62%)`; + return ( +
+ ); +} diff --git a/website/components/Live.tsx b/website/components/Live.tsx new file mode 100644 index 0000000..cd50fc2 --- /dev/null +++ b/website/components/Live.tsx @@ -0,0 +1,221 @@ +import { useEffect, useRef, useState } from "react"; +import { AnimatePresence, LazyMotion, domMax, m } from "motion/react"; +import { Button, CodeBlock } from "@edgeandnode/eds-react"; +import { ArrowSquareOutIcon } from "@edgeandnode/eds-react/icons"; +import { NetworkIcon } from "@web3icons/react/dynamic"; +import { LINKS } from "@/data/constants"; +import { ampClient } from "@/lib/amp-client"; +import type { Network, StreamRow } from "@/lib/amp-api"; +import { NETWORK_ICON, useHeads } from "@/lib/use-heads"; + +export default function Live() { + const heads = useHeads(); + const [network, setNetwork] = useState("mainnet"); + const [rows, setRows] = useState([]); + const [meta, setMeta] = useState<{ batch: StreamRow[]; prev: string }>(); + const last = useRef(""); + const t = TABLES[network]; + + useEffect(() => { + setRows([]); + setMeta(undefined); + last.current = ""; + return ampClient.subscribeStream(network, (batch) => { + setMeta({ batch, prev: last.current || batch[0]!.hash }); + last.current = batch[batch.length - 1]!.hash; + setRows((prev) => [...batch.slice().reverse(), ...prev].slice(0, 8)); + }); + }, [network]); + + const first = meta?.batch[0]; + const end = meta?.batch[meta.batch.length - 1]; + + return ( + +
+
+ {heads.map((h) => { + const on = h.network === network; + return ( + + ); + })} +
+ +
+
+ + {`SELECT ${t.cols.map((c) => c.name).join(", ")}\nFROM "acme/${ + t.dataset + }".${t.table}\nSETTINGS stream = true`} + + + {first && end + ? JSON.stringify( + { + ranges: [ + { + network, + numbers: { + start: first.blockNum, + end: end.blockNum, + }, + hash: short(end.hash), + prev_hash: short(meta!.prev), + }, + ], + ranges_complete: true, + }, + null, + 2, + ) + : "{}"} + +
+ +
+
+
+ {t.cols.map((c) => ( + + {c.name} + {c.type} + + ))} +
+ + {rows.map((r) => ( + + {t.cells(r).map((v, i) => ( + + {v} + + ))} + + ))} + +
+
+
+ +
+

+ Every batch carries the block range it covers and the hash that + links it to the last one. A mismatch is a reorg, and the stream + replays the range. +

+ +
+
+
+ ); +} + +const short = (h: string) => `${h.slice(0, 10)}…${h.slice(-4)}`; +const time = (ms: number) => new Date(ms).toISOString().slice(11, 23); +const B58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; +const base58 = (h: string) => + Array.from(h.slice(2, 46), (c) => B58[parseInt(c, 16) * 3 + 1]).join(""); + +const EVM = (dataset: string) => ({ + dataset, + table: "blocks", + cols: [ + { name: "block_num", type: "UInt64" }, + { name: "timestamp", type: "Timestamp(ns)" }, + { name: "hash", type: "FixedSizeBinary(32)" }, + { name: "gas_used", type: "UInt64" }, + ], + cells: (r: StreamRow) => [ + r.blockNum.toLocaleString("en-US"), + time(r.ts), + short(r.hash), + r.gasUsed.toLocaleString("en-US"), + ], +}); + +const TABLES: Record> = { + mainnet: EVM("eth_mainnet"), + base: EVM("base"), + "solana-mainnet": { + dataset: "solana_mainnet", + table: "block_headers", + cols: [ + { name: "slot", type: "UInt64" }, + { name: "block_time", type: "Int64" }, + { name: "block_hash", type: "Utf8" }, + { name: "parent_slot", type: "UInt64" }, + ], + cells: (r) => [ + r.blockNum.toLocaleString("en-US"), + String(Math.floor(r.ts / 1000)), + `${base58(r.hash).slice(0, 12)}…`, + (r.blockNum - 1).toLocaleString("en-US"), + ], + }, +}; diff --git a/website/components/Page.tsx b/website/components/Page.tsx new file mode 100644 index 0000000..4feb274 --- /dev/null +++ b/website/components/Page.tsx @@ -0,0 +1,192 @@ +import { Button, ButtonGroup, Link } from "@edgeandnode/eds-react"; +import { AmpLogoIcon } from "@edgeandnode/eds-react/icons"; +import { + AnimatePresence, + LazyMotion, + domMax, + m, + useReducedMotion, +} from "motion/react"; +import { LINKS } from "@/data/constants"; +import { useHeads } from "@/lib/use-heads"; +import { + Hero, + LiveSection, + CTA, + Engine, + Features, + How, + Integrations, + Proof, + Cost, + Storage, + Freshness, + Try, + Docs, + License, +} from "./sections"; +import { NetworkEthereum } from "@web3icons/react"; + +export default function Page() { + return ( +
+
+
+
+
+ + Amp +
+
+ + Docs + + +
+
+
+ +
+ + + + + + + + + {/* */} + + + + + + + + + + + +
+ +
+ + Amp is built by Edge & Node, the team behind The Graph. Published + under BUSL-1.1. + + + + Edge & Node + + +
+
+ ); +} + +const Band = ({ children }: { children?: React.ReactNode }) => ( + +); + +const LINE = "var(--border-color-default)"; + +const PatternHatch = () => ( + +
+ +); + +const PatternBlocks = () => { + const head = useHeads().find((h) => h.network === "base")!.ampHead; + const blocks = Array.from({ length: 48 }, (_, i) => head - 47 + i); + return ( + + +
+ + {blocks.map((n) => ( + + ))} + +
+ + + {head.toLocaleString("en-US")} + +
+
+
+
+ ); +}; + +const PatternHashes = () => { + const reduce = useReducedMotion(); + const hashes = Array.from({ length: 24 }, (_, i) => { + let x = (i + 1) * 2654435761; + let h = "0x"; + for (let j = 0; j < 12; j++) { + x = (x * 1103515245 + 12345) >>> 0; + h += (x >>> 24).toString(16).padStart(2, "0").slice(-1); + } + return h; + }); + return ( + + +
+ + {[...hashes, ...hashes].map((h, i) => ( + {h} + ))} + +
+
+
+ ); +}; diff --git a/website/components/Providers.tsx b/website/components/Providers.tsx new file mode 100644 index 0000000..07f4366 --- /dev/null +++ b/website/components/Providers.tsx @@ -0,0 +1,7 @@ +import { EDSProvider } from "@edgeandnode/eds-react"; + +/** One EDSProvider per app. Light only. The archived versions at /v2 and /v3 + * follow the OS through their own eds-system wrapper. */ +export default function Providers({ children }: { children: React.ReactNode }) { + return {children}; +} diff --git a/website/components/Reveal.tsx b/website/components/Reveal.tsx new file mode 100644 index 0000000..42d6207 --- /dev/null +++ b/website/components/Reveal.tsx @@ -0,0 +1,32 @@ +import { cn } from "@/lib/cn"; +import { m, LazyMotion, domAnimation, useReducedMotion } from "motion/react"; + +const EASE_OUT = [0.16, 1, 0.3, 1] as const; + +/** Fade + rise on scroll into view. Content is visible without JS (SSR renders + * the resting state; motion only adds the entrance once hydrated). */ +export function Reveal({ + children, + delay = 0, + className, +}: { + children: React.ReactNode; + delay?: number; + className?: string; +}) { + const reduce = useReducedMotion(); + if (reduce) return
{children}
; + return ( + + + {children} + + + ); +} diff --git a/website/components/Section.tsx b/website/components/Section.tsx new file mode 100644 index 0000000..4aae702 --- /dev/null +++ b/website/components/Section.tsx @@ -0,0 +1,35 @@ +import { cn } from "@/lib/cn"; +import { Fragment } from "react"; + +interface Props { + id?: string; + children: React.ReactNode; + className?: string; + theme?: "dark" | "light"; +} + +export function Section({ + id, + children, + className = "", + theme = "light", +}: Props) { + return ( +
+
+ {children} +
+
+
+ ); +} diff --git a/website/components/index.ts b/website/components/index.ts new file mode 100644 index 0000000..238dc3a --- /dev/null +++ b/website/components/index.ts @@ -0,0 +1,3 @@ +export { Dots } from "./Dots"; +export { Reveal } from "./Reveal"; +export { Section } from "./Section"; diff --git a/website/components/sections/cost.tsx b/website/components/sections/cost.tsx new file mode 100644 index 0000000..200b694 --- /dev/null +++ b/website/components/sections/cost.tsx @@ -0,0 +1,117 @@ +import { Section } from "@/components"; + +export function Cost() { + return ( +
+
+

+ Scale usage without scaling the bill.{" "} + + A flat license, with queries that are never metered. + +

+
+ + + Pay per query or compute credits + + + + Amp, flat license + +
+ {/*
+ {STATS.map(([value, label]) => ( +
+
{value}
+
{label}
+
+ ))} +
*/} +
+ +
+
+ + + + + + + breakeven + + + queries + +
+
+ ); +} + +// Pay-per-query cost as a cubic in a 100 by 100 box, y measured from the top. +const P = [ + [0, 95], + [45, 95], + [72, 58], + [100, 4], +] as const; +const CURVE = `M${P[0].join(" ")} C${P[1].join(" ")} ${P[2].join( + " ", +)} ${P[3].join(" ")}`; +const AREA = Array.from({ length: 49 }, (_, i) => { + const t = i / 48; + const u = 1 - t; + const at = (k: 0 | 1) => + u ** 3 * P[0][k] + + 3 * u * u * t * P[1][k] + + 3 * u * t * t * P[2][k] + + t ** 3 * P[3][k]; + return `${at(0).toFixed(2)}% ${at(1).toFixed(2)}%`; +}) + .concat("100% 100%", "0% 100%") + .join(", "); +const FLAT = 80; +const BREAKEVEN = 44.6; + +const STATS = [ + ["Flat", "license fee, agreed up front"], + ["0", "charges per query or per dataset"], + ["5×", "smaller at rest than BigQuery"], + ["Yours", "hardware, in your cloud or on-prem"], +]; diff --git a/website/components/sections/cta.tsx b/website/components/sections/cta.tsx new file mode 100644 index 0000000..38a16fc --- /dev/null +++ b/website/components/sections/cta.tsx @@ -0,0 +1,64 @@ +import { Button, ButtonGroup, CodeBlock } from "@edgeandnode/eds-react"; +import { Dots } from "@/components"; +import { INSTALL } from "@/data/constants"; + +export function CTA() { + return ( +
+ +
+

+ Get started with Amp +

+
+ {ITEMS.map((c, i) => ( +
+ {c.title} + {c.body} + {i === 0 ? ( + + {INSTALL} + + ) : null} + {c.cta ? ( + + + + ) : null} +
+ ))} +
+
+
+ ); +} + +const ITEMS: { title: string; body: string; cta?: string; href?: string }[] = [ + { + title: "Install it", + body: "One script installs ampup and the latest ampd.", + }, + { + title: "See it running", + body: "Live heads, a streaming feed, and a dataset catalog.", + cta: "Open the preview", + href: "#live", + }, + { + title: "Talk to the team", + body: "Questions, a demo, or an operated deployment.", + cta: "Talk to the team", + href: "https://edgeandnode.com/contact", + }, +]; diff --git a/website/components/sections/docs.tsx b/website/components/sections/docs.tsx new file mode 100644 index 0000000..c6e31cd --- /dev/null +++ b/website/components/sections/docs.tsx @@ -0,0 +1,93 @@ +import { Link, TabSet } from "@edgeandnode/eds-react"; +import { Section } from "@/components"; + +export function Docs() { + return ( +
+

Docs and references

+ + + {TABS.map((t) => ( + + {t.label} + + ))} + + + {TABS.map((t) => ( + + {t.items.map(([title, body]) => ( + + + {title} + + {body} + + ))} + + ))} + + +
+ ); +} + +const TABS = [ + { + value: "start", + label: "Get started", + items: [ + ["Quickstart", "Seven commands from nothing to a SQL result."], + [ + "Operational modes", + "solo, server, controller, worker, and what each one runs.", + ], + [ + "Configuration", + "Storage, services, PostgreSQL, and environment overrides.", + ], + ], + }, + { + value: "reference", + label: "Reference", + items: [ + [ + "Table schemas", + "Every column of every provider kind, with Arrow types.", + ], + ["Reorg protocol", "What app_metadata carries and how a client resumes."], + [ + "Decode functions", + "evm_decode_log, evm_decode_params, Borsh, SCALE, XDR.", + ], + ], + }, + { + value: "agents", + label: "For agents", + items: [ + [ + "Shipped skills", + "amp-setup, amp-providers, amp-datasets, amp-query, and four more.", + ], + [ + "Retrieval docs", + "Feature docs written to be loaded by an agent before it acts.", + ], + [ + "Deterministic queries", + "Pinned versions return the same answer every time.", + ], + ], + }, +]; diff --git a/website/components/sections/engine.tsx b/website/components/sections/engine.tsx new file mode 100644 index 0000000..a93e13e --- /dev/null +++ b/website/components/sections/engine.tsx @@ -0,0 +1,426 @@ +import { useEffect, useRef, useState } from "react"; +import { + AnimatePresence, + LazyMotion, + domMax, + m, + useInView, + useReducedMotion, +} from "motion/react"; +import { Button, ButtonGroup } from "@edgeandnode/eds-react"; +import { + ArrowRightIcon, + ArrowsClockwiseIcon, + BracketsCurlyIcon, + ClockCounterClockwiseIcon, + DotsThreeOutlineIcon, + GitBranchIcon, + ShieldCheckIcon, +} from "@edgeandnode/eds-react/icons"; +import { Dots, Reveal, Section } from "@/components"; +import { LINKS } from "@/data/constants"; + +const STEP = 1100; +const HOLD = 1800; +const EASE = [0.25, 0.1, 0.25, 1] as const; + +export function Engine() { + const reduce = useReducedMotion(); + const ref = useRef(null); + const inView = useInView(ref, { amount: 0.3 }); + const [active, setActive] = useState(0); + const [step, setStep] = useState(0); + const [run, setRun] = useState(0); + const playing = inView && !reduce; + const problem = PROBLEMS[active]!; + const last = problem.steps.length - 1; + + useEffect(() => { + if (!playing) return; + if (step < last) { + const t = setTimeout(() => setStep((s) => s + 1), STEP); + return () => clearTimeout(t); + } + const t = setTimeout(() => { + setActive((a) => (a + 1) % PROBLEMS.length); + setStep(0); + setRun((r) => r + 1); + }, HOLD); + return () => clearTimeout(t); + }, [playing, step, last]); + + const select = (i: number) => { + setActive(i); + setStep(0); + setRun((r) => r + 1); + }; + + return ( +
+ +

+ Chain data fails in ways a warehouse never sees.{" "} + + Amp handles every one of them below the SQL. + +

+ + + +
+ +
+
    + {PROBLEMS.map(({ icon: Icon, title }, i) => { + const open = i === active; + return ( + + + {open ? ( +
    + {PROBLEMS.map((p, j) => ( + + {p.body} + + ))} +
    + ) : null} + {open && playing ? ( + + ) : null} +
    + ); + })} +
+
+
+

+ {problem.caption} +

+ +
    + + {problem.steps[reduce ? last : step]!.map((r) => { + const t = TONE[r.tone]; + return ( + + + {r.k} + {r.v ? ( + + {r.v} + + ) : null} + + {r.status} + + + ); + })} + +
+
+
+
+
+
+ ); +} + +type Tone = "ok" | "warn" | "bad" | "muted" | "brand"; +type Row = { id: string; k: string; v?: string; status: string; tone: Tone }; + +const TONE: Record = { + ok: { + dot: "bg-status-success-default", + text: "text-status-success-default", + row: "border-subtle bg-canvas", + }, + warn: { + dot: "bg-status-warning-default", + text: "text-status-warning-default", + row: "border-status-warning-muted bg-status-warning-subtle", + }, + bad: { + dot: "bg-status-error-default", + text: "text-status-error-default", + row: "border-status-error-muted bg-status-error-subtle", + }, + muted: { + dot: "bg-foam-700", + text: "text-muted", + row: "border-dashed border-subtle bg-canvas", + }, + brand: { + dot: "bg-brand-500", + text: "text-brand-800", + row: "border-brand-muted bg-brand-subtlest", + }, +}; + +const row = + (tone: Tone) => + (id: string, k: string, status: string, v?: string): Row => ({ + id, + k, + v, + status, + tone, + }); +const ok = row("ok"); +const warn = row("warn"); +const bad = row("bad"); +const muted = row("muted"); +const brand = row("brand"); + +const PROBLEMS = [ + { + icon: GitBranchIcon, + title: "Reorgs", + body: "Every file and microbatch carries hash-linked block ranges. A fork is detected from the hashes, the orphaned range is invalidated with an explicit signal, and consumers replay the corrected range.", + caption: "stream, mainnet blocks", + steps: [ + [ok("a", "25,931,398", "committed", "to 401")], + [ + ok("a", "25,931,398", "committed", "to 401"), + ok("b", "25,931,402", "committed", "to 405"), + ], + [ + ok("a", "25,931,398", "committed", "to 401"), + ok("b", "25,931,402", "committed", "to 405"), + ok("c", "25,931,406", "committed", "to 409"), + ], + [ + ok("a", "25,931,398", "committed", "to 401"), + ok("b", "25,931,402", "committed", "to 405"), + bad("c", "25,931,406", "prev_hash mismatch", "to 409"), + ], + [ + ok("a", "25,931,398", "committed", "to 401"), + ok("b", "25,931,402", "committed", "to 405"), + brand("d", "25,931,406", "replayed", "to 408"), + ], + [ + ok("a", "25,931,398", "committed", "to 401"), + ok("b", "25,931,402", "committed", "to 405"), + ok("d", "25,931,406", "committed", "to 408"), + ok("e", "25,931,409", "committed", "to 412"), + ], + ], + }, + { + icon: DotsThreeOutlineIcon, + title: "Skipped slots and gaps", + body: "Block numbers are not required to be dense. Continuity is checked on the hash chain, so a Solana slot that never existed is not a hole in your data.", + caption: "extract, solana slots", + steps: [ + [ok("a", "445,218,930", "hash ok")], + [ok("a", "445,218,930", "hash ok"), ok("b", "445,218,931", "hash ok")], + [ + ok("a", "445,218,930", "hash ok"), + ok("b", "445,218,931", "hash ok"), + muted("c", "445,218,932", "skipped", "no block"), + ], + [ + ok("a", "445,218,930", "hash ok"), + ok("b", "445,218,931", "hash ok"), + muted("c", "445,218,932", "skipped", "no block"), + ok("d", "445,218,933", "hash ok", "parent 931"), + ], + [ + ok("a", "445,218,930", "hash ok"), + ok("b", "445,218,931", "hash ok"), + muted("c", "445,218,932", "skipped", "no block"), + ok("d", "445,218,933", "hash ok", "parent 931"), + ok("e", "445,218,934", "hash ok"), + ], + ], + }, + { + icon: ShieldCheckIcon, + title: "Bad provider data", + body: "With --verify, extraction recomputes Ethereum header hashes and Merkle-Patricia roots and checks Solana chain integrity. A wrong transaction from an RPC fails verification instead of landing in a table.", + caption: "extract with verify, mainnet", + steps: [ + [ok("a", "25,931,402", "header ok", "roots ok")], + [ + ok("a", "25,931,402", "header ok", "roots ok"), + ok("b", "25,931,403", "header ok", "roots ok"), + ], + [ + ok("a", "25,931,402", "header ok", "roots ok"), + ok("b", "25,931,403", "header ok", "roots ok"), + bad("c", "25,931,404", "root mismatch", "rpc 2"), + ], + [ + ok("a", "25,931,402", "header ok", "roots ok"), + ok("b", "25,931,403", "header ok", "roots ok"), + warn("c", "25,931,404", "refetching", "rpc 1"), + ], + [ + ok("a", "25,931,402", "header ok", "roots ok"), + ok("b", "25,931,403", "header ok", "roots ok"), + ok("c", "25,931,404", "header ok", "roots ok"), + ], + [ + ok("a", "25,931,402", "header ok", "roots ok"), + ok("b", "25,931,403", "header ok", "roots ok"), + ok("c", "25,931,404", "header ok", "roots ok"), + ok("d", "25,931,405", "header ok", "roots ok"), + ], + ], + }, + { + icon: ArrowsClockwiseIcon, + title: "Backfills that die halfway", + body: "Backfills detect already-extracted ranges and continue from there. Streams checkpoint with cursors and resume without gaps or duplicates.", + caption: "backfill, base from genesis", + steps: [ + [ok("a", "0", "done", "to 12,000,000")], + [ + ok("a", "0", "done", "to 12,000,000"), + ok("b", "12,000,000", "done", "to 24,000,000"), + ], + [ + ok("a", "0", "done", "to 12,000,000"), + ok("b", "12,000,000", "done", "to 24,000,000"), + brand("c", "24,000,000", "extracting", "to 36,000,000"), + ], + [ + ok("a", "0", "done", "to 12,000,000"), + ok("b", "12,000,000", "done", "to 24,000,000"), + bad("c", "24,000,000", "disconnected", "at 29,417,208"), + ], + [ + ok("a", "0", "done", "to 12,000,000"), + ok("b", "12,000,000", "done", "to 24,000,000"), + warn("c", "29,417,208", "resumed", "to 36,000,000"), + ], + [ + ok("a", "0", "done", "to 12,000,000"), + ok("b", "12,000,000", "done", "to 24,000,000"), + ok("c", "24,000,000", "done", "to 36,000,000"), + brand("d", "36,000,000", "extracting", "to head"), + ], + ], + }, + { + icon: BracketsCurlyIcon, + title: "Decoding", + body: "ABI, Borsh, Anchor, SCALE, and XDR decode inside the query. A new event signature is a new query, with no re-index.", + caption: "query, decode at read time", + steps: [ + [muted("a", "0xddf252ad1be2c89b", "raw log", "topic0")], + [ok("a", "Transfer", "abi", "1,250.00 USDC")], + [ + ok("a", "Transfer", "abi", "1,250.00 USDC"), + muted("b", "0xc42079f94a635580", "raw log", "topic0"), + ], + [ + ok("a", "Transfer", "abi", "1,250.00 USDC"), + ok("b", "Swap", "abi", "3.2 ETH for 9,870 USDC"), + ], + [ + ok("a", "Transfer", "abi", "1,250.00 USDC"), + ok("b", "Swap", "abi", "3.2 ETH for 9,870 USDC"), + muted("c", "AwAAAGRlcG9zaXQ", "raw data", "borsh"), + ], + [ + ok("a", "Transfer", "abi", "1,250.00 USDC"), + ok("b", "Swap", "abi", "3.2 ETH for 9,870 USDC"), + ok("c", "Deposit", "borsh", "42.5 SOL"), + ], + ], + }, + { + icon: ClockCounterClockwiseIcon, + title: "Reproducing last quarter's number", + body: "Datasets are immutable revisions with atomic activation. Old revisions stay for point-in-time recovery, and an as-of query over a pinned version returns the same answer every time.", + caption: "query, as of revision 12", + steps: [ + [ok("a", "run 1", "revision 12", "4,397,210.18")], + [ + ok("a", "run 1", "revision 12", "4,397,210.18"), + ok("b", "run 2", "revision 12", "4,397,210.18"), + ], + [ + ok("a", "run 1", "revision 12", "4,397,210.18"), + ok("b", "run 2", "revision 12", "4,397,210.18"), + warn("r", "revision 13", "activated", "new data"), + ], + [ + ok("a", "run 1", "revision 12", "4,397,210.18"), + ok("b", "run 2", "revision 12", "4,397,210.18"), + warn("r", "revision 13", "activated", "new data"), + ok("c", "run 3", "revision 12", "4,397,210.18"), + ], + [ + ok("a", "run 1", "revision 12", "4,397,210.18"), + ok("b", "run 2", "revision 12", "4,397,210.18"), + warn("r", "revision 13", "activated", "new data"), + ok("c", "run 3", "revision 12", "4,397,210.18"), + brand("d", "run 4", "identical", "4,397,210.18"), + ], + ], + }, +]; diff --git a/website/components/sections/features.tsx b/website/components/sections/features.tsx new file mode 100644 index 0000000..b4b91ab --- /dev/null +++ b/website/components/sections/features.tsx @@ -0,0 +1,173 @@ +import { CodeBlock, Status } from "@edgeandnode/eds-react"; +import { + ArrowsClockwiseIcon, + FingerprintIcon, + PlugsConnectedIcon, + PulseIcon, + RobotIcon, +} from "@edgeandnode/eds-react/icons"; +import { Section } from "@/components"; +import { useHeads } from "@/lib/use-heads"; + +export function Features() { + const mainnet = useHeads().find((h) => h.network === "mainnet")!; + + return ( +
+
    + {FACTS.map(({ icon: Icon, title, body }) => ( +
  • + + + {title} + {body} + +
  • + ))} +
+

+ Every chain as tables.{" "} + Ready for the tools you run. +

+ + {STEPS.map((step, i) => ( +
+
+ 0{i + 1} +

{step.title}

+

{step.body}

+
+
+ + {step.code} + + {step.output} + {i === 0 ? ( +

+ + genesis to {mainnet.ampHead.toLocaleString("en-US")},{" "} + {mainnet.lagMs} ms behind the head +

+ ) : null} +
+
+ ))} +
+ ); +} + +const FACTS = [ + { + icon: PulseIcon, + title: "It follows the head.", + body: "Under a second behind the chain, on every network you name.", + }, + { + icon: PlugsConnectedIcon, + title: "Your tools keep working.", + body: "Flight SQL, ADBC, and Parquet that any engine reads.", + }, + { + icon: ArrowsClockwiseIcon, + title: "Reorgs replay themselves.", + body: "Hash-linked ranges drop orphaned blocks and resend the right ones.", + }, + { + icon: FingerprintIcon, + title: "Every answer repeats.", + body: "A pinned revision returns the same result every time.", + }, + { + icon: RobotIcon, + title: "Agents use the same CLI.", + body: "Skills for ampctl and ampsql ship with Amp.", + }, +]; + +const QUERY = `SELECT + CAST(date_trunc('day', timestamp) AS DATE) AS day, + count(*) AS transfers +FROM "acme/eth_mainnet".logs +WHERE topic0 = evm_topic('Transfer(address indexed from, address indexed to, uint256 value)') +GROUP BY 1 +ORDER BY 1 DESC +LIMIT 5`; + +const STEPS: { + title: string; + body: string; + file: string; + lang: "toml" | "sql" | "py"; + code: string; + outputLabel: string; + output: string; +}[] = [ + { + title: "Extract", + body: "A provider is a TOML file with a kind, a network, and a URL. Amp generates the tables from it, syncs genesis to head, and checks every header hash on the way in.", + file: "mainnet.toml", + lang: "toml", + code: `kind = "evm-rpc" +network = "mainnet" +url = "https://ethereum-rpc.example.com"`, + outputLabel: '"acme/eth_mainnet".blocks', + output: `+------------------+-------------------------------+ +| column_name | data_type | ++------------------+-------------------------------+ +| block_num | UInt64 | +| timestamp | Timestamp(Nanosecond, +00:00) | +| hash | FixedSizeBinary(32) | +| parent_hash | FixedSizeBinary(32) | +| miner | FixedSizeBinary(20) | +| gas_used | UInt64 | +| base_fee_per_gas | Decimal128(38, 0) | ++------------------+-------------------------------+ +19 more columns, plus transactions and logs`, + }, + { + title: "Query and stream", + body: "Standard SQL over Arrow Flight. Events decode inside the query, so a new event signature needs no re-index. Add SETTINGS stream = true and the same statement streams in block order.", + file: "transfers.sql", + lang: "sql", + code: QUERY, + outputLabel: "ampsql", + output: `+------------+-----------+ +| day | transfers | ++------------+-----------+ +| 2026-09-22 | 1184302 | +| 2026-09-21 | 1209877 | +| 2026-09-20 | 1151640 | +| 2026-09-19 | 1098215 | +| 2026-09-18 | 1236004 | ++------------+-----------+`, + }, + { + title: "Deliver", + body: "The same result lands in Polars as zero-copy Arrow, or in a Snowflake or Postgres table through an ADBC export job, exactly once.", + file: "notebook.py", + lang: "py", + code: `df = client.sql(q).to_polars() + +# or keep a warehouse table in sync +client.sql(q).load(connection=sf, destination="raw.transfers_daily")`, + outputLabel: "df", + output: `shape: (5, 2) +┌────────────┬───────────┐ +│ day ┆ transfers │ +│ --- ┆ --- │ +│ date ┆ u64 │ +╞════════════╪═══════════╡ +│ 2026-09-22 ┆ 1184302 │ +│ 2026-09-21 ┆ 1209877 │ +│ 2026-09-20 ┆ 1151640 │ +│ 2026-09-19 ┆ 1098215 │ +│ 2026-09-18 ┆ 1236004 │ +└────────────┴───────────┘`, + }, +]; diff --git a/website/components/sections/freshness.tsx b/website/components/sections/freshness.tsx new file mode 100644 index 0000000..f7a5709 --- /dev/null +++ b/website/components/sections/freshness.tsx @@ -0,0 +1,105 @@ +import { Section } from "@/components"; + +const HOURS = 7; + +export function Freshness() { + return ( +
+
+

+ Under 3 minutes behind the head.{" "} + + Derived Solana tables elsewhere trail by an hour or more. + +

+

+ Vendor figures from their published documentation. +

+
+ +
+
+ {Array.from({ length: HOURS + 1 }, (_, h) => ( + + {h === 0 ? "chain head" : `${h}h`} + + ))} +
+
+ {LANES.map((l) => ( +
+ + + {l.name} + + + {l.label} + + + + + {/* {l.to ? ( + + ) : null} */} + + {l.note} +
+ ))} +
+
+
+ ); +} + +const LANES = [ + { + name: "Amp", + label: "under 3 minutes", + note: "", + from: 3, + amp: true, + }, + { + name: "Allium", + label: "1 hour", + note: "Documented for most enriched historical tables", + from: 60, + }, + { + name: "Dune", + label: "6 to 7 hours", + note: "Documented for Solana DEX trades and token transfers tables", + from: 360, + to: 420, + }, +]; diff --git a/website/components/sections/hero.tsx b/website/components/sections/hero.tsx new file mode 100644 index 0000000..85c0162 --- /dev/null +++ b/website/components/sections/hero.tsx @@ -0,0 +1,64 @@ +import { LINKS } from "@/data/constants"; +import { Button } from "@edgeandnode/eds-react"; +import { Dots, Reveal, Section } from "@/components"; + +export function Hero() { + return ( +
+ +
+
+

+ + Amp · the blockchain native database +

+

+ + Blockchain data that behaves {" "} + like the rest of your stack. + +

+

+ Amp turns any RPC endpoint into Parquet you own and SQL you already + know. Under a second behind the head, correct through reorgs, from + one binary that runs on your machine, in your cloud, or operated by + Edge & Node. +

+
+ +

+ Running Amp in production needs a license. The team sets it up + with you. +

+
+
+ +
+ {STATS.items.map(({ label, description }) => ( +
+
{label}
+
{description}
+
+ ))} +
+
+
+ ); +} + +const STATS = { + items: [ + { label: "747 ms", description: "median freshness behind the chain head" }, + { + label: "4,397×", + description: "peak query speedup against BigQuery and RPC", + }, + { + label: "5×", + description: "smaller at rest than BigQuery's public Solana dataset", + }, + { label: "2", description: "services to run besides ampd" }, + ], +}; diff --git a/website/components/sections/how.tsx b/website/components/sections/how.tsx new file mode 100644 index 0000000..6969500 --- /dev/null +++ b/website/components/sections/how.tsx @@ -0,0 +1,249 @@ +import { useReducedMotion } from "motion/react"; +import { AmpLogoIcon } from "@edgeandnode/eds-react/icons"; +import { + NetworkArbitrumOne, + NetworkBase, + NetworkEthereum, + NetworkOptimism, + NetworkPolygon, + NetworkSolana, +} from "@web3icons/react"; +import { Reveal, Section } from "@/components"; +import { INTEGRATIONS } from "@/data/integrations"; +import { CodeInline } from "@edgeandnode/eds-react"; + +export function How() { + const reduce = useReducedMotion(); + return ( +
+ +

+ Pull any chain into the tools you already run. +

+

+ Amp extracts every block, transaction, and log from the chains you + point it at, keeps them as Parquet in your bucket, and serves them as + SQL to whatever you query with today. +

+
+ +
+
+ + + + + + + {ROWS.map((y, i) => ( + + {[inPath(y), outPath(y)].map((d, k) => ( + + + {reduce ? null : } + + ))} + + ))} + + + + extract and verify + + + query or stream + + + {CHAINS.map(([Icon, name], i) => ( +
+ + {name} +
+ ))} + +
+ + + + Amp + + + Parquet in your bucket + SQL over Arrow Flight + +
+ + {TOOLS.map((t, i) => ( +
+ + + + {t.name} +
+ ))} +
+ +
+
+ {CHAINS.map(([Icon, name]) => ( + + + {name} + + ))} +
+ + ↓ extract and verify + +
+ + Amp +
+ + ↓ query or stream + +
+ {TOOLS.map((t) => ( + + + + + {t.name} + + ))} +
+
+
+
+ {VERBS.map(([verb, rest]) => ( +

+ {verb} {rest} +

+ ))} +
+
+
+ ); +} + +// A light beam along a path: a bright head and a blurred trail, both dashes +// on a path normalised to length 1. Every layer's leading edge travels from +// the start to past the end (1.22, the longest trail) in the same time. +function Beam({ d, begin }: { d: string; begin: number }) { + const run = (len: number, extra = {}) => ( + + + + ); + return ( + <> + {run(0.22, { + strokeWidth: 4, + strokeOpacity: 0.35, + filter: "url(#beam-glow)", + })} + {run(0.14, { strokeWidth: 1.5, strokeOpacity: 0.5 })} + {run(0.04, { strokeWidth: 2 })} + + ); +} + +// Row centres in the 1000 by 440 drawing. Amp sits at the middle, x 400 to 600. +const ROWS = [40, 112, 184, 256, 328, 400]; +const inPath = (y: number) => `M190 ${y} C300 ${y} 300 220 400 220`; +const outPath = (y: number) => `M600 220 C700 220 700 ${y} 810 ${y}`; + +const CHAINS = [ + [NetworkEthereum, "Ethereum"], + [NetworkBase, "Base"], + [NetworkSolana, "Solana"], + [NetworkArbitrumOne, "Arbitrum"], + [NetworkOptimism, "Optimism"], + [NetworkPolygon, "Polygon"], +] as const; + +const TOOLS = [ + "Snowflake", + "ClickHouse", + "Postgres", + "Databricks", + "Apache Kafka", + "Grafana", +].map((name) => { + const it = INTEGRATIONS.flatMap((g) => g.items).find((x) => x.name === name)!; + return { name, path: it.path! }; +}); + +const VERBS = [ + [ + "extract", + "every block, transaction, and log from the chains you name, verified against their own hashes", + ], + [ + "query", + "with standard SQL over Arrow Flight, decoding ABI, Borsh, SCALE, and XDR at query time", + ], + [ + "stream", + "any query as microbatches that replay on reorg and resume from a cursor", + ], +]; diff --git a/website/components/sections/index.ts b/website/components/sections/index.ts new file mode 100644 index 0000000..2279c50 --- /dev/null +++ b/website/components/sections/index.ts @@ -0,0 +1,14 @@ +export { Hero } from "./hero"; +export { LiveSection } from "./live"; +export { CTA } from "./cta"; +export { Engine } from "./engine"; +export { Features } from "./features"; +export { How } from "./how"; +export { Integrations } from "./integrations"; +export { Proof } from "./proof"; +export { Cost } from "./cost"; +export { Storage } from "./storage"; +export { Freshness } from "./freshness"; +export { Try } from "./try"; +export { Docs } from "./docs"; +export { License } from "./license"; diff --git a/website/components/sections/integrations.tsx b/website/components/sections/integrations.tsx new file mode 100644 index 0000000..d6ac107 --- /dev/null +++ b/website/components/sections/integrations.tsx @@ -0,0 +1,58 @@ +import { Tag } from "@edgeandnode/eds-react"; +import { Reveal, Section } from "@/components"; +import { INTEGRATIONS } from "@/data/integrations"; + +export function Integrations() { + return ( +
+ +

+ Drops into the stack you already run +

+
+
+ {INTEGRATIONS.map((group) => ( +
+

+ {GROUPS[group.key]} +

+
+ {group.items.map((it) => ( + + + + ) : undefined + } + > + {it.name} + + ))} +
+
+ ))} +
+
+ ); +} + +const GROUPS: Record = { + warehouses: "Data warehouses", + lakes: "Data lakes and storage", + bi: "BI and analytics", + aiml: "AI and ML", + streaming: "Streaming and serving", + observability: "Observability", +}; diff --git a/website/components/sections/license.tsx b/website/components/sections/license.tsx new file mode 100644 index 0000000..4564d21 --- /dev/null +++ b/website/components/sections/license.tsx @@ -0,0 +1,59 @@ +import { Button, ButtonGroup } from "@edgeandnode/eds-react"; +import { ArrowRightIcon } from "@edgeandnode/eds-react/icons"; +import { Dots, Reveal } from "@/components"; +import { LINKS } from "@/data/constants"; + +export function License() { + return ( +
+ +
+ +

+ Running Amp in production needs a license.{" "} + The team sets it up with you. +

+ + + +
+
+ {TERMS.map(([title, body]) => ( +
+
{title}
+
{body}
+
+ ))} +
+
+
+ ); +} + +const TERMS = [ + [ + "Flat license", + "Unlimited queries. Nothing is metered per query or per dataset.", + ], + [ + "Your cloud or on-prem", + "Parquet stays in your bucket and PostgreSQL stays on your network.", + ], + [ + "Or operated by Edge & Node", + "The same binary, run for you by the team behind The Graph.", + ], +]; diff --git a/website/components/sections/live.tsx b/website/components/sections/live.tsx new file mode 100644 index 0000000..c6b00d8 --- /dev/null +++ b/website/components/sections/live.tsx @@ -0,0 +1,17 @@ +import { Reveal, Section } from "@/components"; +import Live from "../Live"; + +export function LiveSection() { + return ( +
+ +

+ Under a second behind the head. +

+
+
+ +
+
+ ); +} diff --git a/website/components/sections/proof.tsx b/website/components/sections/proof.tsx new file mode 100644 index 0000000..d77479e --- /dev/null +++ b/website/components/sections/proof.tsx @@ -0,0 +1,274 @@ +import { Button, ButtonGroup, Table } from "@edgeandnode/eds-react"; +import { ArrowRightIcon } from "@edgeandnode/eds-react/icons"; +import { LINKS } from "@/data/constants"; +import { Reveal, Section } from "@/components"; + +export function Proof() { + return ( +
+ +

+ Owning the engine pays off +

+

+ We compared Amp with hosted vendors on storage, freshness, and cost. +

+
+ {ROWS.map((r) => ( +
+ +

+ {r.title} +

+

{r.body}

+

{r.note}

+ {r.cta ? ( + + + + ) : null} +
+ + {r.chart} + +
+ ))} +
+ + + + Amp + Hosted vendors + + + {COMPARE.map(([k, amp, hosted]) => ( + + {k} + + {amp} + + {hosted} + + ))} + +
+
+
+ ); +} + +function Bars({ + rows, + max, +}: { + rows: { name: string; value: number; label: string; note?: string }[]; + max: number; +}) { + return ( +
+ {rows.map((r) => { + const amp = r.name === "Amp"; + return ( +
+
+ {r.name} +
+
+
+ + + {r.label} + +
+ {r.note ? ( + {r.note} + ) : null} +
+
+ ); + })} +
+ ); +} + +// Breakeven and flat-line position, in percent of the plot box. +const BX = 15.5; +const FY = 63; +const CURVE = "M0 100 Q23 21 100 5.3"; + +const ROWS: { + title: string; + body: string; + note: string; + cta?: string; + chart: React.ReactNode; +}[] = [ + { + title: "5× smaller at rest", + body: "Amp keeps raw blockchain data in compact encoded form at rest and decodes it at query time, instead of permanently expanding it into wide tables.", + note: "Public Solana tables, same coverage window.", + chart: ( + + ), + }, + { + title: "Under 3 minutes on derived Solana data", + body: "How far behind the chain head a derived Solana table sits by the time it is queryable.", + note: "Vendor figures from their published documentation.", + chart: ( + + ), + }, + { + title: "Scale usage without scaling the bill", + cta: "Price your workload", + body: "Flat license fee. Unlimited usage on hardware you own. No vendor lock-in.", + note: "", + chart: ( +
+
+ + + Pay per query or compute credits + + + + Amp, flat license + +
+
+ Cost +
+ + + + + + + + + + + + + + Breakeven + + + Savings at scale + +
+ Number of queries +
+
+ ), + }, +]; + +const COMPARE = [ + ["Raw data freshness", "Under 1 second", "Seconds to over an hour"], + ["Derived Solana freshness", "Under 3 minutes", "1 hour to 7 hours"], + [ + "Storage at rest", + "≈159 TB for all of Solana", + "~800 TB for the same chain in BigQuery", + ], + ["Deployment", "Your cloud or on-prem", "Hosted only"], + [ + "Billing", + "Flat license, unlimited queries", + "Per query, per dataset, or credits", + ], + ["Pipeline visibility", "The SQL of every pipeline, and the logs", "Limited"], + ["Chain coverage", "Any EVM or SVM chain, Canton, others", "Fixed list"], +]; diff --git a/website/components/sections/storage.tsx b/website/components/sections/storage.tsx new file mode 100644 index 0000000..f46a0a8 --- /dev/null +++ b/website/components/sections/storage.tsx @@ -0,0 +1,55 @@ +import { Section } from "@/components"; + +// Squares drawn to scale by area: side = sqrt(159 / 800). +const SIDE = `${(Math.sqrt(159 / 800) * 100).toFixed(1)}%`; + +export function Storage() { + return ( +
+
+
+

+ 5× smaller at rest.{" "} + + Raw data stays encoded and decodes at query time. + +

+
+

+ Amp keeps raw blockchain data in compact encoded form instead of + expanding it into wide tables. The same Solana history takes a + fifth of the space. +

+

+ Public Solana tables, same coverage window. +

+
+
+ +
+
+ + BigQuery + ~800 TB + +
+ + Amp + + ≈159 TB + + +
+
+
+
+
+ ); +} diff --git a/website/components/sections/try.tsx b/website/components/sections/try.tsx new file mode 100644 index 0000000..59ea801 --- /dev/null +++ b/website/components/sections/try.tsx @@ -0,0 +1,209 @@ +import { useEffect, useState } from "react"; +import { + Button, + ButtonGroup, + Card, + CodeBlock, + Status, + ToggleButton, +} from "@edgeandnode/eds-react"; +import { ArrowSquareOutIcon } from "@edgeandnode/eds-react/icons"; +import { Reveal, Section } from "@/components"; +import { LINKS } from "@/data/constants"; +import type { Network } from "@/lib/amp-api"; + +const NETWORKS: { + id: Network; + label: string; + kind: string; + ds: string; + url: string; +}[] = [ + { + id: "mainnet", + label: "Ethereum", + kind: "evm-rpc", + ds: "eth_mainnet", + url: "https://ethereum-rpc.example.com", + }, + { + id: "base", + label: "Base", + kind: "evm-rpc", + ds: "base", + url: "https://base-rpc.example.com", + }, + { + id: "solana-mainnet", + label: "Solana", + kind: "solana", + ds: "solana_mainnet", + url: "https://solana-rpc.example.com", + }, +]; + +export function Try() { + const [net, setNet] = useState("mainnet"); + const [phase, setPhase] = useState<"idle" | "running" | "done">("idle"); + const [step, setStep] = useState(0); + const [pct, setPct] = useState(0); + const n = NETWORKS.find((x) => x.id === net)!; + + useEffect(() => { + if (phase !== "running") return; + setStep(0); + setPct(0); + const t0 = Date.now(); + const id = setInterval(() => { + const s = (Date.now() - t0) / 1000; + if (s < 0.8) setStep(0); + else if (s < 1.6) setStep(1); + else if (s < 5.2) { + setStep(2); + setPct(Math.min(100, Math.round(((s - 1.6) / 3.6) * 100))); + } else { + setStep(3); + setPct(100); + setPhase("done"); + clearInterval(id); + } + }, 80); + return () => clearInterval(id); + }, [phase]); + + const provider = [ + `kind = "${n.kind}"`, + `network = "${net}"`, + `url = "${n.url}"`, + `auth_token = "\${RPC_AUTH_TOKEN}"`, + ]; + const commands = [ + `ampctl provider register ${n.ds}_rpc ./${n.ds}.toml`, + `ampctl manifest generate --kind ${n.kind} --network ${net} --out ${n.ds}.json`, + `ampctl dataset register acme/${n.ds} ./${n.ds}.json --tag 1.0.0`, + `ampctl dataset deploy acme/${n.ds}@1.0.0${ + n.kind === "evm-rpc" ? " --verify ethereum" : "" + }`, + ]; + + return ( +
+ +

+ From an RPC endpoint to a streaming dataset +

+

+ Pick a network. The provider file, the manifest, and the deploy are + generated for you. This runs against a mock; the real flow needs an + account. +

+
+
+
+ + {NETWORKS.map((x) => ( + { + setNet(x.id); + setPhase("idle"); + }} + disabled={phase === "running"} + > + {x.label} + + ))} + + + + {provider.join("\n")} + + {commands.join("\n")} + +
+ +
    + {STEPS.map((label, i) => { + const state = + phase === "idle" + ? "pending" + : i < step || phase === "done" + ? "done" + : i === step + ? "active" + : "pending"; + return ( +
  1. + + + {label} + {i === 2 && state !== "pending" ? ( + + {pct}% + + ) : null} + +
  2. + ); + })} +
+ {phase === "done" ? ( +

+ Streaming. Every new block lands in the table within a second, and + a reorg replays the corrected range. +

+ ) : null} + + {phase === "done" ? ( + + ) : ( + + )} + +
+

+ Then run it on your own chains. +

+

+ The same flow on Amp Cloud, with your endpoints and your bucket. +

+ + + +
+
+
+
+ ); +} + +const STEPS = [ + "Provider registered", + "Manifest registered", + "Backfilling from genesis", + "Following the head", +]; diff --git a/website/data/constants.ts b/website/data/constants.ts new file mode 100644 index 0000000..f17ec20 --- /dev/null +++ b/website/data/constants.ts @@ -0,0 +1,8 @@ +export const LINKS = { + docs: "https://ampup.sh/docs", + edgeandnode: "https://edgeandnode.com", + contact: "https://edgeandnode.com/contact", +}; + +export const INSTALL = + "curl --proto '=https' --tlsv1.2 -sSf https://ampup.sh/install | sh"; diff --git a/website/data/integrations.ts b/website/data/integrations.ts new file mode 100644 index 0000000..374601a --- /dev/null +++ b/website/data/integrations.ts @@ -0,0 +1,79 @@ +// Monochrome marks from simple-icons (CC0), viewBox 0 0 24 24. +export type IntegrationItem = { name: string; path?: string }; +export type IntegrationGroup = { key: string; items: IntegrationItem[] }; + +export const INTEGRATIONS: IntegrationGroup[] = [ + { + key: "warehouses", + items: [ + { + name: "Snowflake", + path: "M24 3.459c0 .646-.418 1.18-1.141 1.18-.723 0-1.142-.534-1.142-1.18 0-.647.419-1.18 1.142-1.18.723 0 1.141.533 1.141 1.18zm-.228 0c0-.533-.38-.951-.913-.951s-.913.38-.913.95c0 .533.38.952.913.952.57 0 .913-.419.913-.951zm-1.37-.533h.495c.266 0 .456.152.456.38 0 .153-.076.229-.19.305l.19.266v.038h-.266l-.19-.266h-.229v.266h-.266zm.495.228h-.229v.267h.229c.114 0 .152-.038.152-.114.038-.077-.038-.153-.152-.153zM7.602 12.4c.038-.151.076-.304.076-.456 0-.114-.038-.228-.038-.342-.114-.343-.304-.647-.646-.838l-4.87-2.777c-.685-.38-1.56-.152-1.94.533-.381.685-.153 1.56.532 1.94l2.701 1.56-2.701 1.56c-.685.38-.913 1.256-.533 1.94.38.685 1.256.914 1.94.533l4.832-2.777c.343-.267.571-.533.647-.876zm1.332 2.626c-.266-.038-.57.038-.837.19l-4.832 2.777c-.685.38-.913 1.256-.532 1.94.38.686 1.255.914 1.94.533l2.701-1.56v3.12c0 .8.647 1.408 1.446 1.408.799 0 1.407-.647 1.407-1.408v-5.592c0-.761-.57-1.37-1.293-1.408zm4.946-6.088c.266.038.57-.038.837-.19l4.832-2.777c.685-.38.913-1.256.532-1.94-.38-.686-1.255-.914-1.94-.533l-2.701 1.56V1.975c0-.799-.647-1.408-1.446-1.408-.799 0-1.446.609-1.446 1.408V7.53c0 .76.609 1.37 1.332 1.407zM3.265 5.97l4.832 2.777c.266.152.533.19.837.19.723-.038 1.331-.684 1.331-1.407V1.975c0-.799-.646-1.408-1.407-1.408-.799 0-1.446.647-1.446 1.408v3.12l-2.701-1.56c-.685-.38-1.56-.152-1.94.533-.419.646-.19 1.521.494 1.902zm9.093 6.011a.412.412 0 00-.114-.266l-.57-.571a.346.346 0 00-.267-.114.412.412 0 00-.266.114l-.571.57a.411.411 0 00-.114.267c0 .076.038.19.114.267l.57.57a.345.345 0 00.267.114c.076 0 .19-.038.266-.114l.571-.57a.412.412 0 00.114-.267zm1.598.533L11.94 14.53c-.039.038-.153.114-.229.114h-.608a.411.411 0 01-.267-.114L8.82 12.514a.408.408 0 01-.076-.229v-.608c0-.076.038-.19.114-.267l2.016-2.016a.41.41 0 01.267-.114h.608a.41.41 0 01.267.114l2.016 2.016a.347.347 0 01.114.267v.608c-.076.077-.114.19-.19.229zm5.593 5.44l-4.832-2.777c-.266-.152-.57-.19-.837-.152-.723.038-1.332.684-1.332 1.408v5.554c0 .8.647 1.408 1.408 1.408.799 0 1.446-.647 1.446-1.408v-3.12l2.7 1.56c.686.38 1.561.152 1.941-.533.419-.646.19-1.521-.494-1.94zm2.549-7.533l-2.701 1.56 2.7 1.56c.686.38.914 1.256.533 1.94-.38.685-1.255.913-1.94.533l-4.832-2.778a1.644 1.644 0 01-.647-.798c-.037-.153-.076-.305-.076-.457 0-.114.039-.228.039-.342.114-.343.342-.647.646-.837l4.832-2.778c.685-.38 1.56-.152 1.94.533.457.609.19 1.484-.494 1.864", + }, + { + name: "ClickHouse", + path: "M21.333 10H24v4h-2.667ZM16 1.335h2.667v21.33H16Zm-5.333 0h2.666v21.33h-2.666ZM0 22.665V1.335h2.667v21.33zm5.333-21.33H8v21.33H5.333Z", + }, + { + name: "Postgres", + path: "M23.5594 14.7228a.5269.5269 0 0 0-.0563-.1191c-.139-.2632-.4768-.3418-1.0074-.2321-1.6533.3411-2.2935.1312-2.5256-.0191 1.342-2.0482 2.445-4.522 3.0411-6.8297.2714-1.0507.7982-3.5237.1222-4.7316a1.5641 1.5641 0 0 0-.1509-.235C21.6931.9086 19.8007.0248 17.5099.0005c-1.4947-.0158-2.7705.3461-3.1161.4794a9.449 9.449 0 0 0-.5159-.0816 8.044 8.044 0 0 0-1.3114-.1278c-1.1822-.0184-2.2038.2642-3.0498.8406-.8573-.3211-4.7888-1.645-7.2219.0788C.9359 2.1526.3086 3.8733.4302 6.3043c.0409.818.5069 3.334 1.2423 5.7436.4598 1.5065.9387 2.7019 1.4334 3.582.553.9942 1.1259 1.5933 1.7143 1.7895.4474.1491 1.1327.1441 1.8581-.7279.8012-.9635 1.5903-1.8258 1.9446-2.2069.4351.2355.9064.3625 1.39.3772a.0569.0569 0 0 0 .0004.0041 11.0312 11.0312 0 0 0-.2472.3054c-.3389.4302-.4094.5197-1.5002.7443-.3102.064-1.1344.2339-1.1464.8115-.0025.1224.0329.2309.0919.3268.2269.4231.9216.6097 1.015.6331 1.3345.3335 2.5044.092 3.3714-.6787-.017 2.231.0775 4.4174.3454 5.0874.2212.5529.7618 1.9045 2.4692 1.9043.2505 0 .5263-.0291.8296-.0941 1.7819-.3821 2.5557-1.1696 2.855-2.9059.1503-.8707.4016-2.8753.5388-4.1012.0169-.0703.0357-.1207.057-.1362.0007-.0005.0697-.0471.4272.0307a.3673.3673 0 0 0 .0443.0068l.2539.0223.0149.001c.8468.0384 1.9114-.1426 2.5312-.4308.6438-.2988 1.8057-1.0323 1.5951-1.6698zM2.371 11.8765c-.7435-2.4358-1.1779-4.8851-1.2123-5.5719-.1086-2.1714.4171-3.6829 1.5623-4.4927 1.8367-1.2986 4.8398-.5408 6.108-.13-.0032.0032-.0066.0061-.0098.0094-2.0238 2.044-1.9758 5.536-1.9708 5.7495-.0002.0823.0066.1989.0162.3593.0348.5873.0996 1.6804-.0735 2.9184-.1609 1.1504.1937 2.2764.9728 3.0892.0806.0841.1648.1631.2518.2374-.3468.3714-1.1004 1.1926-1.9025 2.1576-.5677.6825-.9597.5517-1.0886.5087-.3919-.1307-.813-.5871-1.2381-1.3223-.4796-.839-.9635-2.0317-1.4155-3.5126zm6.0072 5.0871c-.1711-.0428-.3271-.1132-.4322-.1772.0889-.0394.2374-.0902.4833-.1409 1.2833-.2641 1.4815-.4506 1.9143-1.0002.0992-.126.2116-.2687.3673-.4426a.3549.3549 0 0 0 .0737-.1298c.1708-.1513.2724-.1099.4369-.0417.156.0646.3078.26.3695.4752.0291.1016.0619.2945-.0452.4444-.9043 1.2658-2.2216 1.2494-3.1676 1.0128zm2.094-3.988-.0525.141c-.133.3566-.2567.6881-.3334 1.003-.6674-.0021-1.3168-.2872-1.8105-.8024-.6279-.6551-.9131-1.5664-.7825-2.5004.1828-1.3079.1153-2.4468.079-3.0586-.005-.0857-.0095-.1607-.0122-.2199.2957-.2621 1.6659-.9962 2.6429-.7724.4459.1022.7176.4057.8305.928.5846 2.7038.0774 3.8307-.3302 4.7363-.084.1866-.1633.3629-.2311.5454zm7.3637 4.5725c-.0169.1768-.0358.376-.0618.5959l-.146.4383a.3547.3547 0 0 0-.0182.1077c-.0059.4747-.054.6489-.115.8693-.0634.2292-.1353.4891-.1794 1.0575-.11 1.4143-.8782 2.2267-2.4172 2.5565-1.5155.3251-1.7843-.4968-2.0212-1.2217a6.5824 6.5824 0 0 0-.0769-.2266c-.2154-.5858-.1911-1.4119-.1574-2.5551.0165-.5612-.0249-1.9013-.3302-2.6462.0044-.2932.0106-.5909.019-.8918a.3529.3529 0 0 0-.0153-.1126 1.4927 1.4927 0 0 0-.0439-.208c-.1226-.4283-.4213-.7866-.7797-.9351-.1424-.059-.4038-.1672-.7178-.0869.067-.276.1831-.5875.309-.9249l.0529-.142c.0595-.16.134-.3257.213-.5012.4265-.9476 1.0106-2.2453.3766-5.1772-.2374-1.0981-1.0304-1.6343-2.2324-1.5098-.7207.0746-1.3799.3654-1.7088.5321a5.6716 5.6716 0 0 0-.1958.1041c.0918-1.1064.4386-3.1741 1.7357-4.4823a4.0306 4.0306 0 0 1 .3033-.276.3532.3532 0 0 0 .1447-.0644c.7524-.5706 1.6945-.8506 2.802-.8325.4091.0067.8017.0339 1.1742.081 1.939.3544 3.2439 1.4468 4.0359 2.3827.8143.9623 1.2552 1.9315 1.4312 2.4543-1.3232-.1346-2.2234.1268-2.6797.779-.9926 1.4189.543 4.1729 1.2811 5.4964.1353.2426.2522.4522.2889.5413.2403.5825.5515.9713.7787 1.2552.0696.087.1372.1714.1885.245-.4008.1155-1.1208.3825-1.0552 1.717-.0123.1563-.0423.4469-.0834.8148-.0461.2077-.0702.4603-.0994.7662zm.8905-1.6211c-.0405-.8316.2691-.9185.5967-1.0105a2.8566 2.8566 0 0 0 .135-.0406 1.202 1.202 0 0 0 .1342.103c.5703.3765 1.5823.4213 3.0068.1344-.2016.1769-.5189.3994-.9533.6011-.4098.1903-1.0957.333-1.7473.3636-.7197.0336-1.0859-.0807-1.1721-.151zm.5695-9.2712c-.0059.3508-.0542.6692-.1054 1.0017-.055.3576-.112.7274-.1264 1.1762-.0142.4368.0404.8909.0932 1.3301.1066.887.216 1.8003-.2075 2.7014a3.5272 3.5272 0 0 1-.1876-.3856c-.0527-.1276-.1669-.3326-.3251-.6162-.6156-1.1041-2.0574-3.6896-1.3193-4.7446.3795-.5427 1.3408-.5661 2.1781-.463zm.2284 7.0137a12.3762 12.3762 0 0 0-.0853-.1074l-.0355-.0444c.7262-1.1995.5842-2.3862.4578-3.4385-.0519-.4318-.1009-.8396-.0885-1.2226.0129-.4061.0666-.7543.1185-1.0911.0639-.415.1288-.8443.1109-1.3505.0134-.0531.0188-.1158.0118-.1902-.0457-.4855-.5999-1.938-1.7294-3.253-.6076-.7073-1.4896-1.4972-2.6889-2.0395.5251-.1066 1.2328-.2035 2.0244-.1859 2.0515.0456 3.6746.8135 4.8242 2.2824a.908.908 0 0 1 .0667.1002c.7231 1.3556-.2762 6.2751-2.9867 10.5405zm-8.8166-6.1162c-.025.1794-.3089.4225-.6211.4225a.5821.5821 0 0 1-.0809-.0056c-.1873-.026-.3765-.144-.5059-.3156-.0458-.0605-.1203-.178-.1055-.2844.0055-.0401.0261-.0985.0925-.1488.1182-.0894.3518-.1226.6096-.0867.3163.0441.6426.1938.6113.4186zm7.9305-.4114c.0111.0792-.049.201-.1531.3102-.0683.0717-.212.1961-.4079.2232a.5456.5456 0 0 1-.075.0052c-.2935 0-.5414-.2344-.5607-.3717-.024-.1765.2641-.3106.5611-.352.297-.0414.6111.0088.6356.1851z", + }, + ], + }, + { + key: "lakes", + items: [ + { name: "Apache Iceberg" }, + { name: "Delta Lake" }, + { name: "Amazon S3" }, + ], + }, + { + key: "bi", + items: [{ name: "Power BI" }, { name: "Tableau" }], + }, + { + key: "aiml", + items: [ + { + name: "Databricks", + path: "M.95 14.184L12 20.403l9.919-5.55v2.21L12 22.662l-10.484-5.96-.565.308v.77L12 24l11.05-6.218v-4.317l-.515-.309L12 19.118l-9.867-5.653v-2.21L12 16.805l11.05-6.218V6.32l-.515-.308L12 11.974 2.647 6.681 12 1.388l7.76 4.368.668-.411v-.566L12 0 .95 6.27v.72L12 13.207l9.919-5.55v2.26L12 15.52 1.516 9.56l-.565.308Z", + }, + { + name: "LangChain", + path: "M13.796 0a6.93 6.93 0 0 0-4.91 2.019L5.451 5.455l3.273 3.27 3.432-3.432a2.284 2.284 0 0 1 3.277 0 2.28 2.28 0 0 1 0 3.275L12 12.001l3.273 3.273 3.433-3.435c2.692-2.692 2.692-7.127 0-9.82A6.92 6.92 0 0 0 13.796 0m-5.07 8.728-3.433 3.434c-2.692 2.693-2.692 7.126 0 9.819A6.92 6.92 0 0 0 10.203 24a6.93 6.93 0 0 0 4.911-2.02l3.432-3.432-3.271-3.272-3.433 3.433a2.284 2.284 0 0 1-3.277 0 2.28 2.28 0 0 1 0-3.276L12 12z", + }, + ], + }, + { + key: "streaming", + items: [ + { + name: "Apache Kafka", + path: "M9.71 2.136a1.43 1.43 0 0 0-2.047 0h-.007a1.48 1.48 0 0 0-.421 1.042c0 .41.161.777.422 1.039l.007.007c.257.264.616.426 1.019.426.404 0 .766-.162 1.027-.426l.003-.007c.261-.262.421-.629.421-1.039 0-.408-.159-.777-.421-1.042H9.71zM8.683 22.295c.404 0 .766-.167 1.027-.429l.003-.008c.261-.261.421-.631.421-1.036 0-.41-.159-.778-.421-1.044H9.71a1.42 1.42 0 0 0-1.027-.432 1.4 1.4 0 0 0-1.02.432h-.007c-.26.266-.422.634-.422 1.044 0 .406.161.775.422 1.036l.007.008c.258.262.617.429 1.02.429zm7.89-4.462c.359-.096.683-.33.882-.684l.027-.052a1.47 1.47 0 0 0 .114-1.067 1.454 1.454 0 0 0-.675-.896l-.021-.014a1.425 1.425 0 0 0-1.078-.132c-.36.091-.684.335-.881.686-.2.349-.241.75-.146 1.119.099.363.33.691.675.896h.002c.346.203.737.239 1.101.144zm-6.405-7.342a2.083 2.083 0 0 0-1.485-.627c-.58 0-1.103.242-1.482.627-.378.385-.612.916-.612 1.507s.233 1.124.612 1.514a2.08 2.08 0 0 0 2.967 0c.379-.39.612-.923.612-1.514s-.233-1.122-.612-1.507zm-.835-2.51c.843.141 1.6.552 2.178 1.144h.004c.092.093.182.196.265.299l1.446-.851a3.176 3.176 0 0 1-.047-1.808 3.149 3.149 0 0 1 1.456-1.926l.025-.016a3.062 3.062 0 0 1 2.345-.306c.77.21 1.465.721 1.898 1.482v.002c.431.757.518 1.626.313 2.408a3.145 3.145 0 0 1-1.456 1.928l-.198.118h-.02a3.095 3.095 0 0 1-2.154.201 3.127 3.127 0 0 1-1.514-.944l-1.444.848a4.162 4.162 0 0 1 0 2.879l1.444.846c.413-.47.939-.789 1.514-.944a3.041 3.041 0 0 1 2.371.319l.048.023v.002a3.17 3.17 0 0 1 1.408 1.906 3.215 3.215 0 0 1-.313 2.405l-.026.053-.003-.005a3.147 3.147 0 0 1-1.867 1.436 3.096 3.096 0 0 1-2.371-.318v-.006a3.156 3.156 0 0 1-1.456-1.927 3.175 3.175 0 0 1 .047-1.805l-1.446-.848a3.905 3.905 0 0 1-.265.294l-.004.005a3.938 3.938 0 0 1-2.178 1.138v1.699a3.09 3.09 0 0 1 1.56.862l.002.004c.565.572.914 1.368.914 2.243 0 .873-.35 1.664-.914 2.239l-.002.009a3.1 3.1 0 0 1-2.21.931 3.1 3.1 0 0 1-2.206-.93h-.002v-.009a3.186 3.186 0 0 1-.916-2.239c0-.875.35-1.672.916-2.243v-.004h.002a3.1 3.1 0 0 1 1.558-.862v-1.699a3.926 3.926 0 0 1-2.176-1.138l-.006-.005a4.098 4.098 0 0 1-1.173-2.874c0-1.122.452-2.136 1.173-2.872h.006a3.947 3.947 0 0 1 2.176-1.144V6.289a3.137 3.137 0 0 1-1.558-.864h-.002v-.004a3.192 3.192 0 0 1-.916-2.243c0-.871.35-1.669.916-2.243l.002-.002A3.084 3.084 0 0 1 8.683 0c.861 0 1.641.355 2.21.932v.002h.002c.565.574.914 1.372.914 2.243 0 .876-.35 1.667-.914 2.243l-.002.005a3.142 3.142 0 0 1-1.56.864v1.692zm8.121-1.129l-.012-.019a1.452 1.452 0 0 0-.87-.668 1.43 1.43 0 0 0-1.103.146h.002c-.347.2-.58.529-.677.896-.095.365-.054.768.146 1.119l.007.009c.2.347.519.579.874.673.357.103.755.059 1.098-.144l.019-.009a1.47 1.47 0 0 0 .657-.885 1.493 1.493 0 0 0-.141-1.118", + }, + { + name: "Redis", + path: "M22.71 13.145c-1.66 2.092-3.452 4.483-7.038 4.483-3.203 0-4.397-2.825-4.48-5.12.701 1.484 2.073 2.685 4.214 2.63 4.117-.133 6.94-3.852 6.94-7.239 0-4.05-3.022-6.972-8.268-6.972-3.752 0-8.4 1.428-11.455 3.685C2.59 6.937 3.885 9.958 4.35 9.626c2.648-1.904 4.748-3.13 6.784-3.744C8.12 9.244.886 17.05 0 18.425c.1 1.261 1.66 4.648 2.424 4.648.232 0 .431-.133.664-.365a100.49 100.49 0 0 0 5.54-6.765c.222 3.104 1.748 6.898 6.014 6.898 3.819 0 7.604-2.756 9.33-8.965.2-.764-.73-1.361-1.261-.73zm-4.349-5.013c0 1.959-1.926 2.922-3.685 2.922-.941 0-1.664-.247-2.235-.568 1.051-1.592 2.092-3.225 3.21-4.973 1.972.334 2.71 1.43 2.71 2.619z", + }, + { name: "CDC / Debezium" }, + ], + }, + { + key: "observability", + items: [ + { + name: "Datadog", + path: "M19.57 17.04l-1.997-1.316-1.665 2.782-1.937-.567-1.706 2.604.087.82 9.274-1.71-.538-5.794zm-8.649-2.498l1.488-.204c.241.108.409.15.697.223.45.117.97.23 1.741-.16.18-.088.553-.43.704-.625l6.096-1.106.622 7.527-10.444 1.882zm11.325-2.712l-.602.115L20.488 0 .789 2.285l2.427 19.693 2.306-.334c-.184-.263-.471-.581-.96-.989-.68-.564-.44-1.522-.039-2.127.53-1.022 3.26-2.322 3.106-3.956-.056-.594-.15-1.368-.702-1.898-.02.22.017.432.017.432s-.227-.289-.34-.683c-.112-.15-.2-.199-.319-.4-.085.233-.073.503-.073.503s-.186-.437-.216-.807c-.11.166-.137.48-.137.48s-.241-.69-.186-1.062c-.11-.323-.436-.965-.343-2.424.6.421 1.924.321 2.44-.439.171-.251.288-.939-.086-2.293-.24-.868-.835-2.16-1.066-2.651l-.028.02c.122.395.374 1.223.47 1.625.293 1.218.372 1.642.234 2.204-.116.488-.397.808-1.107 1.165-.71.358-1.653-.514-1.713-.562-.69-.55-1.224-1.447-1.284-1.883-.062-.477.275-.763.445-1.153-.243.07-.514.192-.514.192s.323-.334.722-.624c.165-.109.262-.178.436-.323a9.762 9.762 0 0 0-.456.003s.42-.227.855-.392c-.318-.014-.623-.003-.623-.003s.937-.419 1.678-.727c.509-.208 1.006-.147 1.286.257.367.53.752.817 1.569.996.501-.223.653-.337 1.284-.509.554-.61.99-.688.99-.688s-.216.198-.274.51c.314-.249.66-.455.66-.455s-.134.164-.259.426l.03.043c.366-.22.797-.394.797-.394s-.123.156-.268.358c.277-.002.838.012 1.056.037 1.285.028 1.552-1.374 2.045-1.55.618-.22.894-.353 1.947.68.903.888 1.609 2.477 1.259 2.833-.294.295-.874-.115-1.516-.916a3.466 3.466 0 0 1-.716-1.562 1.533 1.533 0 0 0-.497-.85s.23.51.23.96c0 .246.03 1.165.424 1.68-.039.076-.057.374-.1.43-.458-.554-1.443-.95-1.604-1.067.544.445 1.793 1.468 2.273 2.449.453.927.186 1.777.416 1.997.065.063.976 1.197 1.15 1.767.306.994.019 2.038-.381 2.685l-1.117.174c-.163-.045-.273-.068-.42-.153.08-.143.241-.5.243-.572l-.063-.111c-.348.492-.93.97-1.414 1.245-.633.359-1.363.304-1.838.156-1.348-.415-2.623-1.327-2.93-1.566 0 0-.01.191.048.234.34.383 1.119 1.077 1.872 1.56l-1.605.177.759 5.908c-.337.048-.39.071-.757.124-.325-1.147-.946-1.895-1.624-2.332-.599-.384-1.424-.47-2.214-.314l-.05.059a2.851 2.851 0 0 1 1.863.444c.654.413 1.181 1.481 1.375 2.124.248.822.42 1.7-.248 2.632-.476.662-1.864 1.028-2.986.237.3.481.705.876 1.25.95.809.11 1.577-.03 2.106-.574.452-.464.69-1.434.628-2.456l.714-.104.258 1.834 11.827-1.424zM15.05 6.848c-.034.075-.085.125-.007.37l.004.014.013.032.032.073c.14.287.295.558.552.696.067-.011.136-.019.207-.023.242-.01.395.028.492.08.009-.048.01-.119.005-.222-.018-.364.072-.982-.626-1.308-.264-.122-.634-.084-.757.068a.302.302 0 0 1 .058.013c.186.066.06.13.027.207m1.958 3.392c-.092-.05-.52-.03-.821.005-.574.068-1.193.267-1.328.372-.247.191-.135.523.047.66.511.382.96.638 1.432.575.29-.038.546-.497.728-.914.124-.288.124-.598-.058-.698m-5.077-2.942c.162-.154-.805-.355-1.556.156-.554.378-.571 1.187-.041 1.646.053.046.096.078.137.104a4.77 4.77 0 0 1 1.396-.412c.113-.125.243-.345.21-.745-.044-.542-.455-.456-.146-.749", + }, + { + name: "Grafana", + path: "M23.02 10.59a8.578 8.578 0 0 0-.862-3.034 8.911 8.911 0 0 0-1.789-2.445c.337-1.342-.413-2.505-.413-2.505-1.292-.08-2.113.4-2.416.62-.052-.02-.102-.044-.154-.064-.22-.089-.446-.172-.677-.247-.231-.073-.47-.14-.711-.197a9.867 9.867 0 0 0-.875-.161C14.557.753 12.94 0 12.94 0c-1.804 1.145-2.147 2.744-2.147 2.744l-.018.093c-.098.029-.2.057-.298.088-.138.042-.275.094-.413.143-.138.055-.275.107-.41.166a8.869 8.869 0 0 0-1.557.87l-.063-.029c-2.497-.955-4.716.195-4.716.195-.203 2.658.996 4.33 1.235 4.636a11.608 11.608 0 0 0-.607 2.635C1.636 12.677.953 15.014.953 15.014c1.926 2.214 4.171 2.351 4.171 2.351.003-.002.006-.002.006-.005.285.509.615.994.986 1.446.156.19.32.371.488.548-.704 2.009.099 3.68.099 3.68 2.144.08 3.553-.937 3.849-1.173a9.784 9.784 0 0 0 3.164.501h.08l.055-.003.107-.002.103-.005.003.002c1.01 1.44 2.788 1.646 2.788 1.646 1.264-1.332 1.337-2.653 1.337-2.94v-.058c0-.02-.003-.039-.003-.06.265-.187.52-.387.758-.6a7.875 7.875 0 0 0 1.415-1.7c1.43.083 2.437-.885 2.437-.885-.236-1.49-1.085-2.216-1.264-2.354l-.018-.013-.016-.013a.217.217 0 0 1-.031-.02c.008-.092.016-.18.02-.27.011-.162.016-.323.016-.48v-.253l-.005-.098-.008-.135a1.891 1.891 0 0 0-.01-.13c-.003-.042-.008-.083-.013-.125l-.016-.124-.018-.122a6.215 6.215 0 0 0-2.032-3.73 6.015 6.015 0 0 0-3.222-1.46 6.292 6.292 0 0 0-.85-.048l-.107.002h-.063l-.044.003-.104.008a4.777 4.777 0 0 0-3.335 1.695c-.332.4-.592.84-.768 1.297a4.594 4.594 0 0 0-.312 1.817l.003.091c.005.055.007.11.013.164a3.615 3.615 0 0 0 .698 1.82 3.53 3.53 0 0 0 1.827 1.282c.33.098.66.14.971.137.039 0 .078 0 .114-.002l.063-.003c.02 0 .041-.003.062-.003.034-.002.065-.007.099-.01.007 0 .018-.003.028-.003l.031-.005.06-.008a1.18 1.18 0 0 0 .112-.02c.036-.008.072-.013.109-.024a2.634 2.634 0 0 0 .914-.415c.028-.02.056-.041.085-.065a.248.248 0 0 0 .039-.35.244.244 0 0 0-.309-.06l-.078.042c-.09.044-.184.083-.283.116a2.476 2.476 0 0 1-.475.096c-.028.003-.054.006-.083.006l-.083.002c-.026 0-.054 0-.08-.002l-.102-.006h-.012l-.024.006c-.016-.003-.031-.003-.044-.006-.031-.002-.06-.007-.091-.01a2.59 2.59 0 0 1-.724-.213 2.557 2.557 0 0 1-.667-.438 2.52 2.52 0 0 1-.805-1.475 2.306 2.306 0 0 1-.029-.444l.006-.122v-.023l.002-.031c.003-.021.003-.04.005-.06a3.163 3.163 0 0 1 1.352-2.29 3.12 3.12 0 0 1 .937-.43 2.946 2.946 0 0 1 .776-.101h.06l.07.002.045.003h.026l.07.005a4.041 4.041 0 0 1 1.635.49 3.94 3.94 0 0 1 1.602 1.662 3.77 3.77 0 0 1 .397 1.414l.005.076.003.075c.002.026.002.05.002.075 0 .024.003.052 0 .07v.065l-.002.073-.008.174a6.195 6.195 0 0 1-.08.639 5.1 5.1 0 0 1-.267.927 5.31 5.31 0 0 1-.624 1.13 5.052 5.052 0 0 1-3.237 2.014 4.82 4.82 0 0 1-.649.066l-.039.003h-.287a6.607 6.607 0 0 1-1.716-.265 6.776 6.776 0 0 1-3.4-2.274 6.75 6.75 0 0 1-.746-1.15 6.616 6.616 0 0 1-.714-2.596l-.005-.083-.002-.02v-.056l-.003-.073v-.096l-.003-.104v-.07l.003-.163c.008-.22.026-.45.054-.678a8.707 8.707 0 0 1 .28-1.355c.128-.444.286-.872.473-1.277a7.04 7.04 0 0 1 1.456-2.1 5.925 5.925 0 0 1 .953-.763c.169-.111.343-.213.524-.306.089-.05.182-.091.273-.135.047-.02.093-.042.138-.062a7.177 7.177 0 0 1 .714-.267l.145-.045c.049-.015.098-.026.148-.041.098-.029.197-.052.296-.076.049-.013.1-.02.15-.033l.15-.032.151-.028.076-.013.075-.01.153-.024c.057-.01.114-.013.171-.023l.169-.021c.036-.003.073-.008.106-.01l.073-.008.036-.003.042-.002c.057-.003.114-.008.171-.01l.086-.006h.023l.037-.003.145-.007a7.999 7.999 0 0 1 1.708.125 7.917 7.917 0 0 1 2.048.68 8.253 8.253 0 0 1 1.672 1.09l.09.077.089.078c.06.052.114.107.171.159.057.052.112.106.166.16.052.055.107.107.159.164a8.671 8.671 0 0 1 1.41 1.978c.012.026.028.052.04.078l.04.078.075.156c.023.051.05.1.07.153l.065.15a8.848 8.848 0 0 1 .45 1.34.19.19 0 0 0 .201.142.186.186 0 0 0 .172-.184c.01-.246.002-.532-.024-.856z", + }, + { + name: "Splunk", + path: "M23.348 11.911l-2.241-1.091v-.65L24 11.621v.593l-2.893 1.438v-.636zm-5.397 1.841h-.961v-5.31h.961v3.116h.102l1.28-1.481.723.31-1.23 1.316 1.453 1.809-.888.311-1.44-1.996zm-2.577-.002v-2.068a2.685 2.685 0 0 0-.026-.42.791.791 0 0 0-.09-.26c-.113-.202-.308-.304-.59-.304a.888.888 0 0 0-.461.113.673.673 0 0 0-.286.33 1.012 1.012 0 0 0-.07.263c-.012.13-.019.262-.017.395v1.95h-.961v-3.614h.961l.002.485c.185-.2.373-.348.566-.437.192-.089.418-.134.673-.134.286 0 .527.058.721.177a1.016 1.016 0 0 1 .475.665 1.972 1.972 0 0 1 .054.448c.002.1.004.22.004.358v2.053zm-4.115.002l-.002-.485a1.783 1.783 0 0 1-.565.437 1.597 1.597 0 0 1-.674.135c-.285 0-.524-.057-.72-.17a.972.972 0 0 1-.425-.504.75.75 0 0 1-.054-.167 1.918 1.918 0 0 1-.033-.199 2.033 2.033 0 0 1-.017-.258 15.516 15.516 0 0 1-.005-.355V10.13h.956v2.07c-.003.141.006.282.026.42.015.092.045.18.09.26.113.204.308.306.59.306.36 0 .606-.15.74-.449.035-.082.06-.168.074-.257.017-.134.024-.269.022-.403v-1.95h.955v3.624zM7.184 8.44h.955v5.31h-.955zM5.759 11.9c0-.396-.08-.708-.24-.937a.759.759 0 0 0-.657-.345.804.804 0 0 0-.693.366c-.171.245-.256.574-.253.99 0 .405.084.723.25.957a.796.796 0 0 0 .69.347.685.685 0 0 0 .433-.135.985.985 0 0 0 .277-.34c.071-.14.121-.292.147-.448.03-.151.043-.3.046-.455m1.01-.036c.003.266-.04.532-.129.786-.082.23-.204.441-.364.626-.31.361-.764.567-1.24.563a1.67 1.67 0 0 1-.313-.028 1.041 1.041 0 0 1-.275-.098 1.33 1.33 0 0 1-.257-.178 2.379 2.379 0 0 1-.265-.268v2.293h-.929v-5.425h.93l.004.529c.169-.212.353-.368.55-.468.197-.1.426-.15.688-.147a1.509 1.509 0 0 1 1.156.507c.148.166.259.361.33.571.08.236.12.485.115.737m-4.21.89a.946.946 0 0 1-.102.441 1.007 1.007 0 0 1-.282.345c-.13.1-.275.173-.43.22a1.8 1.8 0 0 1-.546.08 1.985 1.985 0 0 1-.637-.097 1.964 1.964 0 0 1-.563-.32l.312-.505c.15.126.284.217.405.275.115.057.24.087.368.087a.557.557 0 0 0 .373-.12.396.396 0 0 0 .14-.322.475.475 0 0 0-.12-.318 1.306 1.306 0 0 0-.187-.173 9.231 9.231 0 0 0-.308-.232 6.787 6.787 0 0 1-.281-.21 2.11 2.11 0 0 1-.252-.232 1.039 1.039 0 0 1-.18-.275.826.826 0 0 1-.069-.347.893.893 0 0 1 .094-.409.935.935 0 0 1 .255-.314 1.22 1.22 0 0 1 .39-.203c.16-.05.327-.074.494-.072.184 0 .368.026.545.076.174.05.338.123.488.219l-.282.454a1.05 1.05 0 0 0-.608-.201.504.504 0 0 0-.323.102.307.307 0 0 0-.126.253c0 .098.041.193.113.26.074.078.203.186.385.325.185.136.336.253.457.355.104.085.202.182.286.286.065.08.115.173.145.273a.808.808 0 0 1 .046.299Z", + }, + ], + }, +]; diff --git a/website/index.html b/website/index.html new file mode 100644 index 0000000..7734c21 --- /dev/null +++ b/website/index.html @@ -0,0 +1,32 @@ + + + + + + Amp: the blockchain native database + + + + + + + + + + + + + +
+ + + diff --git a/website/lib/amp-api.ts b/website/lib/amp-api.ts new file mode 100644 index 0000000..7c2cb60 --- /dev/null +++ b/website/lib/amp-api.ts @@ -0,0 +1,144 @@ +/** The data the live section renders, behind one interface. `createMockClient` + * fabricates plausible values; a real client implements the same interface + * against the Amp Cloud API and is swapped in at one call site (Live.tsx). */ + +export type Network = "mainnet" | "base" | "solana-mainnet"; + +export interface ChainHead { + network: Network; + label: string; + /** Latest block or slot on the chain. */ + chainHead: number; + /** Latest block or slot Amp has materialized. */ + ampHead: number; + /** Milliseconds between the chain head and Amp's head. */ + lagMs: number; + /** Seconds per block or slot, for the ticker. */ + blockTimeS: number; +} + +export interface StreamRow { + network: Network; + blockNum: number; + hash: string; + txCount: number; + gasUsed: number; + ts: number; + /** The cursor field on the last row of a microbatch. */ + rangesComplete: boolean; +} + +export interface DatasetSummary { + name: string; + version: string; + kind: string; + network: Network; + tables: number; + sizeTb: number; + lagMs: number; + status: "following" | "backfilling"; +} + +export interface SeriesPoint { + day: string; + value: number; +} + +export interface AmpClient { + heads(): ChainHead[]; + subscribeHeads(cb: (heads: ChainHead[]) => void): () => void; + subscribeStream(network: Network, cb: (rows: StreamRow[]) => void): () => void; + datasets(): DatasetSummary[]; + series(network: Network, days: number): SeriesPoint[]; +} + +/* ------------------------------ mock ------------------------------------ */ + +function rng(seed: number) { + let s = seed >>> 0; + return () => { + s = (s * 1664525 + 1013904223) >>> 0; + return s / 4294967296; + }; +} + +function hex(n: number, r: () => number) { + let out = "0x"; + for (let i = 0; i < n; i++) out += Math.floor(r() * 16).toString(16); + return out; +} + +const BASELINE: ChainHead[] = [ + { network: "mainnet", label: "Ethereum", chainHead: 25_931_402, ampHead: 25_931_402, lagMs: 740, blockTimeS: 12 }, + { network: "base", label: "Base", chainHead: 51_204_118, ampHead: 51_204_117, lagMs: 810, blockTimeS: 2 }, + { network: "solana-mainnet", label: "Solana", chainHead: 445_218_930, ampHead: 445_218_928, lagMs: 690, blockTimeS: 0.4 }, +]; + +export function createMockClient(): AmpClient { + const r = rng(7); + const start = Date.now(); + const heads = () => + BASELINE.map((h) => { + const elapsed = (Date.now() - start) / 1000; + const advanced = Math.floor(elapsed / h.blockTimeS); + const jitter = Math.floor(Math.sin(elapsed / 3 + h.blockTimeS) * 90); + return { ...h, chainHead: h.chainHead + advanced, ampHead: h.ampHead + advanced, lagMs: h.lagMs + jitter }; + }); + + return { + heads, + subscribeHeads(cb) { + cb(heads()); + const id = setInterval(() => cb(heads()), 400); + return () => clearInterval(id); + }, + subscribeStream(network, cb) { + const head = BASELINE.find((h) => h.network === network)!; + let next = head.chainHead - 12; + const batch = () => { + const size = network === "solana-mainnet" ? 5 : network === "base" ? 3 : 1; + const rows: StreamRow[] = []; + for (let i = 0; i < size; i++) { + next += 1; + rows.push({ + network, + blockNum: next, + hash: hex(64, r), + txCount: network === "solana-mainnet" ? 900 + Math.floor(r() * 700) : network === "base" ? 200 + Math.floor(r() * 220) : 120 + Math.floor(r() * 160), + gasUsed: network === "solana-mainnet" ? 0 : 12_000_000 + Math.floor(r() * 18_000_000), + ts: Date.now(), + rangesComplete: i === size - 1, + }); + } + cb(rows); + }; + batch(); + const id = setInterval(batch, Math.max(1200, head.blockTimeS * 1000 * (network === "solana-mainnet" ? 5 : network === "base" ? 3 : 1))); + return () => clearInterval(id); + }, + datasets() { + return [ + { name: "acme/eth_mainnet", version: "1.2.0", kind: "evm-rpc", network: "mainnet", tables: 3, sizeTb: 4.1, lagMs: 740, status: "following" }, + { name: "acme/base", version: "1.0.3", kind: "evm-rpc", network: "base", tables: 3, sizeTb: 2.7, lagMs: 810, status: "following" }, + { name: "acme/solana_mainnet", version: "2.0.0", kind: "solana", network: "solana-mainnet", tables: 5, sizeTb: 159.2, lagMs: 690, status: "following" }, + { name: "acme/erc20_transfers", version: "1.4.1", kind: "derived", network: "mainnet", tables: 1, sizeTb: 0.9, lagMs: 2_100, status: "following" }, + { name: "acme/usdc_volume_daily", version: "0.3.0", kind: "derived", network: "mainnet", tables: 1, sizeTb: 0.01, lagMs: 0, status: "backfilling" }, + ]; + }, + series(network, days) { + const s = rng(network === "mainnet" ? 11 : network === "base" ? 13 : 17); + const base = network === "mainnet" ? 1_520_000 : network === "base" ? 9_800_000 : 310_000_000; + const out: SeriesPoint[] = []; + const today = new Date(); + for (let i = days - 1; i >= 0; i--) { + const d = new Date(today); + d.setDate(today.getDate() - i); + const weekday = d.getDay(); + const weekend = weekday === 0 || weekday === 6 ? 0.86 : 1; + const trend = 1 + (days - 1 - i) * 0.004; + out.push({ day: d.toISOString().slice(0, 10), value: Math.round(base * weekend * trend * (0.94 + s() * 0.12)) }); + } + return out; + }, + }; +} diff --git a/website/lib/amp-client.ts b/website/lib/amp-client.ts new file mode 100644 index 0000000..8fdeb51 --- /dev/null +++ b/website/lib/amp-client.ts @@ -0,0 +1,5 @@ +import { createMockClient, type AmpClient } from "./amp-api"; + +/** One client for every live element on the page. Swap the factory for the + * real API client when it lands; nothing else changes. */ +export const ampClient: AmpClient = createMockClient(); diff --git a/website/lib/cn.ts b/website/lib/cn.ts new file mode 100644 index 0000000..b345942 --- /dev/null +++ b/website/lib/cn.ts @@ -0,0 +1,3 @@ +export function cn(...parts: Array): string { + return parts.filter(Boolean).join(" "); +} diff --git a/website/lib/use-heads.ts b/website/lib/use-heads.ts new file mode 100644 index 0000000..456c766 --- /dev/null +++ b/website/lib/use-heads.ts @@ -0,0 +1,15 @@ +import { useEffect, useState } from "react"; +import { ampClient } from "./amp-client"; +import type { ChainHead, Network } from "./amp-api"; + +export const NETWORK_ICON: Record = { + mainnet: "ethereum", + base: "base", + "solana-mainnet": "solana", +}; + +export function useHeads() { + const [heads, setHeads] = useState(() => ampClient.heads()); + useEffect(() => ampClient.subscribeHeads(setHeads), []); + return heads; +} diff --git a/website/package.json b/website/package.json new file mode 100644 index 0000000..6fe7619 --- /dev/null +++ b/website/package.json @@ -0,0 +1,31 @@ +{ + "name": "ampup", + "version": "0.1.0", + "private": true, + "scripts": { + "dev": "vite", + "build": "tsc --noEmit && vite build", + "preview": "vite preview", + "typecheck": "tsc --noEmit" + }, + "dependencies": { + "@edgeandnode/eds-react": "^1.0.0", + "@web3icons/react": "^4.1.22", + "motion": "^12.40.0", + "react": "19.2.4", + "react-dom": "19.2.4", + "react-is": "^19.3.0", + "react-router": "^7.18.4" + }, + "devDependencies": { + "@tailwindcss/vite": "^4.3.3", + "@types/node": "^20", + "@types/react": "^19", + "@types/react-dom": "^19", + "@vitejs/plugin-react": "^6.1.1", + "tailwindcss": "^4", + "typescript": "^5", + "vite": "^8.3.0" + }, + "type": "module" +} diff --git a/website/pnpm-lock.yaml b/website/pnpm-lock.yaml new file mode 100644 index 0000000..b1aae30 --- /dev/null +++ b/website/pnpm-lock.yaml @@ -0,0 +1,2621 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@edgeandnode/eds-react': + specifier: ^1.0.0 + version: 1.0.0(@types/react@19.3.0)(react-dom@19.2.4(react@19.2.4))(react-is@19.3.0)(react@19.2.4)(tailwindcss@4.3.3)(typescript@5.9.3) + '@web3icons/react': + specifier: ^4.1.22 + version: 4.1.22(react@19.2.4) + motion: + specifier: ^12.40.0 + version: 12.43.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + react: + specifier: 19.2.4 + version: 19.2.4 + react-dom: + specifier: 19.2.4 + version: 19.2.4(react@19.2.4) + react-is: + specifier: ^19.3.0 + version: 19.3.0 + react-router: + specifier: ^7.18.4 + version: 7.18.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + devDependencies: + '@tailwindcss/vite': + specifier: ^4.3.3 + version: 4.3.3(vite@8.3.0(@types/node@20.19.43)(jiti@2.7.0)) + '@types/node': + specifier: ^20 + version: 20.19.43 + '@types/react': + specifier: ^19 + version: 19.3.0 + '@types/react-dom': + specifier: ^19 + version: 19.3.0(@types/react@19.3.0) + '@vitejs/plugin-react': + specifier: ^6.1.1 + version: 6.1.1(vite@8.3.0(@types/node@20.19.43)(jiti@2.7.0)) + tailwindcss: + specifier: ^4 + version: 4.3.3 + typescript: + specifier: ^5 + version: 5.9.3 + vite: + specifier: ^8.3.0 + version: 8.3.0(@types/node@20.19.43)(jiti@2.7.0) + +packages: + + '@adraffy/ens-normalize@1.11.1': + resolution: {integrity: sha512-nhCBV3quEgesuf7c7KYfperqSS14T8bYuvJ8PcLJp6znkZpFc0AuW4qBtr8eKVyPPe/8RSr7sglCWPU5eaxwKQ==} + + '@babel/runtime@7.29.7': + resolution: {integrity: sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==} + engines: {node: '>=6.9.0'} + + '@base-ui/react@1.8.0': + resolution: {integrity: sha512-P0/1sxo6SBVZOklKMIedvTWqw2s2IQzi9x5bIVsXu980cuSOD4NeuRSs+/L7LZQfDkZP/uRZyGPyfFl/B1oH+Q==} + engines: {node: '>=14.0.0'} + peerDependencies: + '@date-fns/tz': ^1.2.0 + '@types/react': ^17 || ^18 || ^19 + date-fns: ^4.0.0 + react: ^17 || ^18 || ^19 + react-dom: ^17 || ^18 || ^19 + peerDependenciesMeta: + '@date-fns/tz': + optional: true + '@types/react': + optional: true + date-fns: + optional: true + + '@base-ui/utils@0.4.0': + resolution: {integrity: sha512-bO9fz25kKtPf+aZVyfQrC0PDmJdmVni31W2hCS5/Owb+inwdIL3XU26pCPRPlt4LSxZrBgLwubXQXQlKaFEZzw==} + peerDependencies: + '@types/react': ^17 || ^18 || ^19 + react: ^17 || ^18 || ^19 + react-dom: ^17 || ^18 || ^19 + peerDependenciesMeta: + '@types/react': + optional: true + + '@edgeandnode/eds-css@1.0.0': + resolution: {integrity: sha512-FYzEkQ76vkm3EbTUxlMAfoS5m0e8vmeRdlGdZ8rim6DQpEkuO7NuTUpsjz2rzyNjdJRfRxJN5KARNwHAmMDRVw==} + peerDependencies: + tailwindcss: ^4.3.2 + + '@edgeandnode/eds-icons@1.0.0': + resolution: {integrity: sha512-w6GCdnir+dyppTRR+KWmvX6nW8K3AL8kkCbKE+Uujq6McWBI1AwcFO4dt8V8QMyrFWwrReEyNfJQBaIUTy5Jpg==} + + '@edgeandnode/eds-react@1.0.0': + resolution: {integrity: sha512-Ht0uWUFjEMnvUWomkH9QzHQ10g2tkVoQknFiqosccDIrnOCwN/Ipw6NhsHWe6LwObhpS/VjEk/duGbXHh2idxg==} + peerDependencies: + react: ^19.0.0 + react-dom: ^19.0.0 + react-is: ^19.0.0 + tailwindcss: ^4.3.2 + + '@edgeandnode/eds-utils@1.0.0': + resolution: {integrity: sha512-8lz9s0uSyQXTtsFAbydKYNacyyNbTy8XvkX0vvV7CeJrhRDfcEkCmJtn2neBDRE+RnQJAm8cbC7WpKxVFy8TRA==} + + '@edgeandnode/tailwindcss-animate@1.0.0': + resolution: {integrity: sha512-bT9mxFTNmfhTEBMb+Ts7ESHcDH2e3QprrXG7dO+KDvLo/v1QeRrZzttl+RrWZxV4ivUJdfV04cLWqfAnQGUGFw==} + peerDependencies: + tailwindcss: ^4.3.2 + + '@floating-ui/core@1.8.0': + resolution: {integrity: sha512-0CIZ5itps/8x7BG8dEIhs53BvCUH2PCoogtakwRTut+Arm58sJooJ0AuZhLw2HJYIR5cMLNPBSS728sPho2khQ==} + + '@floating-ui/dom@1.8.0': + resolution: {integrity: sha512-yXSrzeHZBTZadLOlfyhCkJHNeLJnHRnRInwdZ40L7ZiaAtrBwoYlsDrX3v5zB1Utk7CLfzcOVnVVWoXEky7Ceg==} + + '@floating-ui/react-dom@2.1.9': + resolution: {integrity: sha512-JDjEFGCpImxDCA7JJKviA0M9+RtmJdj0m/NVU5IMgBK+AmZouAQQ7/+2GLH0GXXY0YMw9oXPB8hKdbPYg5QLYg==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + + '@floating-ui/utils@0.2.12': + resolution: {integrity: sha512-HpCo8tmWzLVad5s2d19EhAz5zqrrQ6s69qd6moPMQvkOuSwDT1YgRfWSVuc4ennqrgv3OHppiOGMQ7oC13yIww==} + + '@internationalized/date@3.12.4': + resolution: {integrity: sha512-M1dEn4c1U1HsSlaVR8upZtSqvXrTkHDfv18H01uCSJyjVLDxnBR38v/fMxecmlwXKR4i9HeZcmgQAPE6A+aGJQ==} + + '@internationalized/number@3.6.8': + resolution: {integrity: sha512-8UmMFia46DUt+k97zKd9fKWXcWHR+k8ae3eYzILETuT2KbIvLyOfac7zesw+sJdRAAZ7Q9pM1Mk22aXp2LD0Ig==} + + '@internationalized/string@3.2.10': + resolution: {integrity: sha512-PDx6//vHSpRnHfxqMqto11zQvhsaU74O3mKv2F/0eicGZcl9NLjQmGlbHz/LsJh5tLKp4A4L7ZVTzN1/MmMTvA==} + + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + + '@jridgewell/remapping@2.3.5': + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.6.0': + resolution: {integrity: sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==} + + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + + '@noble/ciphers@1.3.0': + resolution: {integrity: sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==} + engines: {node: ^14.21.3 || >=16} + + '@noble/curves@1.9.1': + resolution: {integrity: sha512-k11yZxZg+t+gWvBbIswW0yoJlu8cHOC7dhunwOzoWH/mXGBiYyR4YY6hAEK/3EUs4UpB8la1RfdRpeGsFHkWsA==} + engines: {node: ^14.21.3 || >=16} + + '@noble/hashes@1.8.0': + resolution: {integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==} + engines: {node: ^14.21.3 || >=16} + + '@oxc-project/types@0.150.0': + resolution: {integrity: sha512-rDS5/31E9HfPl/CIzGrn0DOlvBbXFseQ5URJ9sYMfstbKLD/c6Gm9vmRzRGDdAXyOIL4zmO37lc9RIwYqVruZw==} + + '@react-aria/utils@3.34.1': + resolution: {integrity: sha512-H6+rGZL+0f58bBNaUMfctEnT+NogqwAk+nHiB8sR3K+YlQ37GTuCijy2U/pPvQtFMS5mURrjZeBH5JNNXsx14A==} + 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 + + '@react-hookz/web@26.1.0': + resolution: {integrity: sha512-GKErtGGoaPNWc8rp4SE/rVgJT1kJ/3s6n3q+Vs6DM4TRVsLqbsIGU9u3jTwcV3tCYgxAwz9DqJZxCaal89Lxqg==} + engines: {node: '>=18.0.0'} + peerDependencies: + js-cookie: ^3.0.5 + react: ^16.8 || ^17 || ^18 || ^19 + react-dom: ^16.8 || ^17 || ^18 || ^19 + peerDependenciesMeta: + js-cookie: + optional: true + + '@react-types/shared@3.36.1': + resolution: {integrity: sha512-AzsuD9OfxTOZMMvTRhlN3oHBwOmFN7tDh27LzqmHt4+uOgPhJT7ZM7/kVs/8/o0WxayMUIk3hBmCFRHv1FUoag==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@rolldown/binding-android-arm-eabi@1.2.9': + resolution: {integrity: sha512-tNISae1QEf/vkb3xkRcjV5SEdzPE97We5IVaa2Z8jSszQPZ8U60B/YCYpw4QI7VidYsBtKavczXf+DyDs9WGxw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [android] + + '@rolldown/binding-android-arm64@1.2.9': + resolution: {integrity: sha512-YC8YsI30o606GTZi0VyzYlsDKFP8W61i/QzayHDkLbNEz/IShqAmTa+hsJRj13xTHA0H+6fk4b2UmGn+Q/cMlg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@rolldown/binding-darwin-arm64@1.2.9': + resolution: {integrity: sha512-IwhlH3qK5urrY8hZiEgGkHKEFN901p/p2bjxCxJlr4GyNnF7wYpUvK+Y43uaRYuC4hpfjzbR3SJC3arX1jGvmw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + + '@rolldown/binding-darwin-x64@1.2.9': + resolution: {integrity: sha512-XxpJfVzFh+jilRxIXUqcfYAYcunIc/XEzIizsOL1fcJee5Sf7H3mH8WlLmfHfluz5amqR88QQo9izKtmMlavAw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@rolldown/binding-freebsd-x64@1.2.9': + resolution: {integrity: sha512-kSfvhmgeWyfkbT3p/1s5vSgboogoah2zkm9fX2zjg2hHxSV7T4KhMWRUUaRk4OXNqoD3QAUeRqLcs1aZOK4U1g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@rolldown/binding-linux-arm-gnueabihf@1.2.9': + resolution: {integrity: sha512-1RVzG17pxqbTfYLC352JlLt6kKLG+6Hr30n8DlIJqsnV5luUDd2Qdx9Ayw1Cabfyb1K9k0jXEZ7evxkRoT+uiw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@rolldown/binding-linux-arm64-gnu@1.2.9': + resolution: {integrity: sha512-BXqPvZ2drqVD+/Z8UpKwcs4Mp7grM+eGFku4CAEKrEtcbAsUpzREphK1sogCRZGreVPiMkiiBtw0n3TPteuqvw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + + '@rolldown/binding-linux-arm64-musl@1.2.9': + resolution: {integrity: sha512-11vWvo8YDwLzukt27J3aYDWU+gg2P7J+ZOmiJ0hkF5BXZDW7pVya7r40MXDy6ya0i9KamoENSVKIugvJNgFXIA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + + '@rolldown/binding-linux-ppc64-gnu@1.2.9': + resolution: {integrity: sha512-a1tijMkdwsIARtc0F39ApURROkf3NwqinI6TOiSSWCTR7dT96dffNvMUtDHnq64wKNTIZOIlzKrFvvFUznJiyw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + + '@rolldown/binding-linux-s390x-gnu@1.2.9': + resolution: {integrity: sha512-x6SQNdAvv4c3hWqTMaWuawzMX9myaCs/yEmlGsxJzkdClnHW7FbrjQuSiRDhuSYzEYoEMhsaJy9qHG/XNemJPQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + + '@rolldown/binding-linux-x64-gnu@1.2.9': + resolution: {integrity: sha512-9s0AZ8BFK5/n7B/TBoa2yJE3gI3KURrbXcPBlsAsvjU4VeJKgE90y1YtNxyEUIcHPQkg6/yfF3qihUrcM/Kf0Q==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + + '@rolldown/binding-linux-x64-musl@1.2.9': + resolution: {integrity: sha512-P7VWAmV+WdJluH7ovnRGoiv2i8To7GAZ+kGzfGup635cyL7SyYl3lSUaA3Gp5THf0n/Co5EyEqb2zbqq+nMOHQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + + '@rolldown/binding-openharmony-arm64@1.2.9': + resolution: {integrity: sha512-1qixtsE4BK8h+yS3BfmZ09UhA7O/N4IACva6YBr7EBvCJraByTuRcgOTaiA62Tm0vey3UcKXLOaoGHtYmNGEVg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@rolldown/binding-win32-arm64-msvc@1.2.9': + resolution: {integrity: sha512-ok8IQjcEPs1AKZfuEUznVBrJw+gK4soq+bx8b1X2XoMqVClarc1q5JDmVtWXY1xfr6ZuHTAsPXHTgTrqKTZeww==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@rolldown/binding-win32-x64-msvc@1.2.9': + resolution: {integrity: sha512-Ip2mXoU0hM0boq3Rf+ekuT653OROSo6aSYcPT1VHE4q52KvyxgFkQgrgb/IEsxOuvQ2fZZbs8khJAyCEPM24/g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + + '@rolldown/pluginutils@1.0.1': + resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==} + + '@scure/base@1.2.6': + resolution: {integrity: sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==} + + '@scure/bip32@1.7.0': + resolution: {integrity: sha512-E4FFX/N3f4B80AKWp5dP6ow+flD1LQZo/w8UnLGYZO674jS6YnYeepycOOksv+vLPSpgN35wgKgy+ybfTb2SMw==} + + '@scure/bip39@1.6.0': + resolution: {integrity: sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A==} + + '@shikijs/core@4.4.3': + resolution: {integrity: sha512-QCR4q2ZO/ILJEuwiBMel4wdcTDb1JGwfjKTxPDF6x8ixOaluPrVqIn06C99AcRPhmYlBR56d/Fb+GN58GzExpg==} + engines: {node: '>=20'} + + '@shikijs/engine-javascript@4.4.3': + resolution: {integrity: sha512-FbOjFJp9VLdo1Wevs10BBtVxiTWwNLqZh5Gkhjgda/ioL15YOgeSl9n+6XMa3qRlPQzfhFNe641SrynFHYG0nQ==} + engines: {node: '>=20'} + + '@shikijs/engine-oniguruma@4.4.3': + resolution: {integrity: sha512-EcOQkxdxGQrc1Row/cC2c96/v1dbZqGnEVu1qTuT/MJmp6+cXCvQussowVmCv5Tqr3KuY3c7IbM6HTW3LJ1k9w==} + engines: {node: '>=20'} + + '@shikijs/langs@4.4.3': + resolution: {integrity: sha512-ePic0yfAJGOF83D5wBHK/00EjK65oahBYxFk5epgq33WRv7X9UuxLEV8PtR0szC0z8dl7INIpIodB99JRFlR+A==} + engines: {node: '>=20'} + + '@shikijs/primitive@4.4.3': + resolution: {integrity: sha512-m0wBeLDQDeIxRdUmrCPdQqfuUamDwRL5isCfYbguKD6NiaKpVbsv+3J81DyIKgNW5h4WAIIr8T4EkgQrBBxvaQ==} + engines: {node: '>=20'} + + '@shikijs/themes@4.4.3': + resolution: {integrity: sha512-w8UHjeUnIR965KMWJHUPXOc2mNJUnK3vpVLYLvw5IYU2mnTTJ89E24OrJDBNiJDQ0qzb0tc4l7mrIXx5cFeIyw==} + engines: {node: '>=20'} + + '@shikijs/types@4.4.3': + resolution: {integrity: sha512-UEJxmRR++MAGR6hugn0vgVS2W/6lWAts84FFSrnlH9sP0LNol7E5+NQ792pH8liWUhyMyjhTgSUH3k7iD7tc5g==} + engines: {node: '>=20'} + + '@shikijs/vscode-textmate@10.0.2': + resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==} + + '@swc/helpers@0.5.15': + resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} + + '@tailwindcss/node@4.3.3': + resolution: {integrity: sha512-/T8IKEsf9VTU6tLjgC7+sv2mOPtQxzE2jMw7u4Tt40Tx+QSZxpzh95/H6cMKoja9XuW7iMdLJYBB0o9G1CaAgg==} + + '@tailwindcss/oxide-android-arm64@4.3.3': + resolution: {integrity: sha512-Y85A2gmPSkl5Ve5qR86GL4HT509cFqQh1aes9p3sSkyTPwt0Pppf3GkwGe4JPACcRYjgJIEhQgM6dBClnr0NYw==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [android] + + '@tailwindcss/oxide-darwin-arm64@4.3.3': + resolution: {integrity: sha512-BiaWatpBcERQFDlOjRDpIVXuFK5PJez5SA4JMg6VYZdBYU+qKfV/vqjcIs+IYmtitf1xYQZTwXvU/8y4lfZUGw==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [darwin] + + '@tailwindcss/oxide-darwin-x64@4.3.3': + resolution: {integrity: sha512-fAeUqfV5ndhxRwai8cXGzdLvul9utWOmeTkv69unv4ZXixjn61Z+p9lCWdwOwA3TYboG3BwdVuN/RDjhBRl0mw==} + engines: {node: '>= 20'} + cpu: [x64] + os: [darwin] + + '@tailwindcss/oxide-freebsd-x64@4.3.3': + resolution: {integrity: sha512-iyf5bV6+wnAlflVeEy7R25dupxTNECZN5QMI0qNT6eT+EgaGdZcKhGkr5SdoaWiLJ3spLqIY9VCeSGrwmtg4kw==} + engines: {node: '>= 20'} + cpu: [x64] + os: [freebsd] + + '@tailwindcss/oxide-linux-arm-gnueabihf@4.3.3': + resolution: {integrity: sha512-aAYUprJAJQWWbRrPvtjdroZ56Md+JM8pMiopS6xGEwDfLhqj+2ver2p4nU4Mb3CRqcMmNBjo8KkUgcxhkzVQGQ==} + engines: {node: '>= 20'} + cpu: [arm] + os: [linux] + + '@tailwindcss/oxide-linux-arm64-gnu@4.3.3': + resolution: {integrity: sha512-nDxldcEENOxZRzC2uu9jrutZdAAQtb+8WWDCSnWL1zvBk1+FN+x6MtDViPB5AJMfttVCUhehGWus3XBPgatM/w==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [linux] + + '@tailwindcss/oxide-linux-arm64-musl@4.3.3': + resolution: {integrity: sha512-Md44bD6veX/PC5iyF8cDVnw4HBIANZepRZZ7a8DQOvkfo5WUBwcp6iAuCUz23u+4SUkhJlD3eL7hNdW8ezd/kA==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [linux] + + '@tailwindcss/oxide-linux-x64-gnu@4.3.3': + resolution: {integrity: sha512-tx7us1muwOKAKWao2v/GaafFeQboE6aj88vC6ziN2NCGcRm8gWUhwjzg+YdVB1e4boAtdtma4L43onunI6NS4w==} + engines: {node: '>= 20'} + cpu: [x64] + os: [linux] + + '@tailwindcss/oxide-linux-x64-musl@4.3.3': + resolution: {integrity: sha512-SJxX60smvHgasZoBy11dX6YRjXJFovwWBoedhbQPOBzgFWBHGB+TVPWB9BxzR7TTxU8FQZAI2AyiNCMzFm8Img==} + engines: {node: '>= 20'} + cpu: [x64] + os: [linux] + + '@tailwindcss/oxide-wasm32-wasi@4.3.3': + resolution: {integrity: sha512-jx1+rPhY/5Ympkktd656HBWEBLxP7dH06losBLjjf5vgCODXvi9KhtftWcMIwTFIDqBr7cRnQkdLnAG+IOlGvQ==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + bundledDependencies: + - '@napi-rs/wasm-runtime' + - '@emnapi/core' + - '@emnapi/runtime' + - '@tybys/wasm-util' + - '@emnapi/wasi-threads' + - tslib + + '@tailwindcss/oxide-win32-arm64-msvc@4.3.3': + resolution: {integrity: sha512-3rc292Ca2ceK6Ulcc/bAVnTs/3nDtoPhyEKlgPv+yQJQi/JS/AMJlqzxvlDacL1nekbrcf6bTqp/jV4qgnPxNQ==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [win32] + + '@tailwindcss/oxide-win32-x64-msvc@4.3.3': + resolution: {integrity: sha512-yJ0pwIVc/nYeGoV02WtsN8KYyLQv7kyI2wDnkezyJlGGjkd4QLwDGAwl47YpPJeuI0M0ObaXGSPjvWDPeTPggw==} + engines: {node: '>= 20'} + cpu: [x64] + os: [win32] + + '@tailwindcss/oxide@4.3.3': + resolution: {integrity: sha512-krXjAikiaFSPaK/FkAQT5UTx3VormQaiZ5hBFlJZ9UFQGB/rwg1MZIhHAG9smMQRTdyJxP6Qt5MwMtdyU5FWrA==} + engines: {node: '>= 20'} + + '@tailwindcss/vite@4.3.3': + resolution: {integrity: sha512-yYU8cogLeSh/ms2jh8Fj7jaba/EWa7Ja6GoUqYZaraEuCI5YS6ms6ObZgjjedm+jm6XZjdNRWBpPP6Z86oOxcw==} + peerDependencies: + vite: ^5.2.0 || ^6 || ^7 || ^8 + + '@types/debug@4.1.13': + resolution: {integrity: sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==} + + '@types/estree-jsx@1.0.5': + resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==} + + '@types/estree@1.0.9': + resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} + + '@types/hast@3.0.5': + resolution: {integrity: sha512-rp/ezSWaD1m44dPKICGhiskI13nVr7qTloFwDa/IYkhhf5nzwP+zIQcIJh3WIFSBOy/H1PzB40jPjMDksN4F+g==} + + '@types/mdast@4.0.4': + resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} + + '@types/ms@2.1.0': + resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} + + '@types/node@20.19.43': + resolution: {integrity: sha512-6oYBAi5ikg4Pl+kGsoYtawUMBT2zZMCvPNF7pVLnHZfd1zf38DRiWn/gT01RYCdUqkv7Fhr+C9ot4/tb+2sVvA==} + + '@types/react-dom@19.3.0': + resolution: {integrity: sha512-ZI7bU42mZXXKHn/qNLEw2IrbiINU7X5+vfgdixBHkCNpYWXjKgfQ/P+uyGb5CjOLB9UcnTeg3rylQtV2hym44Q==} + peerDependencies: + '@types/react': ^19.3.0 + + '@types/react@19.3.0': + resolution: {integrity: sha512-N0rFCuH9YoxG9/m61l9MfpJKfmLOVU0em7ipIz6TRgSSkvReLB9vL85GB+yr8Bs5leqpvg96JSwF4ZS1s4viQg==} + + '@types/unist@2.0.11': + resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} + + '@types/unist@3.0.3': + resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + + '@ungap/structured-clone@1.4.0': + resolution: {integrity: sha512-1mEZtMKPM09vDmQt5y7YvmN2+DFTP7Tg0EWXdic8/C6VRnpb33e4ghisCIE3WZjsE2N8mf+QV1Zqh7ZFYLWInQ==} + + '@ver0/deep-equal@2.0.1': + resolution: {integrity: sha512-JVSbDwzKASqorJum+ATnnZNIkni4K4G3aeJDsTgEhHcm0CiCwAVaLbhFByeNAir1HExEWjHxhIXVR+d8ZzeJGw==} + engines: {node: '>=20'} + + '@vitejs/plugin-react@6.1.1': + resolution: {integrity: sha512-yxLaQV9gkhS8ezJqCM6+ndU7mDY6gqAg75NQ+0IjwEI8IYOmQCgkRwHKVSfWXW076DsqMo0Dk+0FK1U+M5RgFw==} + engines: {node: ^20.19.0 || >=22.12.0} + peerDependencies: + '@rolldown/plugin-babel': ^0.1.7 || ^0.2.0 + babel-plugin-react-compiler: ^1.0.0 + oxc-transform-react: ^0.145.0 + vite: ^8.0.0 + peerDependenciesMeta: + '@rolldown/plugin-babel': + optional: true + babel-plugin-react-compiler: + optional: true + oxc-transform-react: + optional: true + + '@web3icons/common@0.11.51': + resolution: {integrity: sha512-ZXaTW/P6ReLHmkYQcxP8OcPoUrSmgPlsFKVboiG/cVSIkz0mHNP1tIFhf9zPOQaQm20yqTc+uuNuXb2ywHzI1A==} + + '@web3icons/react@4.1.22': + resolution: {integrity: sha512-GpcNQGKImC7UeVwI9U0HX++m0jb5WXYV18SSEkDMANQdcz1EzgboKQg2ZWg1G4TKVToguNBgrtDISo7Sx5rINw==} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + + abitype@1.2.3: + resolution: {integrity: sha512-Ofer5QUnuUdTFsBRwARMoWKOH1ND5ehwYhJ3OJ/BQO+StkwQjHw0XyVh4vDttzHB7QOFhPHa/o413PJ82gU/Tg==} + peerDependencies: + typescript: '>=5.0.4' + zod: ^3.22.0 || ^4.0.0 + peerDependenciesMeta: + typescript: + optional: true + zod: + optional: true + + aria-hidden@1.2.6: + resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==} + engines: {node: '>=10'} + + bail@2.0.2: + resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} + + ccount@2.0.1: + resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + + character-entities-html4@2.1.0: + resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} + + character-entities-legacy@3.0.0: + resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} + + character-entities@2.0.2: + resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} + + character-reference-invalid@2.0.1: + resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} + + charenc@0.0.2: + resolution: {integrity: sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==} + + clsx@2.1.1: + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} + engines: {node: '>=6'} + + comma-separated-tokens@2.0.3: + resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} + + cookie@1.1.1: + resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==} + engines: {node: '>=18'} + + crypt@0.0.2: + resolution: {integrity: sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==} + + cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + + csstype@3.2.3: + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decode-named-character-reference@1.3.0: + resolution: {integrity: sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==} + + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + + devlop@1.1.0: + resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + + enhanced-resolve@5.25.1: + resolution: {integrity: sha512-nGXts5znJzmWPu+mIE9izCOzdg63oJca2mDzGWWTth7sr4aCToKcoyFVBQwN75Ij5Pf6p510EwkTqViTRzDV+w==} + engines: {node: '>=10.13.0'} + + escape-string-regexp@5.0.0: + resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} + engines: {node: '>=12'} + + estree-util-is-identifier-name@3.0.0: + resolution: {integrity: sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==} + + eventemitter3@5.0.1: + resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + + extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + framer-motion@12.43.0: + resolution: {integrity: sha512-1eaL3RvR/kAlbG7UYcpMptEyzPoENO0c6w7ZnB3/hh2vSAz/6uGAFn6fdoqTBguNstf3MsFhJHsD/0DHiclG+g==} + peerDependencies: + '@emotion/is-prop-valid': '*' + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@emotion/is-prop-valid': + optional: true + react: + optional: true + react-dom: + optional: true + + framer-motion@13.4.0: + resolution: {integrity: sha512-HCpqKM9BTu6UYKtj0u6J1QNxojnnirNcghcSDZ+SkpiL3myxvtsgXPS3ZGEELC2eSma7YiA937rAEXtRyydSXQ==} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + react: + optional: true + react-dom: + optional: true + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + hast-util-to-html@9.0.5: + resolution: {integrity: sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==} + + hast-util-to-jsx-runtime@2.3.6: + resolution: {integrity: sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==} + + hast-util-whitespace@3.0.0: + resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} + + html-url-attributes@3.0.1: + resolution: {integrity: sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==} + + html-void-elements@3.0.0: + resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} + + inline-style-parser@0.2.7: + resolution: {integrity: sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==} + + is-alphabetical@2.0.1: + resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==} + + is-alphanumerical@2.0.1: + resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==} + + is-buffer@1.1.6: + resolution: {integrity: sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==} + + is-decimal@2.0.1: + resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==} + + is-hexadecimal@2.0.1: + resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==} + + is-plain-obj@4.1.0: + resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} + engines: {node: '>=12'} + + isows@1.0.7: + resolution: {integrity: sha512-I1fSfDCZL5P0v33sVqeTDSpcstAg/N+wF5HS033mogOVIp4B+oHC7oOCsA3axAbBSGTJ8QubbNmnIRN/h8U7hg==} + peerDependencies: + ws: '*' + + jiti@2.7.0: + resolution: {integrity: sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==} + hasBin: true + + lightningcss-android-arm64@1.32.0: + resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [android] + + lightningcss-android-arm64@1.33.0: + resolution: {integrity: sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [android] + + lightningcss-darwin-arm64@1.32.0: + resolution: {integrity: sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] + + lightningcss-darwin-arm64@1.33.0: + resolution: {integrity: sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] + + lightningcss-darwin-x64@1.32.0: + resolution: {integrity: sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] + + lightningcss-darwin-x64@1.33.0: + resolution: {integrity: sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] + + lightningcss-freebsd-x64@1.32.0: + resolution: {integrity: sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] + + lightningcss-freebsd-x64@1.33.0: + resolution: {integrity: sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] + + lightningcss-linux-arm-gnueabihf@1.32.0: + resolution: {integrity: sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] + + lightningcss-linux-arm-gnueabihf@1.33.0: + resolution: {integrity: sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] + + lightningcss-linux-arm64-gnu@1.32.0: + resolution: {integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + + lightningcss-linux-arm64-gnu@1.33.0: + resolution: {integrity: sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + + lightningcss-linux-arm64-musl@1.32.0: + resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + + lightningcss-linux-arm64-musl@1.33.0: + resolution: {integrity: sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + + lightningcss-linux-x64-gnu@1.32.0: + resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + + lightningcss-linux-x64-gnu@1.33.0: + resolution: {integrity: sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + + lightningcss-linux-x64-musl@1.32.0: + resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + + lightningcss-linux-x64-musl@1.33.0: + resolution: {integrity: sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + + lightningcss-win32-arm64-msvc@1.32.0: + resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] + + lightningcss-win32-arm64-msvc@1.33.0: + resolution: {integrity: sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] + + lightningcss-win32-x64-msvc@1.32.0: + resolution: {integrity: sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] + + lightningcss-win32-x64-msvc@1.33.0: + resolution: {integrity: sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] + + lightningcss@1.32.0: + resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==} + engines: {node: '>= 12.0.0'} + + lightningcss@1.33.0: + resolution: {integrity: sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==} + engines: {node: '>= 12.0.0'} + + longest-streak@3.1.0: + resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} + + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + + markdown-table@3.0.4: + resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} + + md5@2.3.0: + resolution: {integrity: sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==} + + mdast-util-find-and-replace@3.0.2: + resolution: {integrity: sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==} + + mdast-util-from-markdown@2.0.3: + resolution: {integrity: sha512-W4mAWTvSlKvf8L6J+VN9yLSqQ9AOAAvHuoDAmPkz4dHf553m5gVj2ejadHJhoJmcmxEnOv6Pa8XJhpxE93kb8Q==} + + mdast-util-gfm-autolink-literal@2.0.1: + resolution: {integrity: sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==} + + mdast-util-gfm-footnote@2.1.0: + resolution: {integrity: sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==} + + mdast-util-gfm-strikethrough@2.0.0: + resolution: {integrity: sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==} + + mdast-util-gfm-table@2.0.0: + resolution: {integrity: sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==} + + mdast-util-gfm-task-list-item@2.0.0: + resolution: {integrity: sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==} + + mdast-util-gfm@3.1.0: + resolution: {integrity: sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==} + + mdast-util-mdx-expression@2.0.1: + resolution: {integrity: sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==} + + mdast-util-mdx-jsx@3.2.0: + resolution: {integrity: sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==} + + mdast-util-mdxjs-esm@2.0.1: + resolution: {integrity: sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==} + + mdast-util-phrasing@4.1.0: + resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==} + + mdast-util-to-hast@13.2.1: + resolution: {integrity: sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==} + + mdast-util-to-markdown@2.1.2: + resolution: {integrity: sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==} + + mdast-util-to-string@4.0.0: + resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} + + micromark-core-commonmark@2.0.3: + resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==} + + micromark-extension-gfm-autolink-literal@2.1.0: + resolution: {integrity: sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==} + + micromark-extension-gfm-footnote@2.1.0: + resolution: {integrity: sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==} + + micromark-extension-gfm-strikethrough@2.1.0: + resolution: {integrity: sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==} + + micromark-extension-gfm-table@2.1.2: + resolution: {integrity: sha512-pRzm4kDTu0MjlmBkxmS9yYhw60nncfcEwu9NNdPFSQEFXS95ZKyIIyTSHu/o3ReBUrLKYEq+7YaXCRn/bPB4MA==} + + micromark-extension-gfm-tagfilter@2.0.0: + resolution: {integrity: sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==} + + micromark-extension-gfm-task-list-item@2.1.0: + resolution: {integrity: sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==} + + micromark-extension-gfm@3.0.0: + resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==} + + micromark-factory-destination@2.0.1: + resolution: {integrity: sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==} + + micromark-factory-label@2.0.1: + resolution: {integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==} + + micromark-factory-space@2.0.1: + resolution: {integrity: sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==} + + micromark-factory-title@2.0.1: + resolution: {integrity: sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==} + + micromark-factory-whitespace@2.0.1: + resolution: {integrity: sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==} + + micromark-util-character@2.1.1: + resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} + + micromark-util-chunked@2.0.1: + resolution: {integrity: sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==} + + micromark-util-classify-character@2.0.1: + resolution: {integrity: sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==} + + micromark-util-combine-extensions@2.0.1: + resolution: {integrity: sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==} + + micromark-util-decode-numeric-character-reference@2.0.2: + resolution: {integrity: sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==} + + micromark-util-decode-string@2.0.1: + resolution: {integrity: sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==} + + micromark-util-encode@2.0.1: + resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} + + micromark-util-html-tag-name@2.0.1: + resolution: {integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==} + + micromark-util-normalize-identifier@2.0.1: + resolution: {integrity: sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==} + + micromark-util-resolve-all@2.0.1: + resolution: {integrity: sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==} + + micromark-util-sanitize-uri@2.0.1: + resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==} + + micromark-util-subtokenize@2.1.0: + resolution: {integrity: sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==} + + micromark-util-symbol@2.0.1: + resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} + + micromark-util-types@2.0.2: + resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==} + + micromark@4.0.2: + resolution: {integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==} + + motion-dom@12.43.0: + resolution: {integrity: sha512-azKON4d9S65PEoFUiQTMTgPheEmzf2QngdRc50AKfJp9Q9mmcBVw22c8eMq9k8kxOFHdL7+WZY7N/5F/lwiDag==} + + motion-dom@13.3.0: + resolution: {integrity: sha512-AmAnB6pHdZ1vHGzWzuzteG6Q3j1lHKeX/lbST6jGlgm0cjvLUgaCk1xhOuPMOy5SgovN6wnnUdwFrkcsus7Ftg==} + + motion-utils@12.39.0: + resolution: {integrity: sha512-8nadJAJjTtqRkmRF36FoJTrywK9nnFmnPwnSMyxaOCU7GDjN9RTMJIxx9De8ErM+vpPhMccr/6fo5WciyQLnMQ==} + + motion-utils@13.3.0: + resolution: {integrity: sha512-sgSschQp7EseHInIlR7hBbMuvet3RA0bs28KPZAXJcGKGdxHGvh1ogpYDilY3bOMtl73EqPNmp75sAKHYPU5sg==} + + motion@12.43.0: + resolution: {integrity: sha512-BQgQbSa9Hn3/mtbib0MK53y6JSANa+YKUKlaYnWzAVDH424RYQ5LVpV3pNiWH00BA2z4ojsSdMzqT7g2FQwjuQ==} + peerDependencies: + '@emotion/is-prop-valid': '*' + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@emotion/is-prop-valid': + optional: true + react: + optional: true + react-dom: + optional: true + + motion@13.4.0: + resolution: {integrity: sha512-aiNSA29N+vgV5p5cJSB5cFzx8KTuuxB99z8zGtxsaqlwKtBK6sq8YgPRpkVQLkbJMOcLDU0q/ShdT95qpBy/0g==} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + react: + optional: true + react-dom: + optional: true + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + nanoid@3.3.19: + resolution: {integrity: sha512-Y2tUNy4ouw6tq5oDSKeQYGOyhkUBhNOcGV/02KC+6kd9eDGqdZd++mjMiIDilrBYvjEnCYvVtsuHCuP+okSfug==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + oniguruma-parser@0.12.2: + resolution: {integrity: sha512-6HVa5oIrgMC6aA6WF6XyyqbhRPJrKR02L20+2+zpDtO5QAzGHAUGw5TKQvwi5vctNnRHkJYmjAhRVQF2EKdTQw==} + + oniguruma-to-es@4.3.6: + resolution: {integrity: sha512-csuQ9x3Yr0cEIs/Zgx/OEt9iBw9vqIunAPQkx19R/fiMq2oGVTgcMqO/V3Ybqefr1TBvosI6jU539ksaBULJyA==} + + ox@0.14.45: + resolution: {integrity: sha512-jpsQ+p0JZh9mKCxxzxz0d5qFHZZg2/O9xW18IpEC/dNXXPVqmDJ0c//9RMz0CILkbSGPA42+cbU0fC/ghwJ03w==} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + parse-entities@4.0.2: + resolution: {integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@4.0.7: + resolution: {integrity: sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==} + engines: {node: '>=12'} + + postcss@8.5.28: + resolution: {integrity: sha512-RRuzqDtt5Y9h3quz5hWhK+TPnsmVs6WwSU6LkJMeY4HstUEDuYTG8UJSdawMRzmzAtV+KEoG8N3Qg2qLy5vM/A==} + engines: {node: ^10 || ^12 || >=14} + + property-information@7.2.0: + resolution: {integrity: sha512-IAtzIB6sUiWaJYrX9smp3V46pBGbBeLFRGdh25kg1334VcBlD8HzhPeNIWQH9zhGmo2itIe25EHt9dQP7G5hmg==} + + react-aria@3.52.1: + resolution: {integrity: sha512-fdZZruC9/x/joCg0mhKGs5aHpwrXLCSZ4GOJmhhYyiE0ffyEsk9MLFt9LCOCF9tn8ErTD+UDQP4oDUSlZkmpCg==} + 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 + + react-dom@19.2.4: + resolution: {integrity: sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==} + peerDependencies: + react: ^19.2.4 + + react-is@19.3.0: + resolution: {integrity: sha512-UpMYezM4v5/18F28aC66AEsjXIgE02kyEMH6yLdgLXu/UTfa1Ntwck/nNLrbqJsEXW7gPb0coNO9FQse9WTovA==} + + react-keyed-flatten-children@5.1.3: + resolution: {integrity: sha512-Sg/dy1L74BTU+X1X5Wy4CUcf1SzDVJCIwIt3Zhr+yPtCMl7OAKHVxx2b5zhLfbTveFFmTa8a82j5tqaji0feEQ==} + peerDependencies: + react: '>=18.0.0' + react-is: '>=18.0.0' + + react-markdown@10.1.0: + resolution: {integrity: sha512-qKxVopLT/TyA6BX3Ue5NwabOsAzm0Q7kAPwq6L+wWDwisYs7R8vZ0nRXqq6rkueboxpkjvLGU9fWifiX/ZZFxQ==} + peerDependencies: + '@types/react': '>=18' + react: '>=18' + + react-router@7.18.4: + resolution: {integrity: sha512-PUPQcMhMGRAslLcvtlPz/kmzBEWPhLdgLFrL7pLNepBL6dX0lWj4WD2cUYVgYCuT3jxvghYFg81cDTj44DhetQ==} + engines: {node: '>=20.0.0'} + peerDependencies: + react: '>=18' + react-dom: '>=18' + peerDependenciesMeta: + react-dom: + optional: true + + react-stately@3.50.0: + resolution: {integrity: sha512-TnckvpDQGU0672wEaLZqdzvhuSeXWjgW6vijMWxiKOxc8CosQUfPGISdcZyfHqjX3XMjEtRxj4w9HumvX4h4mw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + react@19.2.4: + resolution: {integrity: sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==} + engines: {node: '>=0.10.0'} + + regex-recursion@6.0.2: + resolution: {integrity: sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==} + + regex-utilities@2.3.0: + resolution: {integrity: sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==} + + regex@6.1.0: + resolution: {integrity: sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==} + + remark-gfm@4.0.1: + resolution: {integrity: sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==} + + remark-parse@11.0.0: + resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==} + + remark-rehype@11.1.2: + resolution: {integrity: sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==} + + remark-stringify@11.0.0: + resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==} + + reselect@5.3.0: + resolution: {integrity: sha512-XGoLeRAVzUTcJ1qkxPQhDJyIZ5d6zzZD9nT7AEZOaaU9UbWclhycElmhO+VD5bFeLuzhPBaOV2oXC8uG35ZSpg==} + + rolldown@1.2.9: + resolution: {integrity: sha512-hx/Pv0N1haXRb11qkfnK5MXB/iqr7i0yjWQqmO9uHqZpBgQSqzc8UsSnEpalsh+j1I8qQ2CkXAkJC8Br3dKSlg==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + + scheduler@0.27.0: + resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} + + set-cookie-parser@2.7.2: + resolution: {integrity: sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==} + + shiki@4.4.3: + resolution: {integrity: sha512-Mb/GvXPHBAXdgGIcnfU5L3ldpn1XcxrGkPHwqgRx17/I2XRfqlFKk2vGkHWINn1kdXvzJZeuO3is6I9KLPFm0g==} + engines: {node: '>=20'} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + space-separated-tokens@2.0.2: + resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + + stringify-entities@4.0.4: + resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} + + style-observer@0.1.2: + resolution: {integrity: sha512-VdGkVx7dGqEzosau63CI33vRJsAGKPJCXyS9f5ze7gFbgsXm0wt5liXUNB9+YjyfhMyD+iTwNa7sM4cvpP3N9Q==} + + style-to-js@1.1.21: + resolution: {integrity: sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==} + + style-to-object@1.0.14: + resolution: {integrity: sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==} + + tagged-tag@1.0.0: + resolution: {integrity: sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==} + engines: {node: '>=20'} + + tailwindcss@4.3.3: + resolution: {integrity: sha512-gOhV3P7ufE62QDGg1zVaTgCR+EtPv92k2nIhVcVKcLmxT1sUBsQGhnZj175j+MqRt4zLF7ic+sCYjfhxMxj7YQ==} + + tapable@2.3.3: + resolution: {integrity: sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==} + engines: {node: '>=6'} + + tinyglobby@0.2.17: + resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} + engines: {node: '>=12.0.0'} + + trim-lines@3.0.1: + resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} + + trough@2.2.0: + resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==} + + ts-extras@1.3.0: + resolution: {integrity: sha512-2o31AwfP5q7Sa0RN/KaSNBFkw0jRnWsqUY4W4SwBWrxbge9J6t9YBvJIRX2ZyVhpGj4zE5UYwNzTTBnIHeaDew==} + engines: {node: '>=20'} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + type-fest@5.10.0: + resolution: {integrity: sha512-NoSdpq/WEiAg5sjmBkmV/hfxv6HJH4NqPNrqjtSO5CwRmpsDfaf4begxW34KdJykH/l1yHtwBWQkCRdoXO8mPA==} + engines: {node: '>=20'} + + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + engines: {node: '>=14.17'} + hasBin: true + + undici-types@6.21.0: + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + + unified@11.0.5: + resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} + + unist-util-is@6.0.1: + resolution: {integrity: sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==} + + unist-util-position@5.0.0: + resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} + + unist-util-stringify-position@4.0.0: + resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} + + unist-util-visit-parents@6.0.2: + resolution: {integrity: sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==} + + unist-util-visit@5.1.0: + resolution: {integrity: sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==} + + use-sync-external-store@1.7.0: + resolution: {integrity: sha512-6L+EeigHMQhdaIPNIFUKwfWJSwWFQ8gJbJ2DLOs5sDIegTwR9fRxvnM3uciHKjIZhFz+KAv2emhWMRvDmMcY8A==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + vfile-message@4.0.3: + resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==} + + vfile@6.0.3: + resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} + + viem@2.56.8: + resolution: {integrity: sha512-vD1DsnYxySMml5/02m/+boWQYfZtWug2VYzm6+hdVT+VDmULBZfpoh9gPDAENdMMBmQKW/2QJ/1DuZaslBJDAg==} + peerDependencies: + typescript: '>=5.0.4' + peerDependenciesMeta: + typescript: + optional: true + + vite@8.3.0: + resolution: {integrity: sha512-lhZBVvEHefgE+HQZC9O7EBJgCU/nVzFNl7vkS4RE0APtWLP02/8QVIkQtzBxPquh7lq5/78NHipTj7ODQ6XuyQ==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + '@vitejs/devtools': ^0.7.1 + esbuild: ^0.27.0 || ^0.28.0 + jiti: '>=1.21.0' + less: ^4.0.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + '@vitejs/devtools': + optional: true + esbuild: + optional: true + jiti: + optional: true + less: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + ws@8.21.0: + resolution: {integrity: sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + zwitch@2.0.4: + resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} + +snapshots: + + '@adraffy/ens-normalize@1.11.1': {} + + '@babel/runtime@7.29.7': {} + + '@base-ui/react@1.8.0(@types/react@19.3.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@babel/runtime': 7.29.7 + '@base-ui/utils': 0.4.0(@types/react@19.3.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@floating-ui/react-dom': 2.1.9(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@floating-ui/utils': 0.2.12 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + use-sync-external-store: 1.7.0(react@19.2.4) + optionalDependencies: + '@types/react': 19.3.0 + + '@base-ui/utils@0.4.0(@types/react@19.3.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@babel/runtime': 7.29.7 + '@floating-ui/utils': 0.2.12 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + reselect: 5.3.0 + use-sync-external-store: 1.7.0(react@19.2.4) + optionalDependencies: + '@types/react': 19.3.0 + + '@edgeandnode/eds-css@1.0.0(tailwindcss@4.3.3)(typescript@5.9.3)': + dependencies: + '@edgeandnode/eds-utils': 1.0.0(typescript@5.9.3) + '@edgeandnode/tailwindcss-animate': 1.0.0(tailwindcss@4.3.3) + cssesc: 3.0.0 + tailwindcss: 4.3.3 + ts-extras: 1.3.0 + transitivePeerDependencies: + - bufferutil + - typescript + - utf-8-validate + - zod + + '@edgeandnode/eds-icons@1.0.0': {} + + '@edgeandnode/eds-react@1.0.0(@types/react@19.3.0)(react-dom@19.2.4(react@19.2.4))(react-is@19.3.0)(react@19.2.4)(tailwindcss@4.3.3)(typescript@5.9.3)': + dependencies: + '@base-ui/react': 1.8.0(@types/react@19.3.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@base-ui/utils': 0.4.0(@types/react@19.3.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@edgeandnode/eds-css': 1.0.0(tailwindcss@4.3.3)(typescript@5.9.3) + '@edgeandnode/eds-icons': 1.0.0 + '@edgeandnode/eds-utils': 1.0.0(typescript@5.9.3) + '@react-aria/utils': 3.34.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@react-hookz/web': 26.1.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@ver0/deep-equal': 2.0.1 + escape-string-regexp: 5.0.0 + motion: 13.4.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + react: 19.2.4 + react-aria: 3.52.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + react-dom: 19.2.4(react@19.2.4) + react-is: 19.3.0 + react-keyed-flatten-children: 5.1.3(react-is@19.3.0)(react@19.2.4) + react-markdown: 10.1.0(@types/react@19.3.0)(react@19.2.4) + remark-gfm: 4.0.1 + shiki: 4.4.3 + style-observer: 0.1.2 + tailwindcss: 4.3.3 + ts-extras: 1.3.0 + type-fest: 5.10.0 + transitivePeerDependencies: + - '@date-fns/tz' + - '@types/react' + - bufferutil + - date-fns + - js-cookie + - supports-color + - typescript + - utf-8-validate + - zod + + '@edgeandnode/eds-utils@1.0.0(typescript@5.9.3)': + dependencies: + md5: 2.3.0 + viem: 2.56.8(typescript@5.9.3) + transitivePeerDependencies: + - bufferutil + - typescript + - utf-8-validate + - zod + + '@edgeandnode/tailwindcss-animate@1.0.0(tailwindcss@4.3.3)': + dependencies: + tailwindcss: 4.3.3 + + '@floating-ui/core@1.8.0': + dependencies: + '@floating-ui/utils': 0.2.12 + + '@floating-ui/dom@1.8.0': + dependencies: + '@floating-ui/core': 1.8.0 + '@floating-ui/utils': 0.2.12 + + '@floating-ui/react-dom@2.1.9(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@floating-ui/dom': 1.8.0 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@floating-ui/utils@0.2.12': {} + + '@internationalized/date@3.12.4': + dependencies: + '@swc/helpers': 0.5.15 + + '@internationalized/number@3.6.8': + dependencies: + '@swc/helpers': 0.5.15 + + '@internationalized/string@3.2.10': + dependencies: + '@swc/helpers': 0.5.15 + + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.6.0 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/remapping@2.3.5': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/sourcemap-codec@1.6.0': {} + + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.6.0 + + '@noble/ciphers@1.3.0': {} + + '@noble/curves@1.9.1': + dependencies: + '@noble/hashes': 1.8.0 + + '@noble/hashes@1.8.0': {} + + '@oxc-project/types@0.150.0': {} + + '@react-aria/utils@3.34.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@swc/helpers': 0.5.15 + react: 19.2.4 + react-aria: 3.52.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + react-dom: 19.2.4(react@19.2.4) + react-stately: 3.50.0(react@19.2.4) + + '@react-hookz/web@26.1.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@ver0/deep-equal': 2.0.1 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + '@react-types/shared@3.36.1(react@19.2.4)': + dependencies: + react: 19.2.4 + + '@rolldown/binding-android-arm-eabi@1.2.9': + optional: true + + '@rolldown/binding-android-arm64@1.2.9': + optional: true + + '@rolldown/binding-darwin-arm64@1.2.9': + optional: true + + '@rolldown/binding-darwin-x64@1.2.9': + optional: true + + '@rolldown/binding-freebsd-x64@1.2.9': + optional: true + + '@rolldown/binding-linux-arm-gnueabihf@1.2.9': + optional: true + + '@rolldown/binding-linux-arm64-gnu@1.2.9': + optional: true + + '@rolldown/binding-linux-arm64-musl@1.2.9': + optional: true + + '@rolldown/binding-linux-ppc64-gnu@1.2.9': + optional: true + + '@rolldown/binding-linux-s390x-gnu@1.2.9': + optional: true + + '@rolldown/binding-linux-x64-gnu@1.2.9': + optional: true + + '@rolldown/binding-linux-x64-musl@1.2.9': + optional: true + + '@rolldown/binding-openharmony-arm64@1.2.9': + optional: true + + '@rolldown/binding-win32-arm64-msvc@1.2.9': + optional: true + + '@rolldown/binding-win32-x64-msvc@1.2.9': + optional: true + + '@rolldown/pluginutils@1.0.1': {} + + '@scure/base@1.2.6': {} + + '@scure/bip32@1.7.0': + dependencies: + '@noble/curves': 1.9.1 + '@noble/hashes': 1.8.0 + '@scure/base': 1.2.6 + + '@scure/bip39@1.6.0': + dependencies: + '@noble/hashes': 1.8.0 + '@scure/base': 1.2.6 + + '@shikijs/core@4.4.3': + dependencies: + '@shikijs/primitive': 4.4.3 + '@shikijs/types': 4.4.3 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.5 + hast-util-to-html: 9.0.5 + + '@shikijs/engine-javascript@4.4.3': + dependencies: + '@shikijs/types': 4.4.3 + '@shikijs/vscode-textmate': 10.0.2 + oniguruma-to-es: 4.3.6 + + '@shikijs/engine-oniguruma@4.4.3': + dependencies: + '@shikijs/types': 4.4.3 + '@shikijs/vscode-textmate': 10.0.2 + + '@shikijs/langs@4.4.3': + dependencies: + '@shikijs/types': 4.4.3 + + '@shikijs/primitive@4.4.3': + dependencies: + '@shikijs/types': 4.4.3 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.5 + + '@shikijs/themes@4.4.3': + dependencies: + '@shikijs/types': 4.4.3 + + '@shikijs/types@4.4.3': + dependencies: + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.5 + + '@shikijs/vscode-textmate@10.0.2': {} + + '@swc/helpers@0.5.15': + dependencies: + tslib: 2.8.1 + + '@tailwindcss/node@4.3.3': + dependencies: + '@jridgewell/remapping': 2.3.5 + enhanced-resolve: 5.25.1 + jiti: 2.7.0 + lightningcss: 1.32.0 + magic-string: 0.30.21 + source-map-js: 1.2.1 + tailwindcss: 4.3.3 + + '@tailwindcss/oxide-android-arm64@4.3.3': + optional: true + + '@tailwindcss/oxide-darwin-arm64@4.3.3': + optional: true + + '@tailwindcss/oxide-darwin-x64@4.3.3': + optional: true + + '@tailwindcss/oxide-freebsd-x64@4.3.3': + optional: true + + '@tailwindcss/oxide-linux-arm-gnueabihf@4.3.3': + optional: true + + '@tailwindcss/oxide-linux-arm64-gnu@4.3.3': + optional: true + + '@tailwindcss/oxide-linux-arm64-musl@4.3.3': + optional: true + + '@tailwindcss/oxide-linux-x64-gnu@4.3.3': + optional: true + + '@tailwindcss/oxide-linux-x64-musl@4.3.3': + optional: true + + '@tailwindcss/oxide-wasm32-wasi@4.3.3': + optional: true + + '@tailwindcss/oxide-win32-arm64-msvc@4.3.3': + optional: true + + '@tailwindcss/oxide-win32-x64-msvc@4.3.3': + optional: true + + '@tailwindcss/oxide@4.3.3': + optionalDependencies: + '@tailwindcss/oxide-android-arm64': 4.3.3 + '@tailwindcss/oxide-darwin-arm64': 4.3.3 + '@tailwindcss/oxide-darwin-x64': 4.3.3 + '@tailwindcss/oxide-freebsd-x64': 4.3.3 + '@tailwindcss/oxide-linux-arm-gnueabihf': 4.3.3 + '@tailwindcss/oxide-linux-arm64-gnu': 4.3.3 + '@tailwindcss/oxide-linux-arm64-musl': 4.3.3 + '@tailwindcss/oxide-linux-x64-gnu': 4.3.3 + '@tailwindcss/oxide-linux-x64-musl': 4.3.3 + '@tailwindcss/oxide-wasm32-wasi': 4.3.3 + '@tailwindcss/oxide-win32-arm64-msvc': 4.3.3 + '@tailwindcss/oxide-win32-x64-msvc': 4.3.3 + + '@tailwindcss/vite@4.3.3(vite@8.3.0(@types/node@20.19.43)(jiti@2.7.0))': + dependencies: + '@tailwindcss/node': 4.3.3 + '@tailwindcss/oxide': 4.3.3 + tailwindcss: 4.3.3 + vite: 8.3.0(@types/node@20.19.43)(jiti@2.7.0) + + '@types/debug@4.1.13': + dependencies: + '@types/ms': 2.1.0 + + '@types/estree-jsx@1.0.5': + dependencies: + '@types/estree': 1.0.9 + + '@types/estree@1.0.9': {} + + '@types/hast@3.0.5': + dependencies: + '@types/unist': 3.0.3 + + '@types/mdast@4.0.4': + dependencies: + '@types/unist': 3.0.3 + + '@types/ms@2.1.0': {} + + '@types/node@20.19.43': + dependencies: + undici-types: 6.21.0 + + '@types/react-dom@19.3.0(@types/react@19.3.0)': + dependencies: + '@types/react': 19.3.0 + + '@types/react@19.3.0': + dependencies: + csstype: 3.2.3 + + '@types/unist@2.0.11': {} + + '@types/unist@3.0.3': {} + + '@ungap/structured-clone@1.4.0': {} + + '@ver0/deep-equal@2.0.1': {} + + '@vitejs/plugin-react@6.1.1(vite@8.3.0(@types/node@20.19.43)(jiti@2.7.0))': + dependencies: + '@rolldown/pluginutils': 1.0.1 + vite: 8.3.0(@types/node@20.19.43)(jiti@2.7.0) + + '@web3icons/common@0.11.51': {} + + '@web3icons/react@4.1.22(react@19.2.4)': + dependencies: + '@web3icons/common': 0.11.51 + react: 19.2.4 + + abitype@1.2.3(typescript@5.9.3): + optionalDependencies: + typescript: 5.9.3 + + aria-hidden@1.2.6: + dependencies: + tslib: 2.8.1 + + bail@2.0.2: {} + + ccount@2.0.1: {} + + character-entities-html4@2.1.0: {} + + character-entities-legacy@3.0.0: {} + + character-entities@2.0.2: {} + + character-reference-invalid@2.0.1: {} + + charenc@0.0.2: {} + + clsx@2.1.1: {} + + comma-separated-tokens@2.0.3: {} + + cookie@1.1.1: {} + + crypt@0.0.2: {} + + cssesc@3.0.0: {} + + csstype@3.2.3: {} + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + decode-named-character-reference@1.3.0: + dependencies: + character-entities: 2.0.2 + + dequal@2.0.3: {} + + detect-libc@2.1.2: {} + + devlop@1.1.0: + dependencies: + dequal: 2.0.3 + + enhanced-resolve@5.25.1: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.3.3 + + escape-string-regexp@5.0.0: {} + + estree-util-is-identifier-name@3.0.0: {} + + eventemitter3@5.0.1: {} + + extend@3.0.2: {} + + fdir@6.5.0(picomatch@4.0.7): + optionalDependencies: + picomatch: 4.0.7 + + framer-motion@12.43.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4): + dependencies: + motion-dom: 12.43.0 + motion-utils: 12.39.0 + tslib: 2.8.1 + optionalDependencies: + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + framer-motion@13.4.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4): + dependencies: + motion-dom: 13.3.0 + motion-utils: 13.3.0 + tslib: 2.8.1 + optionalDependencies: + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + fsevents@2.3.3: + optional: true + + graceful-fs@4.2.11: {} + + hast-util-to-html@9.0.5: + dependencies: + '@types/hast': 3.0.5 + '@types/unist': 3.0.3 + ccount: 2.0.1 + comma-separated-tokens: 2.0.3 + hast-util-whitespace: 3.0.0 + html-void-elements: 3.0.0 + mdast-util-to-hast: 13.2.1 + property-information: 7.2.0 + space-separated-tokens: 2.0.2 + stringify-entities: 4.0.4 + zwitch: 2.0.4 + + hast-util-to-jsx-runtime@2.3.6: + dependencies: + '@types/estree': 1.0.9 + '@types/hast': 3.0.5 + '@types/unist': 3.0.3 + comma-separated-tokens: 2.0.3 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + hast-util-whitespace: 3.0.0 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-mdxjs-esm: 2.0.1 + property-information: 7.2.0 + space-separated-tokens: 2.0.2 + style-to-js: 1.1.21 + unist-util-position: 5.0.0 + vfile-message: 4.0.3 + transitivePeerDependencies: + - supports-color + + hast-util-whitespace@3.0.0: + dependencies: + '@types/hast': 3.0.5 + + html-url-attributes@3.0.1: {} + + html-void-elements@3.0.0: {} + + inline-style-parser@0.2.7: {} + + is-alphabetical@2.0.1: {} + + is-alphanumerical@2.0.1: + dependencies: + is-alphabetical: 2.0.1 + is-decimal: 2.0.1 + + is-buffer@1.1.6: {} + + is-decimal@2.0.1: {} + + is-hexadecimal@2.0.1: {} + + is-plain-obj@4.1.0: {} + + isows@1.0.7(ws@8.21.0): + dependencies: + ws: 8.21.0 + + jiti@2.7.0: {} + + lightningcss-android-arm64@1.32.0: + optional: true + + lightningcss-android-arm64@1.33.0: + optional: true + + lightningcss-darwin-arm64@1.32.0: + optional: true + + lightningcss-darwin-arm64@1.33.0: + optional: true + + lightningcss-darwin-x64@1.32.0: + optional: true + + lightningcss-darwin-x64@1.33.0: + optional: true + + lightningcss-freebsd-x64@1.32.0: + optional: true + + lightningcss-freebsd-x64@1.33.0: + optional: true + + lightningcss-linux-arm-gnueabihf@1.32.0: + optional: true + + lightningcss-linux-arm-gnueabihf@1.33.0: + optional: true + + lightningcss-linux-arm64-gnu@1.32.0: + optional: true + + lightningcss-linux-arm64-gnu@1.33.0: + optional: true + + lightningcss-linux-arm64-musl@1.32.0: + optional: true + + lightningcss-linux-arm64-musl@1.33.0: + optional: true + + lightningcss-linux-x64-gnu@1.32.0: + optional: true + + lightningcss-linux-x64-gnu@1.33.0: + optional: true + + lightningcss-linux-x64-musl@1.32.0: + optional: true + + lightningcss-linux-x64-musl@1.33.0: + optional: true + + lightningcss-win32-arm64-msvc@1.32.0: + optional: true + + lightningcss-win32-arm64-msvc@1.33.0: + optional: true + + lightningcss-win32-x64-msvc@1.32.0: + optional: true + + lightningcss-win32-x64-msvc@1.33.0: + optional: true + + lightningcss@1.32.0: + dependencies: + detect-libc: 2.1.2 + optionalDependencies: + lightningcss-android-arm64: 1.32.0 + lightningcss-darwin-arm64: 1.32.0 + lightningcss-darwin-x64: 1.32.0 + lightningcss-freebsd-x64: 1.32.0 + lightningcss-linux-arm-gnueabihf: 1.32.0 + lightningcss-linux-arm64-gnu: 1.32.0 + lightningcss-linux-arm64-musl: 1.32.0 + lightningcss-linux-x64-gnu: 1.32.0 + lightningcss-linux-x64-musl: 1.32.0 + lightningcss-win32-arm64-msvc: 1.32.0 + lightningcss-win32-x64-msvc: 1.32.0 + + lightningcss@1.33.0: + dependencies: + detect-libc: 2.1.2 + optionalDependencies: + lightningcss-android-arm64: 1.33.0 + lightningcss-darwin-arm64: 1.33.0 + lightningcss-darwin-x64: 1.33.0 + lightningcss-freebsd-x64: 1.33.0 + lightningcss-linux-arm-gnueabihf: 1.33.0 + lightningcss-linux-arm64-gnu: 1.33.0 + lightningcss-linux-arm64-musl: 1.33.0 + lightningcss-linux-x64-gnu: 1.33.0 + lightningcss-linux-x64-musl: 1.33.0 + lightningcss-win32-arm64-msvc: 1.33.0 + lightningcss-win32-x64-msvc: 1.33.0 + + longest-streak@3.1.0: {} + + magic-string@0.30.21: + dependencies: + '@jridgewell/sourcemap-codec': 1.6.0 + + markdown-table@3.0.4: {} + + md5@2.3.0: + dependencies: + charenc: 0.0.2 + crypt: 0.0.2 + is-buffer: 1.1.6 + + mdast-util-find-and-replace@3.0.2: + dependencies: + '@types/mdast': 4.0.4 + escape-string-regexp: 5.0.0 + unist-util-is: 6.0.1 + unist-util-visit-parents: 6.0.2 + + mdast-util-from-markdown@2.0.3: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + mdast-util-to-string: 4.0.0 + micromark: 4.0.2 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-decode-string: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-stringify-position: 4.0.0 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-autolink-literal@2.0.1: + dependencies: + '@types/mdast': 4.0.4 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-find-and-replace: 3.0.2 + micromark-util-character: 2.1.1 + + mdast-util-gfm-footnote@2.1.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + micromark-util-normalize-identifier: 2.0.1 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-strikethrough@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-table@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + markdown-table: 3.0.4 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm-task-list-item@2.0.0: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-gfm@3.1.0: + dependencies: + mdast-util-from-markdown: 2.0.3 + mdast-util-gfm-autolink-literal: 2.0.1 + mdast-util-gfm-footnote: 2.1.0 + mdast-util-gfm-strikethrough: 2.0.0 + mdast-util-gfm-table: 2.0.0 + mdast-util-gfm-task-list-item: 2.0.0 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-mdx-expression@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.5 + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-mdx-jsx@3.2.0: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.5 + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + parse-entities: 4.0.2 + stringify-entities: 4.0.4 + unist-util-stringify-position: 4.0.0 + vfile-message: 4.0.3 + transitivePeerDependencies: + - supports-color + + mdast-util-mdxjs-esm@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.5 + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-phrasing@4.1.0: + dependencies: + '@types/mdast': 4.0.4 + unist-util-is: 6.0.1 + + mdast-util-to-hast@13.2.1: + dependencies: + '@types/hast': 3.0.5 + '@types/mdast': 4.0.4 + '@ungap/structured-clone': 1.4.0 + devlop: 1.1.0 + micromark-util-sanitize-uri: 2.0.1 + trim-lines: 3.0.1 + unist-util-position: 5.0.0 + unist-util-visit: 5.1.0 + vfile: 6.0.3 + + mdast-util-to-markdown@2.1.2: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + longest-streak: 3.1.0 + mdast-util-phrasing: 4.1.0 + mdast-util-to-string: 4.0.0 + micromark-util-classify-character: 2.0.1 + micromark-util-decode-string: 2.0.1 + unist-util-visit: 5.1.0 + zwitch: 2.0.4 + + mdast-util-to-string@4.0.0: + dependencies: + '@types/mdast': 4.0.4 + + micromark-core-commonmark@2.0.3: + dependencies: + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + micromark-factory-destination: 2.0.1 + micromark-factory-label: 2.0.1 + micromark-factory-space: 2.0.1 + micromark-factory-title: 2.0.1 + micromark-factory-whitespace: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-html-tag-name: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-autolink-literal@2.1.0: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-footnote@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-strikethrough@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-table@2.1.2: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-tagfilter@2.0.0: + dependencies: + micromark-util-types: 2.0.2 + + micromark-extension-gfm-task-list-item@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm@3.0.0: + dependencies: + micromark-extension-gfm-autolink-literal: 2.1.0 + micromark-extension-gfm-footnote: 2.1.0 + micromark-extension-gfm-strikethrough: 2.1.0 + micromark-extension-gfm-table: 2.1.2 + micromark-extension-gfm-tagfilter: 2.0.0 + micromark-extension-gfm-task-list-item: 2.1.0 + micromark-util-combine-extensions: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-destination@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-label@2.0.1: + dependencies: + devlop: 1.1.0 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-space@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-types: 2.0.2 + + micromark-factory-title@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-whitespace@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-character@2.1.1: + dependencies: + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-chunked@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-classify-character@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-combine-extensions@2.0.1: + dependencies: + micromark-util-chunked: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-decode-numeric-character-reference@2.0.2: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-decode-string@2.0.1: + dependencies: + decode-named-character-reference: 1.3.0 + micromark-util-character: 2.1.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-symbol: 2.0.1 + + micromark-util-encode@2.0.1: {} + + micromark-util-html-tag-name@2.0.1: {} + + micromark-util-normalize-identifier@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-resolve-all@2.0.1: + dependencies: + micromark-util-types: 2.0.2 + + micromark-util-sanitize-uri@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-encode: 2.0.1 + micromark-util-symbol: 2.0.1 + + micromark-util-subtokenize@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-symbol@2.0.1: {} + + micromark-util-types@2.0.2: {} + + micromark@4.0.2: + dependencies: + '@types/debug': 4.1.13 + debug: 4.4.3 + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-combine-extensions: 2.0.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-encode: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + transitivePeerDependencies: + - supports-color + + motion-dom@12.43.0: + dependencies: + motion-utils: 12.39.0 + + motion-dom@13.3.0: + dependencies: + motion-utils: 13.3.0 + + motion-utils@12.39.0: {} + + motion-utils@13.3.0: {} + + motion@12.43.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4): + dependencies: + framer-motion: 12.43.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + tslib: 2.8.1 + optionalDependencies: + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + motion@13.4.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4): + dependencies: + framer-motion: 13.4.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + tslib: 2.8.1 + optionalDependencies: + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + ms@2.1.3: {} + + nanoid@3.3.19: {} + + oniguruma-parser@0.12.2: {} + + oniguruma-to-es@4.3.6: + dependencies: + oniguruma-parser: 0.12.2 + regex: 6.1.0 + regex-recursion: 6.0.2 + + ox@0.14.45(typescript@5.9.3): + dependencies: + '@adraffy/ens-normalize': 1.11.1 + '@noble/ciphers': 1.3.0 + '@noble/curves': 1.9.1 + '@noble/hashes': 1.8.0 + '@scure/bip32': 1.7.0 + '@scure/bip39': 1.6.0 + abitype: 1.2.3(typescript@5.9.3) + eventemitter3: 5.0.1 + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - zod + + parse-entities@4.0.2: + dependencies: + '@types/unist': 2.0.11 + character-entities-legacy: 3.0.0 + character-reference-invalid: 2.0.1 + decode-named-character-reference: 1.3.0 + is-alphanumerical: 2.0.1 + is-decimal: 2.0.1 + is-hexadecimal: 2.0.1 + + picocolors@1.1.1: {} + + picomatch@4.0.7: {} + + postcss@8.5.28: + dependencies: + nanoid: 3.3.19 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + property-information@7.2.0: {} + + react-aria@3.52.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4): + dependencies: + '@internationalized/date': 3.12.4 + '@internationalized/number': 3.6.8 + '@internationalized/string': 3.2.10 + '@react-types/shared': 3.36.1(react@19.2.4) + '@swc/helpers': 0.5.15 + aria-hidden: 1.2.6 + clsx: 2.1.1 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + react-stately: 3.50.0(react@19.2.4) + use-sync-external-store: 1.7.0(react@19.2.4) + + react-dom@19.2.4(react@19.2.4): + dependencies: + react: 19.2.4 + scheduler: 0.27.0 + + react-is@19.3.0: {} + + react-keyed-flatten-children@5.1.3(react-is@19.3.0)(react@19.2.4): + dependencies: + react: 19.2.4 + react-is: 19.3.0 + + react-markdown@10.1.0(@types/react@19.3.0)(react@19.2.4): + dependencies: + '@types/hast': 3.0.5 + '@types/mdast': 4.0.4 + '@types/react': 19.3.0 + devlop: 1.1.0 + hast-util-to-jsx-runtime: 2.3.6 + html-url-attributes: 3.0.1 + mdast-util-to-hast: 13.2.1 + react: 19.2.4 + remark-parse: 11.0.0 + remark-rehype: 11.1.2 + unified: 11.0.5 + unist-util-visit: 5.1.0 + vfile: 6.0.3 + transitivePeerDependencies: + - supports-color + + react-router@7.18.4(react-dom@19.2.4(react@19.2.4))(react@19.2.4): + dependencies: + cookie: 1.1.1 + react: 19.2.4 + set-cookie-parser: 2.7.2 + optionalDependencies: + react-dom: 19.2.4(react@19.2.4) + + react-stately@3.50.0(react@19.2.4): + dependencies: + '@internationalized/date': 3.12.4 + '@internationalized/number': 3.6.8 + '@internationalized/string': 3.2.10 + '@react-types/shared': 3.36.1(react@19.2.4) + '@swc/helpers': 0.5.15 + react: 19.2.4 + use-sync-external-store: 1.7.0(react@19.2.4) + + react@19.2.4: {} + + regex-recursion@6.0.2: + dependencies: + regex-utilities: 2.3.0 + + regex-utilities@2.3.0: {} + + regex@6.1.0: + dependencies: + regex-utilities: 2.3.0 + + remark-gfm@4.0.1: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-gfm: 3.1.0 + micromark-extension-gfm: 3.0.0 + remark-parse: 11.0.0 + remark-stringify: 11.0.0 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-parse@11.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-from-markdown: 2.0.3 + micromark-util-types: 2.0.2 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-rehype@11.1.2: + dependencies: + '@types/hast': 3.0.5 + '@types/mdast': 4.0.4 + mdast-util-to-hast: 13.2.1 + unified: 11.0.5 + vfile: 6.0.3 + + remark-stringify@11.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-to-markdown: 2.1.2 + unified: 11.0.5 + + reselect@5.3.0: {} + + rolldown@1.2.9: + dependencies: + '@oxc-project/types': 0.150.0 + '@rolldown/pluginutils': 1.0.1 + optionalDependencies: + '@rolldown/binding-android-arm-eabi': 1.2.9 + '@rolldown/binding-android-arm64': 1.2.9 + '@rolldown/binding-darwin-arm64': 1.2.9 + '@rolldown/binding-darwin-x64': 1.2.9 + '@rolldown/binding-freebsd-x64': 1.2.9 + '@rolldown/binding-linux-arm-gnueabihf': 1.2.9 + '@rolldown/binding-linux-arm64-gnu': 1.2.9 + '@rolldown/binding-linux-arm64-musl': 1.2.9 + '@rolldown/binding-linux-ppc64-gnu': 1.2.9 + '@rolldown/binding-linux-s390x-gnu': 1.2.9 + '@rolldown/binding-linux-x64-gnu': 1.2.9 + '@rolldown/binding-linux-x64-musl': 1.2.9 + '@rolldown/binding-openharmony-arm64': 1.2.9 + '@rolldown/binding-win32-arm64-msvc': 1.2.9 + '@rolldown/binding-win32-x64-msvc': 1.2.9 + + scheduler@0.27.0: {} + + set-cookie-parser@2.7.2: {} + + shiki@4.4.3: + dependencies: + '@shikijs/core': 4.4.3 + '@shikijs/engine-javascript': 4.4.3 + '@shikijs/engine-oniguruma': 4.4.3 + '@shikijs/langs': 4.4.3 + '@shikijs/themes': 4.4.3 + '@shikijs/types': 4.4.3 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.5 + + source-map-js@1.2.1: {} + + space-separated-tokens@2.0.2: {} + + stringify-entities@4.0.4: + dependencies: + character-entities-html4: 2.1.0 + character-entities-legacy: 3.0.0 + + style-observer@0.1.2: {} + + style-to-js@1.1.21: + dependencies: + style-to-object: 1.0.14 + + style-to-object@1.0.14: + dependencies: + inline-style-parser: 0.2.7 + + tagged-tag@1.0.0: {} + + tailwindcss@4.3.3: {} + + tapable@2.3.3: {} + + tinyglobby@0.2.17: + dependencies: + fdir: 6.5.0(picomatch@4.0.7) + picomatch: 4.0.7 + + trim-lines@3.0.1: {} + + trough@2.2.0: {} + + ts-extras@1.3.0: + dependencies: + type-fest: 5.10.0 + + tslib@2.8.1: {} + + type-fest@5.10.0: + dependencies: + tagged-tag: 1.0.0 + + typescript@5.9.3: {} + + undici-types@6.21.0: {} + + unified@11.0.5: + dependencies: + '@types/unist': 3.0.3 + bail: 2.0.2 + devlop: 1.1.0 + extend: 3.0.2 + is-plain-obj: 4.1.0 + trough: 2.2.0 + vfile: 6.0.3 + + unist-util-is@6.0.1: + dependencies: + '@types/unist': 3.0.3 + + unist-util-position@5.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-stringify-position@4.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-visit-parents@6.0.2: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + + unist-util-visit@5.1.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + unist-util-visit-parents: 6.0.2 + + use-sync-external-store@1.7.0(react@19.2.4): + dependencies: + react: 19.2.4 + + vfile-message@4.0.3: + dependencies: + '@types/unist': 3.0.3 + unist-util-stringify-position: 4.0.0 + + vfile@6.0.3: + dependencies: + '@types/unist': 3.0.3 + vfile-message: 4.0.3 + + viem@2.56.8(typescript@5.9.3): + dependencies: + '@noble/curves': 1.9.1 + '@noble/hashes': 1.8.0 + '@scure/bip32': 1.7.0 + '@scure/bip39': 1.6.0 + abitype: 1.2.3(typescript@5.9.3) + isows: 1.0.7(ws@8.21.0) + ox: 0.14.45(typescript@5.9.3) + ws: 8.21.0 + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + + vite@8.3.0(@types/node@20.19.43)(jiti@2.7.0): + dependencies: + lightningcss: 1.33.0 + picomatch: 4.0.7 + postcss: 8.5.28 + rolldown: 1.2.9 + tinyglobby: 0.2.17 + optionalDependencies: + '@types/node': 20.19.43 + fsevents: 2.3.3 + jiti: 2.7.0 + + ws@8.21.0: {} + + zwitch@2.0.4: {} diff --git a/website/pnpm-workspace.yaml b/website/pnpm-workspace.yaml new file mode 100644 index 0000000..ce554c1 --- /dev/null +++ b/website/pnpm-workspace.yaml @@ -0,0 +1,2 @@ +onlyBuiltDependencies: + - '@edgeandnode/eds-react' diff --git a/website/public/fonts/MessinaSans-Regular.woff2 b/website/public/fonts/MessinaSans-Regular.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..3dd2e7c15a7c23bd72ed2953307ac439e97f195c GIT binary patch literal 18448 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 Dm-_go literal 0 HcmV?d00001 diff --git a/website/public/logo-amp.svg b/website/public/logo-amp.svg new file mode 100644 index 0000000..d1820e3 --- /dev/null +++ b/website/public/logo-amp.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/website/tsconfig.json b/website/tsconfig.json new file mode 100644 index 0000000..95b95ad --- /dev/null +++ b/website/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "target": "ES2020", + "lib": ["dom", "dom.iterable", "esnext"], + "types": ["vite/client"], + "skipLibCheck": true, + "strict": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "bundler", + "resolveJsonModule": true, + "isolatedModules": true, + "allowImportingTsExtensions": true, + "jsx": "react-jsx", + "paths": { "@/*": ["./*"] } + }, + "include": ["app", "components", "data", "lib", "vite.config.ts"], + "exclude": ["node_modules", "dist"] +} diff --git a/website/vite.config.ts b/website/vite.config.ts new file mode 100644 index 0000000..e476400 --- /dev/null +++ b/website/vite.config.ts @@ -0,0 +1,10 @@ +import { fileURLToPath } from "node:url"; +import { defineConfig } from "vite"; +import react from "@vitejs/plugin-react"; +import tailwindcss from "@tailwindcss/vite"; + +export default defineConfig({ + plugins: [react(), tailwindcss()], + resolve: { alias: { "@": fileURLToPath(new URL(".", import.meta.url)) } }, + server: { port: 3000 }, +});