diff --git a/astro.config.ts b/astro.config.ts
index bafbd5b77a2..16ae5388f55 100644
--- a/astro.config.ts
+++ b/astro.config.ts
@@ -13,6 +13,7 @@ import yaml from "@rollup/plugin-yaml"
import { ccipRedirects } from "./src/config/redirects/ccip"
import trailingSlashMiddleware from "./src/integrations/trailing-slash-middleware"
import redirectsJson from "./src/features/redirects/redirects.json"
+import tailwind from "@astrojs/tailwind"
import { extractCanonicalUrlsWithLanguageVariants } from "./src/utils/sidebar"
config() // Load .env file
@@ -46,6 +47,7 @@ export default defineConfig({
...ccipRedirects,
},
integrations: [
+ tailwind(),
trailingSlashMiddleware(),
preact({
include: ["**/preact/*"],
diff --git a/package-lock.json b/package-lock.json
index 82c8118a6c9..5c853d27f04 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -10,6 +10,8 @@
"license": "ISC",
"dependencies": {
"@11ty/eleventy-fetch": "^4.0.1",
+ "@algolia/client-search": "^5.41.0",
+ "@apollo/client": "^3.14.0",
"@astro-community/astro-embed-youtube": "^0.5.9",
"@astrojs/mdx": "^4.3.12",
"@astrojs/partytown": "^2.1.4",
@@ -17,7 +19,9 @@
"@astrojs/prism": "^3.3.0",
"@astrojs/react": "^4.4.2",
"@astrojs/sitemap": "^3.6.0",
+ "@astrojs/tailwind": "^6.0.2",
"@astrojs/vercel": "^8.2.11",
+ "@chainlink/blocks": "^1.3.1",
"@chainlink/cl-search-frontend": "^0.12.1",
"@chainlink/components": "^0.4.18",
"@chainlink/contracts": "1.5.0",
@@ -98,12 +102,15 @@
"pino-pretty": "^13.1.3",
"prettier": "^3.7.4",
"prettier-plugin-astro": "^0.14.1",
+ "prettier-plugin-solidity": "^1.4.3",
"remark-gfm": "^4.0.0",
"remark-mdx": "^3.1.0",
"remark-parse": "^11.0.0",
"remark-stringify": "^11.0.0",
"solhint": "^6.0.1",
"solhint-plugin-chainlink-solidity": "github:smartcontractkit/chainlink-solhint-rules#v1.3.0",
+ "solhint-plugin-prettier": "^0.1.0",
+ "tailwindcss": "^3.4.18",
"ts-jest": "^29.4.6",
"tsconfig-paths": "^4.2.0",
"tsx": "^4.21.0",
@@ -472,6 +479,47 @@
"openapi-types": ">=7"
}
},
+ "node_modules/@apollo/client": {
+ "version": "3.14.0",
+ "resolved": "https://registry.npmjs.org/@apollo/client/-/client-3.14.0.tgz",
+ "integrity": "sha512-0YQKKRIxiMlIou+SekQqdCo0ZTHxOcES+K8vKB53cIDpwABNR0P0yRzPgsbgcj3zRJniD93S/ontsnZsCLZrxQ==",
+ "dependencies": {
+ "@graphql-typed-document-node/core": "^3.1.1",
+ "@wry/caches": "^1.0.0",
+ "@wry/equality": "^0.5.6",
+ "@wry/trie": "^0.5.0",
+ "graphql-tag": "^2.12.6",
+ "hoist-non-react-statics": "^3.3.2",
+ "optimism": "^0.18.0",
+ "prop-types": "^15.7.2",
+ "rehackt": "^0.1.0",
+ "symbol-observable": "^4.0.0",
+ "ts-invariant": "^0.10.3",
+ "tslib": "^2.3.0",
+ "zen-observable-ts": "^1.2.5"
+ },
+ "peerDependencies": {
+ "graphql": "^15.0.0 || ^16.0.0",
+ "graphql-ws": "^5.5.5 || ^6.0.3",
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || >=19.0.0-rc",
+ "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || >=19.0.0-rc",
+ "subscriptions-transport-ws": "^0.9.0 || ^0.11.0"
+ },
+ "peerDependenciesMeta": {
+ "graphql-ws": {
+ "optional": true
+ },
+ "react": {
+ "optional": true
+ },
+ "react-dom": {
+ "optional": true
+ },
+ "subscriptions-transport-ws": {
+ "optional": true
+ }
+ }
+ },
"node_modules/@arbitrum/nitro-contracts": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@arbitrum/nitro-contracts/-/nitro-contracts-3.0.0.tgz",
@@ -649,6 +697,49 @@
"zod": "^3.25.76"
}
},
+ "node_modules/@astrojs/tailwind": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/@astrojs/tailwind/-/tailwind-6.0.2.tgz",
+ "integrity": "sha512-j3mhLNeugZq6A8dMNXVarUa8K6X9AW+QHU9u3lKNrPLMHhOQ0S7VeWhHwEeJFpEK1BTKEUY1U78VQv2gN6hNGg==",
+ "license": "MIT",
+ "dependencies": {
+ "autoprefixer": "^10.4.21",
+ "postcss": "^8.5.3",
+ "postcss-load-config": "^4.0.2"
+ },
+ "peerDependencies": {
+ "astro": "^3.0.0 || ^4.0.0 || ^5.0.0",
+ "tailwindcss": "^3.0.24"
+ }
+ },
+ "node_modules/@astrojs/tailwind/node_modules/postcss": {
+ "version": "8.5.6",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
+ "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "nanoid": "^3.3.11",
+ "picocolors": "^1.1.1",
+ "source-map-js": "^1.2.1"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
"node_modules/@astrojs/telemetry": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/@astrojs/telemetry/-/telemetry-3.3.0.tgz",
@@ -1299,6 +1390,514 @@
"node": ">=18"
}
},
+ "node_modules/@chainlink/blocks": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/@chainlink/blocks/-/blocks-1.3.1.tgz",
+ "integrity": "sha512-0Px46fJA7aIm7cFuF/6CgV1ZSbkNKfe+QBA0XO7j9Ld8cevlIF/r4GsqR5zDbSaHPejvRloMQJVZoBsU9qINnA==",
+ "license": "ISC",
+ "dependencies": {
+ "@floating-ui/react": "0.22.2",
+ "@hookform/resolvers": "3.9.1",
+ "@radix-ui/react-accordion": "1.2.1",
+ "@radix-ui/react-checkbox": "1.1.2",
+ "@radix-ui/react-dialog": "1.1.6",
+ "@radix-ui/react-dropdown-menu": "2.0.6",
+ "@radix-ui/react-label": "2.1.0",
+ "@radix-ui/react-navigation-menu": "1.1.3",
+ "@radix-ui/react-popover": "1.1.1",
+ "@radix-ui/react-radio-group": "1.2.1",
+ "@radix-ui/react-select": "2.1.2",
+ "@radix-ui/react-slot": "1.0.2",
+ "@radix-ui/react-switch": "1.1.1",
+ "@radix-ui/react-tabs": "1.1.3",
+ "@radix-ui/react-toast": "1.2.4",
+ "@radix-ui/react-toggle": "1.1.9",
+ "@radix-ui/react-toggle-group": "1.1.9",
+ "@radix-ui/react-tooltip": "1.0.7",
+ "@tailwindcss/container-queries": "0.1.1",
+ "@tanstack/react-query": "5.69.0",
+ "@tanstack/react-table": "8.20.5",
+ "apexcharts": "4.5.0",
+ "class-variance-authority": "0.7.0",
+ "clsx": "2.1.1",
+ "lucide-react": "0.390.0",
+ "react": "18.3.1",
+ "react-apexcharts": "1.7.0",
+ "react-dom": "18.3.1",
+ "react-hook-form": "7.53.1",
+ "react-modal": "3.16.1",
+ "react-transition-group": "4.4.5",
+ "sonner": "1.7.3",
+ "tailwind-merge": "2.3.0",
+ "tailwindcss": "3.4.4",
+ "tailwindcss-animate": "1.0.7",
+ "zod": "3.25.76"
+ },
+ "peerDependencies": {
+ "react": ">=18.0.0 <19.0.0",
+ "react-dom": ">=18.0.0 <19.0.0",
+ "tailwindcss": ">=3.0.0 <4.0.0"
+ },
+ "peerDependenciesMeta": {
+ "react": {
+ "optional": false
+ },
+ "react-dom": {
+ "optional": false
+ }
+ }
+ },
+ "node_modules/@chainlink/blocks/node_modules/@radix-ui/primitive": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.1.tgz",
+ "integrity": "sha512-SJ31y+Q/zAyShtXJc8x83i9TYdbAfHZ++tUZnvjJJqFjzsdUnKsxPL6IEtBlxKkU7yzer//GQtZSV4GbldL3YA==",
+ "license": "MIT"
+ },
+ "node_modules/@chainlink/blocks/node_modules/@radix-ui/react-dialog": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.6.tgz",
+ "integrity": "sha512-/IVhJV5AceX620DUJ4uYVMymzsipdKBzo3edo+omeskCKGm9FRHM0ebIdbPnlQVJqyuHbuBltQUOG2mOTq2IYw==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.1.1",
+ "@radix-ui/react-compose-refs": "1.1.1",
+ "@radix-ui/react-context": "1.1.1",
+ "@radix-ui/react-dismissable-layer": "1.1.5",
+ "@radix-ui/react-focus-guards": "1.1.1",
+ "@radix-ui/react-focus-scope": "1.1.2",
+ "@radix-ui/react-id": "1.1.0",
+ "@radix-ui/react-portal": "1.1.4",
+ "@radix-ui/react-presence": "1.1.2",
+ "@radix-ui/react-primitive": "2.0.2",
+ "@radix-ui/react-slot": "1.1.2",
+ "@radix-ui/react-use-controllable-state": "1.1.0",
+ "aria-hidden": "^1.2.4",
+ "react-remove-scroll": "^2.6.3"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@chainlink/blocks/node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-compose-refs": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.1.tgz",
+ "integrity": "sha512-Y9VzoRDSJtgFMUCoiZBDVo084VQ5hfpXxVE+NgkdNsjiDBByiImMZKKhxMwCbdHvhlENG6a833CbFkOQvTricw==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@chainlink/blocks/node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-context": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.1.tgz",
+ "integrity": "sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@chainlink/blocks/node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-dismissable-layer": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.5.tgz",
+ "integrity": "sha512-E4TywXY6UsXNRhFrECa5HAvE5/4BFcGyfTyK36gP+pAW1ed7UTK4vKwdr53gAJYwqbfCWC6ATvJa3J3R/9+Qrg==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.1.1",
+ "@radix-ui/react-compose-refs": "1.1.1",
+ "@radix-ui/react-primitive": "2.0.2",
+ "@radix-ui/react-use-callback-ref": "1.1.0",
+ "@radix-ui/react-use-escape-keydown": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@chainlink/blocks/node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-dismissable-layer/node_modules/@radix-ui/react-use-callback-ref": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz",
+ "integrity": "sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@chainlink/blocks/node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-dismissable-layer/node_modules/@radix-ui/react-use-escape-keydown": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.0.tgz",
+ "integrity": "sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-use-callback-ref": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@chainlink/blocks/node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-focus-guards": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.1.tgz",
+ "integrity": "sha512-pSIwfrT1a6sIoDASCSpFwOasEwKTZWDw/iBdtnqKO7v6FeOzYJ7U53cPzYFVR3geGGXgVHaH+CdngrrAzqUGxg==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@chainlink/blocks/node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-focus-scope": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.2.tgz",
+ "integrity": "sha512-zxwE80FCU7lcXUGWkdt6XpTTCKPitG1XKOwViTxHVKIJhZl9MvIl2dVHeZENCWD9+EdWv05wlaEkRXUykU27RA==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-compose-refs": "1.1.1",
+ "@radix-ui/react-primitive": "2.0.2",
+ "@radix-ui/react-use-callback-ref": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@chainlink/blocks/node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-focus-scope/node_modules/@radix-ui/react-use-callback-ref": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz",
+ "integrity": "sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@chainlink/blocks/node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-id": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.0.tgz",
+ "integrity": "sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-use-layout-effect": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@chainlink/blocks/node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-id/node_modules/@radix-ui/react-use-layout-effect": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz",
+ "integrity": "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@chainlink/blocks/node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-portal": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.4.tgz",
+ "integrity": "sha512-sn2O9k1rPFYVyKd5LAJfo96JlSGVFpa1fS6UuBJfrZadudiw5tAmru+n1x7aMRQ84qDM71Zh1+SzK5QwU0tJfA==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-primitive": "2.0.2",
+ "@radix-ui/react-use-layout-effect": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@chainlink/blocks/node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-portal/node_modules/@radix-ui/react-use-layout-effect": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz",
+ "integrity": "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@chainlink/blocks/node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-presence": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.2.tgz",
+ "integrity": "sha512-18TFr80t5EVgL9x1SwF/YGtfG+l0BS0PRAlCWBDoBEiDQjeKgnNZRVJp/oVBl24sr3Gbfwc/Qpj4OcWTQMsAEg==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-compose-refs": "1.1.1",
+ "@radix-ui/react-use-layout-effect": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@chainlink/blocks/node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-presence/node_modules/@radix-ui/react-use-layout-effect": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz",
+ "integrity": "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@chainlink/blocks/node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-primitive": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.2.tgz",
+ "integrity": "sha512-Ec/0d38EIuvDF+GZjcMU/Ze6MxntVJYO/fRlCPhCaVUyPY9WTalHJw54tp9sXeJo3tlShWpy41vQRgLRGOuz+w==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-slot": "1.1.2"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@chainlink/blocks/node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-slot": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.2.tgz",
+ "integrity": "sha512-YAKxaiGsSQJ38VzKH86/BPRC4rh+b1Jpa+JneA5LRE7skmLPNAyeG8kPJj/oo4STLvlrs8vkf/iYyc3A5stYCQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-compose-refs": "1.1.1"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@chainlink/blocks/node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-use-controllable-state": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.1.0.tgz",
+ "integrity": "sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-use-callback-ref": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@chainlink/blocks/node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-use-controllable-state/node_modules/@radix-ui/react-use-callback-ref": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz",
+ "integrity": "sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@chainlink/blocks/node_modules/@radix-ui/react-dialog/node_modules/react-remove-scroll": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.7.1.tgz",
+ "integrity": "sha512-HpMh8+oahmIdOuS5aFKKY6Pyog+FNaZV/XyJOq7b4YFwsFHe5yYfdbIalI4k3vU2nSDql7YskmUseHsRrJqIPA==",
+ "license": "MIT",
+ "dependencies": {
+ "react-remove-scroll-bar": "^2.3.7",
+ "react-style-singleton": "^2.2.3",
+ "tslib": "^2.1.0",
+ "use-callback-ref": "^1.3.3",
+ "use-sidecar": "^1.1.3"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@chainlink/blocks/node_modules/jiti": {
+ "version": "1.21.7",
+ "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz",
+ "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==",
+ "bin": {
+ "jiti": "bin/jiti.js"
+ }
+ },
+ "node_modules/@chainlink/blocks/node_modules/lilconfig": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz",
+ "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@chainlink/blocks/node_modules/tailwindcss": {
+ "version": "3.4.4",
+ "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.4.tgz",
+ "integrity": "sha512-ZoyXOdJjISB7/BcLTR6SEsLgKtDStYyYZVLsUtWChO4Ps20CBad7lfJKVDiejocV4ME1hLmyY0WJE3hSDcmQ2A==",
+ "license": "MIT",
+ "dependencies": {
+ "@alloc/quick-lru": "^5.2.0",
+ "arg": "^5.0.2",
+ "chokidar": "^3.5.3",
+ "didyoumean": "^1.2.2",
+ "dlv": "^1.1.3",
+ "fast-glob": "^3.3.0",
+ "glob-parent": "^6.0.2",
+ "is-glob": "^4.0.3",
+ "jiti": "^1.21.0",
+ "lilconfig": "^2.1.0",
+ "micromatch": "^4.0.5",
+ "normalize-path": "^3.0.0",
+ "object-hash": "^3.0.0",
+ "picocolors": "^1.0.0",
+ "postcss": "^8.4.23",
+ "postcss-import": "^15.1.0",
+ "postcss-js": "^4.0.1",
+ "postcss-load-config": "^4.0.1",
+ "postcss-nested": "^6.0.1",
+ "postcss-selector-parser": "^6.0.11",
+ "resolve": "^1.22.2",
+ "sucrase": "^3.32.0"
+ },
+ "bin": {
+ "tailwind": "lib/cli.js",
+ "tailwindcss": "lib/cli.js"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
"node_modules/@chainlink/cl-search-frontend": {
"version": "0.12.1",
"resolved": "https://registry.npmjs.org/@chainlink/cl-search-frontend/-/cl-search-frontend-0.12.1.tgz",
@@ -1366,43 +1965,68 @@
],
"license": "MIT",
"dependencies": {
- "@ethersproject/abi": "5.7.0",
- "@ethersproject/abstract-provider": "5.7.0",
- "@ethersproject/abstract-signer": "5.7.0",
- "@ethersproject/address": "5.7.0",
- "@ethersproject/base64": "5.7.0",
- "@ethersproject/basex": "5.7.0",
- "@ethersproject/bignumber": "5.7.0",
- "@ethersproject/bytes": "5.7.0",
- "@ethersproject/constants": "5.7.0",
- "@ethersproject/contracts": "5.7.0",
- "@ethersproject/hash": "5.7.0",
- "@ethersproject/hdnode": "5.7.0",
- "@ethersproject/json-wallets": "5.7.0",
- "@ethersproject/keccak256": "5.7.0",
- "@ethersproject/logger": "5.7.0",
- "@ethersproject/networks": "5.7.1",
- "@ethersproject/pbkdf2": "5.7.0",
- "@ethersproject/properties": "5.7.0",
- "@ethersproject/providers": "5.7.2",
- "@ethersproject/random": "5.7.0",
- "@ethersproject/rlp": "5.7.0",
- "@ethersproject/sha2": "5.7.0",
- "@ethersproject/signing-key": "5.7.0",
- "@ethersproject/solidity": "5.7.0",
- "@ethersproject/strings": "5.7.0",
- "@ethersproject/transactions": "5.7.0",
- "@ethersproject/units": "5.7.0",
- "@ethersproject/wallet": "5.7.0",
- "@ethersproject/web": "5.7.1",
- "@ethersproject/wordlists": "5.7.0"
+ "@ethersproject/bytes": "^5.8.0",
+ "@ethersproject/sha2": "^5.8.0"
+ }
+ },
+ "node_modules/@chainlink/components/node_modules/jiti": {
+ "version": "1.21.7",
+ "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz",
+ "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==",
+ "bin": {
+ "jiti": "bin/jiti.js"
+ }
+ },
+ "node_modules/@chainlink/components/node_modules/lilconfig": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz",
+ "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@chainlink/components/node_modules/tailwindcss": {
+ "version": "3.4.4",
+ "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.4.tgz",
+ "integrity": "sha512-ZoyXOdJjISB7/BcLTR6SEsLgKtDStYyYZVLsUtWChO4Ps20CBad7lfJKVDiejocV4ME1hLmyY0WJE3hSDcmQ2A==",
+ "license": "MIT",
+ "dependencies": {
+ "@alloc/quick-lru": "^5.2.0",
+ "arg": "^5.0.2",
+ "chokidar": "^3.5.3",
+ "didyoumean": "^1.2.2",
+ "dlv": "^1.1.3",
+ "fast-glob": "^3.3.0",
+ "glob-parent": "^6.0.2",
+ "is-glob": "^4.0.3",
+ "jiti": "^1.21.0",
+ "lilconfig": "^2.1.0",
+ "micromatch": "^4.0.5",
+ "normalize-path": "^3.0.0",
+ "object-hash": "^3.0.0",
+ "picocolors": "^1.0.0",
+ "postcss": "^8.4.23",
+ "postcss-import": "^15.1.0",
+ "postcss-js": "^4.0.1",
+ "postcss-load-config": "^4.0.1",
+ "postcss-nested": "^6.0.1",
+ "postcss-selector-parser": "^6.0.11",
+ "resolve": "^1.22.2",
+ "sucrase": "^3.32.0"
+ },
+ "bin": {
+ "tailwind": "lib/cli.js",
+ "tailwindcss": "lib/cli.js"
+ },
+ "engines": {
+ "node": ">=14.0.0"
}
},
"node_modules/@chainlink/contracts": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/@chainlink/contracts/-/contracts-1.5.0.tgz",
"integrity": "sha512-1fGJwjvivqAxvVOTqZUEXGR54CATtg0vjcXgSIk4Cfoad2nUhSG/qaWHXjLg1CkNTeOoteoxGQcpP/HiA5HsUA==",
- "license": "BUSL-1.1",
"dependencies": {
"@arbitrum/nitro-contracts": "3.0.0",
"@changesets/cli": "^2.29.6",
@@ -1659,25 +2283,6 @@
"bn.js": "^5.2.1"
}
},
- "node_modules/@chainlink/contracts-1.4.0/node_modules/@ethersproject/bytes": {
- "version": "5.8.0",
- "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.8.0.tgz",
- "integrity": "sha512-vTkeohgJVCPVHu5c25XWaWQOZ4v+DkGoC42/TS2ond+PARCxTJvgTFUNDZovyQ/uAQ4EcpqqowKydcdmRKjg7A==",
- "funding": [
- {
- "type": "individual",
- "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
- },
- {
- "type": "individual",
- "url": "https://www.buymeacoffee.com/ricmoo"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "@ethersproject/logger": "^5.8.0"
- }
- },
"node_modules/@chainlink/contracts-1.4.0/node_modules/@ethersproject/constants": {
"version": "5.8.0",
"resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.8.0.tgz",
@@ -1837,22 +2442,6 @@
"js-sha3": "0.8.0"
}
},
- "node_modules/@chainlink/contracts-1.4.0/node_modules/@ethersproject/logger": {
- "version": "5.8.0",
- "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.8.0.tgz",
- "integrity": "sha512-Qe6knGmY+zPPWTC+wQrpitodgBfH7XoceCGL5bJVejmH+yCS3R8jJm8iiWuvWbG76RUmyEG53oqv6GMVWqunjA==",
- "funding": [
- {
- "type": "individual",
- "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
- },
- {
- "type": "individual",
- "url": "https://www.buymeacoffee.com/ricmoo"
- }
- ],
- "license": "MIT"
- },
"node_modules/@chainlink/contracts-1.4.0/node_modules/@ethersproject/networks": {
"version": "5.8.0",
"resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.8.0.tgz",
@@ -1872,46 +2461,6 @@
"@ethersproject/logger": "^5.8.0"
}
},
- "node_modules/@chainlink/contracts-1.4.0/node_modules/@ethersproject/pbkdf2": {
- "version": "5.8.0",
- "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.8.0.tgz",
- "integrity": "sha512-wuHiv97BrzCmfEaPbUFpMjlVg/IDkZThp9Ri88BpjRleg4iePJaj2SW8AIyE8cXn5V1tuAaMj6lzvsGJkGWskg==",
- "funding": [
- {
- "type": "individual",
- "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
- },
- {
- "type": "individual",
- "url": "https://www.buymeacoffee.com/ricmoo"
- }
- ],
- "license": "MIT",
- "peer": true,
- "dependencies": {
- "@ethersproject/bytes": "^5.8.0",
- "@ethersproject/sha2": "^5.8.0"
- }
- },
- "node_modules/@chainlink/contracts-1.4.0/node_modules/@ethersproject/properties": {
- "version": "5.8.0",
- "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.8.0.tgz",
- "integrity": "sha512-PYuiEoQ+FMaZZNGrStmN7+lWjlsoufGIHdww7454FIaGdbe/p5rnaCXTr5MtBYl3NkeoVhHZuyzChPeGeKIpQw==",
- "funding": [
- {
- "type": "individual",
- "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
- },
- {
- "type": "individual",
- "url": "https://www.buymeacoffee.com/ricmoo"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "@ethersproject/logger": "^5.8.0"
- }
- },
"node_modules/@chainlink/contracts-1.4.0/node_modules/@ethersproject/providers": {
"version": "5.8.0",
"resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.8.0.tgz",
@@ -1992,28 +2541,6 @@
"@ethersproject/logger": "^5.8.0"
}
},
- "node_modules/@chainlink/contracts-1.4.0/node_modules/@ethersproject/sha2": {
- "version": "5.8.0",
- "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.8.0.tgz",
- "integrity": "sha512-dDOUrXr9wF/YFltgTBYS0tKslPEKr6AekjqDW2dbn1L1xmjGR+9GiKu4ajxovnrDbwxAKdHjW8jNcwfz8PAz4A==",
- "funding": [
- {
- "type": "individual",
- "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
- },
- {
- "type": "individual",
- "url": "https://www.buymeacoffee.com/ricmoo"
- }
- ],
- "license": "MIT",
- "peer": true,
- "dependencies": {
- "@ethersproject/bytes": "^5.8.0",
- "@ethersproject/logger": "^5.8.0",
- "hash.js": "1.1.7"
- }
- },
"node_modules/@chainlink/contracts-1.4.0/node_modules/@ethersproject/signing-key": {
"version": "5.8.0",
"resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.8.0.tgz",
@@ -2587,25 +3114,6 @@
"bn.js": "^5.2.1"
}
},
- "node_modules/@chainlink/contracts-ccip/node_modules/@ethersproject/bytes": {
- "version": "5.8.0",
- "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.8.0.tgz",
- "integrity": "sha512-vTkeohgJVCPVHu5c25XWaWQOZ4v+DkGoC42/TS2ond+PARCxTJvgTFUNDZovyQ/uAQ4EcpqqowKydcdmRKjg7A==",
- "funding": [
- {
- "type": "individual",
- "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
- },
- {
- "type": "individual",
- "url": "https://www.buymeacoffee.com/ricmoo"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "@ethersproject/logger": "^5.8.0"
- }
- },
"node_modules/@chainlink/contracts-ccip/node_modules/@ethersproject/constants": {
"version": "5.8.0",
"resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.8.0.tgz",
@@ -2765,22 +3273,6 @@
"js-sha3": "0.8.0"
}
},
- "node_modules/@chainlink/contracts-ccip/node_modules/@ethersproject/logger": {
- "version": "5.8.0",
- "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.8.0.tgz",
- "integrity": "sha512-Qe6knGmY+zPPWTC+wQrpitodgBfH7XoceCGL5bJVejmH+yCS3R8jJm8iiWuvWbG76RUmyEG53oqv6GMVWqunjA==",
- "funding": [
- {
- "type": "individual",
- "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
- },
- {
- "type": "individual",
- "url": "https://www.buymeacoffee.com/ricmoo"
- }
- ],
- "license": "MIT"
- },
"node_modules/@chainlink/contracts-ccip/node_modules/@ethersproject/networks": {
"version": "5.8.0",
"resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.8.0.tgz",
@@ -2800,46 +3292,6 @@
"@ethersproject/logger": "^5.8.0"
}
},
- "node_modules/@chainlink/contracts-ccip/node_modules/@ethersproject/pbkdf2": {
- "version": "5.8.0",
- "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.8.0.tgz",
- "integrity": "sha512-wuHiv97BrzCmfEaPbUFpMjlVg/IDkZThp9Ri88BpjRleg4iePJaj2SW8AIyE8cXn5V1tuAaMj6lzvsGJkGWskg==",
- "funding": [
- {
- "type": "individual",
- "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
- },
- {
- "type": "individual",
- "url": "https://www.buymeacoffee.com/ricmoo"
- }
- ],
- "license": "MIT",
- "peer": true,
- "dependencies": {
- "@ethersproject/bytes": "^5.8.0",
- "@ethersproject/sha2": "^5.8.0"
- }
- },
- "node_modules/@chainlink/contracts-ccip/node_modules/@ethersproject/properties": {
- "version": "5.8.0",
- "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.8.0.tgz",
- "integrity": "sha512-PYuiEoQ+FMaZZNGrStmN7+lWjlsoufGIHdww7454FIaGdbe/p5rnaCXTr5MtBYl3NkeoVhHZuyzChPeGeKIpQw==",
- "funding": [
- {
- "type": "individual",
- "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
- },
- {
- "type": "individual",
- "url": "https://www.buymeacoffee.com/ricmoo"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "@ethersproject/logger": "^5.8.0"
- }
- },
"node_modules/@chainlink/contracts-ccip/node_modules/@ethersproject/providers": {
"version": "5.8.0",
"resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.8.0.tgz",
@@ -2920,28 +3372,6 @@
"@ethersproject/logger": "^5.8.0"
}
},
- "node_modules/@chainlink/contracts-ccip/node_modules/@ethersproject/sha2": {
- "version": "5.8.0",
- "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.8.0.tgz",
- "integrity": "sha512-dDOUrXr9wF/YFltgTBYS0tKslPEKr6AekjqDW2dbn1L1xmjGR+9GiKu4ajxovnrDbwxAKdHjW8jNcwfz8PAz4A==",
- "funding": [
- {
- "type": "individual",
- "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
- },
- {
- "type": "individual",
- "url": "https://www.buymeacoffee.com/ricmoo"
- }
- ],
- "license": "MIT",
- "peer": true,
- "dependencies": {
- "@ethersproject/bytes": "^5.8.0",
- "@ethersproject/logger": "^5.8.0",
- "hash.js": "1.1.7"
- }
- },
"node_modules/@chainlink/contracts-ccip/node_modules/@ethersproject/signing-key": {
"version": "5.8.0",
"resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.8.0.tgz",
@@ -3235,7 +3665,6 @@
"version": "7.7.3",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
"integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
- "license": "ISC",
"bin": {
"semver": "bin/semver.js"
},
@@ -3399,8 +3828,8 @@
},
"node_modules/@chainlink/contracts/node_modules/@ethersproject/basex": {
"version": "5.8.0",
- "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.8.0.tgz",
- "integrity": "sha512-PIgTszMlDRmNwW9nhS6iqtVfdTAKosA7llYXNmGPw4YAI1PUyMv28988wAb41/gHF/WqGdoLv0erHaRcHRKW2Q==",
+ "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.8.0.tgz",
+ "integrity": "sha512-PYuiEoQ+FMaZZNGrStmN7+lWjlsoufGIHdww7454FIaGdbe/p5rnaCXTr5MtBYl3NkeoVhHZuyzChPeGeKIpQw==",
"funding": [
{
"type": "individual",
@@ -3414,8 +3843,7 @@
"license": "MIT",
"peer": true,
"dependencies": {
- "@ethersproject/bytes": "^5.8.0",
- "@ethersproject/properties": "^5.8.0"
+ "@ethersproject/logger": "^5.8.0"
}
},
"node_modules/@chainlink/contracts/node_modules/@ethersproject/bignumber": {
@@ -3439,25 +3867,6 @@
"bn.js": "^5.2.1"
}
},
- "node_modules/@chainlink/contracts/node_modules/@ethersproject/bytes": {
- "version": "5.8.0",
- "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.8.0.tgz",
- "integrity": "sha512-vTkeohgJVCPVHu5c25XWaWQOZ4v+DkGoC42/TS2ond+PARCxTJvgTFUNDZovyQ/uAQ4EcpqqowKydcdmRKjg7A==",
- "funding": [
- {
- "type": "individual",
- "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
- },
- {
- "type": "individual",
- "url": "https://www.buymeacoffee.com/ricmoo"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "@ethersproject/logger": "^5.8.0"
- }
- },
"node_modules/@chainlink/contracts/node_modules/@ethersproject/constants": {
"version": "5.8.0",
"resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.8.0.tgz",
@@ -3617,22 +4026,6 @@
"js-sha3": "0.8.0"
}
},
- "node_modules/@chainlink/contracts/node_modules/@ethersproject/logger": {
- "version": "5.8.0",
- "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.8.0.tgz",
- "integrity": "sha512-Qe6knGmY+zPPWTC+wQrpitodgBfH7XoceCGL5bJVejmH+yCS3R8jJm8iiWuvWbG76RUmyEG53oqv6GMVWqunjA==",
- "funding": [
- {
- "type": "individual",
- "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
- },
- {
- "type": "individual",
- "url": "https://www.buymeacoffee.com/ricmoo"
- }
- ],
- "license": "MIT"
- },
"node_modules/@chainlink/contracts/node_modules/@ethersproject/networks": {
"version": "5.8.0",
"resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.8.0.tgz",
@@ -3652,46 +4045,6 @@
"@ethersproject/logger": "^5.8.0"
}
},
- "node_modules/@chainlink/contracts/node_modules/@ethersproject/pbkdf2": {
- "version": "5.8.0",
- "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.8.0.tgz",
- "integrity": "sha512-wuHiv97BrzCmfEaPbUFpMjlVg/IDkZThp9Ri88BpjRleg4iePJaj2SW8AIyE8cXn5V1tuAaMj6lzvsGJkGWskg==",
- "funding": [
- {
- "type": "individual",
- "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
- },
- {
- "type": "individual",
- "url": "https://www.buymeacoffee.com/ricmoo"
- }
- ],
- "license": "MIT",
- "peer": true,
- "dependencies": {
- "@ethersproject/bytes": "^5.8.0",
- "@ethersproject/sha2": "^5.8.0"
- }
- },
- "node_modules/@chainlink/contracts/node_modules/@ethersproject/properties": {
- "version": "5.8.0",
- "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.8.0.tgz",
- "integrity": "sha512-PYuiEoQ+FMaZZNGrStmN7+lWjlsoufGIHdww7454FIaGdbe/p5rnaCXTr5MtBYl3NkeoVhHZuyzChPeGeKIpQw==",
- "funding": [
- {
- "type": "individual",
- "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
- },
- {
- "type": "individual",
- "url": "https://www.buymeacoffee.com/ricmoo"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "@ethersproject/logger": "^5.8.0"
- }
- },
"node_modules/@chainlink/contracts/node_modules/@ethersproject/providers": {
"version": "5.8.0",
"resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.8.0.tgz",
@@ -3772,28 +4125,6 @@
"@ethersproject/logger": "^5.8.0"
}
},
- "node_modules/@chainlink/contracts/node_modules/@ethersproject/sha2": {
- "version": "5.8.0",
- "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.8.0.tgz",
- "integrity": "sha512-dDOUrXr9wF/YFltgTBYS0tKslPEKr6AekjqDW2dbn1L1xmjGR+9GiKu4ajxovnrDbwxAKdHjW8jNcwfz8PAz4A==",
- "funding": [
- {
- "type": "individual",
- "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
- },
- {
- "type": "individual",
- "url": "https://www.buymeacoffee.com/ricmoo"
- }
- ],
- "license": "MIT",
- "peer": true,
- "dependencies": {
- "@ethersproject/bytes": "^5.8.0",
- "@ethersproject/logger": "^5.8.0",
- "hash.js": "1.1.7"
- }
- },
"node_modules/@chainlink/contracts/node_modules/@ethersproject/signing-key": {
"version": "5.8.0",
"resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.8.0.tgz",
@@ -4116,6 +4447,60 @@
"tailwindcss-animate": "1.0.7"
}
},
+ "node_modules/@chainlink/design-system/node_modules/jiti": {
+ "version": "1.21.7",
+ "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz",
+ "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==",
+ "bin": {
+ "jiti": "bin/jiti.js"
+ }
+ },
+ "node_modules/@chainlink/design-system/node_modules/lilconfig": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz",
+ "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@chainlink/design-system/node_modules/tailwindcss": {
+ "version": "3.4.4",
+ "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.4.tgz",
+ "integrity": "sha512-ZoyXOdJjISB7/BcLTR6SEsLgKtDStYyYZVLsUtWChO4Ps20CBad7lfJKVDiejocV4ME1hLmyY0WJE3hSDcmQ2A==",
+ "license": "MIT",
+ "dependencies": {
+ "@alloc/quick-lru": "^5.2.0",
+ "arg": "^5.0.2",
+ "chokidar": "^3.5.3",
+ "didyoumean": "^1.2.2",
+ "dlv": "^1.1.3",
+ "fast-glob": "^3.3.0",
+ "glob-parent": "^6.0.2",
+ "is-glob": "^4.0.3",
+ "jiti": "^1.21.0",
+ "lilconfig": "^2.1.0",
+ "micromatch": "^4.0.5",
+ "normalize-path": "^3.0.0",
+ "object-hash": "^3.0.0",
+ "picocolors": "^1.0.0",
+ "postcss": "^8.4.23",
+ "postcss-import": "^15.1.0",
+ "postcss-js": "^4.0.1",
+ "postcss-load-config": "^4.0.1",
+ "postcss-nested": "^6.0.1",
+ "postcss-selector-parser": "^6.0.11",
+ "resolve": "^1.22.2",
+ "sucrase": "^3.32.0"
+ },
+ "bin": {
+ "tailwind": "lib/cli.js",
+ "tailwindcss": "lib/cli.js"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
"node_modules/@chainlink/local": {
"version": "0.2.7-beta",
"resolved": "https://registry.npmjs.org/@chainlink/local/-/local-0.2.7-beta.tgz",
@@ -5639,9 +6024,9 @@
}
},
"node_modules/@ethersproject/bytes": {
- "version": "5.7.0",
- "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.7.0.tgz",
- "integrity": "sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==",
+ "version": "5.8.0",
+ "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.8.0.tgz",
+ "integrity": "sha512-vTkeohgJVCPVHu5c25XWaWQOZ4v+DkGoC42/TS2ond+PARCxTJvgTFUNDZovyQ/uAQ4EcpqqowKydcdmRKjg7A==",
"funding": [
{
"type": "individual",
@@ -5652,9 +6037,8 @@
"url": "https://www.buymeacoffee.com/ricmoo"
}
],
- "license": "MIT",
"dependencies": {
- "@ethersproject/logger": "^5.7.0"
+ "@ethersproject/logger": "^5.8.0"
}
},
"node_modules/@ethersproject/constants": {
@@ -5731,73 +6115,6 @@
"@ethersproject/strings": "^5.7.0"
}
},
- "node_modules/@ethersproject/hdnode": {
- "version": "5.7.0",
- "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.7.0.tgz",
- "integrity": "sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg==",
- "funding": [
- {
- "type": "individual",
- "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
- },
- {
- "type": "individual",
- "url": "https://www.buymeacoffee.com/ricmoo"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "@ethersproject/abstract-signer": "^5.7.0",
- "@ethersproject/basex": "^5.7.0",
- "@ethersproject/bignumber": "^5.7.0",
- "@ethersproject/bytes": "^5.7.0",
- "@ethersproject/logger": "^5.7.0",
- "@ethersproject/pbkdf2": "^5.7.0",
- "@ethersproject/properties": "^5.7.0",
- "@ethersproject/sha2": "^5.7.0",
- "@ethersproject/signing-key": "^5.7.0",
- "@ethersproject/strings": "^5.7.0",
- "@ethersproject/transactions": "^5.7.0",
- "@ethersproject/wordlists": "^5.7.0"
- }
- },
- "node_modules/@ethersproject/json-wallets": {
- "version": "5.7.0",
- "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.7.0.tgz",
- "integrity": "sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g==",
- "funding": [
- {
- "type": "individual",
- "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
- },
- {
- "type": "individual",
- "url": "https://www.buymeacoffee.com/ricmoo"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "@ethersproject/abstract-signer": "^5.7.0",
- "@ethersproject/address": "^5.7.0",
- "@ethersproject/bytes": "^5.7.0",
- "@ethersproject/hdnode": "^5.7.0",
- "@ethersproject/keccak256": "^5.7.0",
- "@ethersproject/logger": "^5.7.0",
- "@ethersproject/pbkdf2": "^5.7.0",
- "@ethersproject/properties": "^5.7.0",
- "@ethersproject/random": "^5.7.0",
- "@ethersproject/strings": "^5.7.0",
- "@ethersproject/transactions": "^5.7.0",
- "aes-js": "3.0.0",
- "scrypt-js": "3.0.1"
- }
- },
- "node_modules/@ethersproject/json-wallets/node_modules/aes-js": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz",
- "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==",
- "license": "MIT"
- },
"node_modules/@ethersproject/keccak256": {
"version": "5.7.0",
"resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.7.0.tgz",
@@ -5819,9 +6136,9 @@
}
},
"node_modules/@ethersproject/logger": {
- "version": "5.7.0",
- "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.7.0.tgz",
- "integrity": "sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==",
+ "version": "5.8.0",
+ "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.8.0.tgz",
+ "integrity": "sha512-Qe6knGmY+zPPWTC+wQrpitodgBfH7XoceCGL5bJVejmH+yCS3R8jJm8iiWuvWbG76RUmyEG53oqv6GMVWqunjA==",
"funding": [
{
"type": "individual",
@@ -5831,8 +6148,7 @@
"type": "individual",
"url": "https://www.buymeacoffee.com/ricmoo"
}
- ],
- "license": "MIT"
+ ]
},
"node_modules/@ethersproject/networks": {
"version": "5.7.1",
@@ -5854,9 +6170,9 @@
}
},
"node_modules/@ethersproject/pbkdf2": {
- "version": "5.7.0",
- "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.7.0.tgz",
- "integrity": "sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw==",
+ "version": "5.8.0",
+ "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.8.0.tgz",
+ "integrity": "sha512-wuHiv97BrzCmfEaPbUFpMjlVg/IDkZThp9Ri88BpjRleg4iePJaj2SW8AIyE8cXn5V1tuAaMj6lzvsGJkGWskg==",
"funding": [
{
"type": "individual",
@@ -5867,16 +6183,16 @@
"url": "https://www.buymeacoffee.com/ricmoo"
}
],
- "license": "MIT",
+ "peer": true,
"dependencies": {
- "@ethersproject/bytes": "^5.7.0",
- "@ethersproject/sha2": "^5.7.0"
+ "@ethersproject/bytes": "^5.8.0",
+ "@ethersproject/sha2": "^5.8.0"
}
},
"node_modules/@ethersproject/properties": {
- "version": "5.7.0",
- "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.7.0.tgz",
- "integrity": "sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==",
+ "version": "5.8.0",
+ "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.8.0.tgz",
+ "integrity": "sha512-PYuiEoQ+FMaZZNGrStmN7+lWjlsoufGIHdww7454FIaGdbe/p5rnaCXTr5MtBYl3NkeoVhHZuyzChPeGeKIpQw==",
"funding": [
{
"type": "individual",
@@ -5887,9 +6203,8 @@
"url": "https://www.buymeacoffee.com/ricmoo"
}
],
- "license": "MIT",
"dependencies": {
- "@ethersproject/logger": "^5.7.0"
+ "@ethersproject/logger": "^5.8.0"
}
},
"node_modules/@ethersproject/providers": {
@@ -5992,9 +6307,9 @@
}
},
"node_modules/@ethersproject/sha2": {
- "version": "5.7.0",
- "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.7.0.tgz",
- "integrity": "sha512-gKlH42riwb3KYp0reLsFTokByAKoJdgFCwI+CCiX/k+Jm2mbNs6oOaCjYQSlI1+XBVejwH2KrmCbMAT/GnRDQw==",
+ "version": "5.8.0",
+ "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.8.0.tgz",
+ "integrity": "sha512-dDOUrXr9wF/YFltgTBYS0tKslPEKr6AekjqDW2dbn1L1xmjGR+9GiKu4ajxovnrDbwxAKdHjW8jNcwfz8PAz4A==",
"funding": [
{
"type": "individual",
@@ -6005,10 +6320,9 @@
"url": "https://www.buymeacoffee.com/ricmoo"
}
],
- "license": "MIT",
"dependencies": {
- "@ethersproject/bytes": "^5.7.0",
- "@ethersproject/logger": "^5.7.0",
+ "@ethersproject/bytes": "^5.8.0",
+ "@ethersproject/logger": "^5.8.0",
"hash.js": "1.1.7"
}
},
@@ -6036,30 +6350,6 @@
"hash.js": "1.1.7"
}
},
- "node_modules/@ethersproject/solidity": {
- "version": "5.7.0",
- "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.7.0.tgz",
- "integrity": "sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA==",
- "funding": [
- {
- "type": "individual",
- "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
- },
- {
- "type": "individual",
- "url": "https://www.buymeacoffee.com/ricmoo"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "@ethersproject/bignumber": "^5.7.0",
- "@ethersproject/bytes": "^5.7.0",
- "@ethersproject/keccak256": "^5.7.0",
- "@ethersproject/logger": "^5.7.0",
- "@ethersproject/sha2": "^5.7.0",
- "@ethersproject/strings": "^5.7.0"
- }
- },
"node_modules/@ethersproject/strings": {
"version": "5.7.0",
"resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.7.0.tgz",
@@ -6108,60 +6398,6 @@
"@ethersproject/signing-key": "^5.7.0"
}
},
- "node_modules/@ethersproject/units": {
- "version": "5.7.0",
- "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.7.0.tgz",
- "integrity": "sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg==",
- "funding": [
- {
- "type": "individual",
- "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
- },
- {
- "type": "individual",
- "url": "https://www.buymeacoffee.com/ricmoo"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "@ethersproject/bignumber": "^5.7.0",
- "@ethersproject/constants": "^5.7.0",
- "@ethersproject/logger": "^5.7.0"
- }
- },
- "node_modules/@ethersproject/wallet": {
- "version": "5.7.0",
- "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.7.0.tgz",
- "integrity": "sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA==",
- "funding": [
- {
- "type": "individual",
- "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
- },
- {
- "type": "individual",
- "url": "https://www.buymeacoffee.com/ricmoo"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "@ethersproject/abstract-provider": "^5.7.0",
- "@ethersproject/abstract-signer": "^5.7.0",
- "@ethersproject/address": "^5.7.0",
- "@ethersproject/bignumber": "^5.7.0",
- "@ethersproject/bytes": "^5.7.0",
- "@ethersproject/hash": "^5.7.0",
- "@ethersproject/hdnode": "^5.7.0",
- "@ethersproject/json-wallets": "^5.7.0",
- "@ethersproject/keccak256": "^5.7.0",
- "@ethersproject/logger": "^5.7.0",
- "@ethersproject/properties": "^5.7.0",
- "@ethersproject/random": "^5.7.0",
- "@ethersproject/signing-key": "^5.7.0",
- "@ethersproject/transactions": "^5.7.0",
- "@ethersproject/wordlists": "^5.7.0"
- }
- },
"node_modules/@ethersproject/web": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.7.1.tgz",
@@ -6185,29 +6421,6 @@
"@ethersproject/strings": "^5.7.0"
}
},
- "node_modules/@ethersproject/wordlists": {
- "version": "5.7.0",
- "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.7.0.tgz",
- "integrity": "sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA==",
- "funding": [
- {
- "type": "individual",
- "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2"
- },
- {
- "type": "individual",
- "url": "https://www.buymeacoffee.com/ricmoo"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "@ethersproject/bytes": "^5.7.0",
- "@ethersproject/hash": "^5.7.0",
- "@ethersproject/logger": "^5.7.0",
- "@ethersproject/properties": "^5.7.0",
- "@ethersproject/strings": "^5.7.0"
- }
- },
"node_modules/@floating-ui/core": {
"version": "1.7.3",
"resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.3.tgz",
@@ -6261,6 +6474,24 @@
"integrity": "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==",
"license": "MIT"
},
+ "node_modules/@graphql-typed-document-node/core": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/@graphql-typed-document-node/core/-/core-3.2.0.tgz",
+ "integrity": "sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ==",
+ "license": "MIT",
+ "peerDependencies": {
+ "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0"
+ }
+ },
+ "node_modules/@hookform/resolvers": {
+ "version": "3.9.1",
+ "resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-3.9.1.tgz",
+ "integrity": "sha512-ud2HqmGBM0P0IABqoskKWI6PEf6ZDDBZkFqe2Vnl+mTHCEHzr3ISjjZyCwTjC/qpL25JC9aIDkloQejvMeq0ug==",
+ "license": "MIT",
+ "peerDependencies": {
+ "react-hook-form": "^7.0.0"
+ }
+ },
"node_modules/@humanwhocodes/config-array": {
"version": "0.13.0",
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz",
@@ -9233,6 +9464,18 @@
"vite": ">=2.0.0"
}
},
+ "node_modules/@prettier/sync": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/@prettier/sync/-/sync-0.3.0.tgz",
+ "integrity": "sha512-3dcmCyAxIcxy036h1I7MQU/uEEBq8oLwf1CE3xeze+MPlgkdlb/+w6rGR/1dhp6Hqi17fRS6nvwnOzkESxEkOw==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/prettier/prettier-synchronized?sponsor=1"
+ },
+ "peerDependencies": {
+ "prettier": "^3.0.0"
+ }
+ },
"node_modules/@project-serum/anchor": {
"version": "0.26.0",
"resolved": "https://registry.npmjs.org/@project-serum/anchor/-/anchor-0.26.0.tgz",
@@ -9311,6 +9554,12 @@
"node": ">=18.0.0"
}
},
+ "node_modules/@radix-ui/number": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.0.tgz",
+ "integrity": "sha512-V3gRzhVNU1ldS5XhAPTom1fOIo4ccrjjJgmE+LI2h/WaFpHmx0MQApT+KZHnx8abG6Avtfcz4WoEciMnpFT3HQ==",
+ "license": "MIT"
+ },
"node_modules/@radix-ui/primitive": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.0.1.tgz",
@@ -9320,20 +9569,27 @@
"@babel/runtime": "^7.13.10"
}
},
- "node_modules/@radix-ui/react-arrow": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.0.3.tgz",
- "integrity": "sha512-wSP+pHsB/jQRaL6voubsQ/ZlrGBHHrOjmBnr19hxYgtS0WvAFwZhK2WP/YY5yF9uKECCEEDGxuLxq1NBK51wFA==",
+ "node_modules/@radix-ui/react-accordion": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-accordion/-/react-accordion-1.2.1.tgz",
+ "integrity": "sha512-bg/l7l5QzUjgsh8kjwDFommzAshnUsuVMV5NM56QVCm+7ZckYdd9P/ExR8xG/Oup0OajVxNLaHJ1tb8mXk+nzQ==",
"license": "MIT",
"dependencies": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/react-primitive": "1.0.3"
+ "@radix-ui/primitive": "1.1.0",
+ "@radix-ui/react-collapsible": "1.1.1",
+ "@radix-ui/react-collection": "1.1.0",
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-context": "1.1.1",
+ "@radix-ui/react-direction": "1.1.0",
+ "@radix-ui/react-id": "1.1.0",
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-use-controllable-state": "1.1.0"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0",
- "react-dom": "^16.8 || ^17.0 || ^18.0"
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
@@ -9344,23 +9600,28 @@
}
}
},
- "node_modules/@radix-ui/react-collection": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.0.3.tgz",
- "integrity": "sha512-3SzW+0PW7yBBoQlT8wNcGtaxaD0XSu0uLUFgrtHY08Acx05TaHaOmVLR73c0j/cqpDy53KBMO7s0dx2wmOIDIA==",
+ "node_modules/@radix-ui/react-accordion/node_modules/@radix-ui/primitive": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.0.tgz",
+ "integrity": "sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==",
+ "license": "MIT"
+ },
+ "node_modules/@radix-ui/react-accordion/node_modules/@radix-ui/react-collection": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.0.tgz",
+ "integrity": "sha512-GZsZslMJEyo1VKm5L1ZJY8tGDxZNPAoUeQUIbKeJfoi7Q4kmig5AsgLMYYuyYbfjd8fBmFORAIwYAkXMnXZgZw==",
"license": "MIT",
"dependencies": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/react-compose-refs": "1.0.1",
- "@radix-ui/react-context": "1.0.1",
- "@radix-ui/react-primitive": "1.0.3",
- "@radix-ui/react-slot": "1.0.2"
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-context": "1.1.0",
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-slot": "1.1.0"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0",
- "react-dom": "^16.8 || ^17.0 || ^18.0"
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
@@ -9371,17 +9632,44 @@
}
}
},
- "node_modules/@radix-ui/react-compose-refs": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.0.1.tgz",
- "integrity": "sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw==",
+ "node_modules/@radix-ui/react-accordion/node_modules/@radix-ui/react-collection/node_modules/@radix-ui/react-context": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.0.tgz",
+ "integrity": "sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==",
"license": "MIT",
- "dependencies": {
- "@babel/runtime": "^7.13.10"
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-accordion/node_modules/@radix-ui/react-compose-refs": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.0.tgz",
+ "integrity": "sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-accordion/node_modules/@radix-ui/react-context": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.1.tgz",
+ "integrity": "sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==",
+ "license": "MIT",
"peerDependencies": {
"@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0"
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
@@ -9389,17 +9677,32 @@
}
}
},
- "node_modules/@radix-ui/react-context": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.0.1.tgz",
- "integrity": "sha512-ebbrdFoYTcuZ0v4wG5tedGnp9tzcV8awzsxYph7gXUyvnNLuTIcCk1q17JEbnVhXAKG9oX3KtchwiMIAYp9NLg==",
+ "node_modules/@radix-ui/react-accordion/node_modules/@radix-ui/react-direction": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.0.tgz",
+ "integrity": "sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-accordion/node_modules/@radix-ui/react-id": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.0.tgz",
+ "integrity": "sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==",
"license": "MIT",
"dependencies": {
- "@babel/runtime": "^7.13.10"
+ "@radix-ui/react-use-layout-effect": "1.1.0"
},
"peerDependencies": {
"@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0"
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
@@ -9407,33 +9710,19 @@
}
}
},
- "node_modules/@radix-ui/react-dialog": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.0.5.tgz",
- "integrity": "sha512-GjWJX/AUpB703eEBanuBnIWdIXg6NvJFCXcNlSZk4xdszCdhrJgBoUd1cGk67vFO+WdA2pfI/plOpqz/5GUP6Q==",
+ "node_modules/@radix-ui/react-accordion/node_modules/@radix-ui/react-primitive": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.0.tgz",
+ "integrity": "sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw==",
"license": "MIT",
"dependencies": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/primitive": "1.0.1",
- "@radix-ui/react-compose-refs": "1.0.1",
- "@radix-ui/react-context": "1.0.1",
- "@radix-ui/react-dismissable-layer": "1.0.5",
- "@radix-ui/react-focus-guards": "1.0.1",
- "@radix-ui/react-focus-scope": "1.0.4",
- "@radix-ui/react-id": "1.0.1",
- "@radix-ui/react-portal": "1.0.4",
- "@radix-ui/react-presence": "1.0.1",
- "@radix-ui/react-primitive": "1.0.3",
- "@radix-ui/react-slot": "1.0.2",
- "@radix-ui/react-use-controllable-state": "1.0.1",
- "aria-hidden": "^1.1.1",
- "react-remove-scroll": "2.5.5"
+ "@radix-ui/react-slot": "1.1.0"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0",
- "react-dom": "^16.8 || ^17.0 || ^18.0"
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
@@ -9444,24 +9733,32 @@
}
}
},
- "node_modules/@radix-ui/react-dialog/node_modules/react-remove-scroll": {
- "version": "2.5.5",
- "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.5.tgz",
- "integrity": "sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw==",
+ "node_modules/@radix-ui/react-accordion/node_modules/@radix-ui/react-slot": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.0.tgz",
+ "integrity": "sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==",
"license": "MIT",
"dependencies": {
- "react-remove-scroll-bar": "^2.3.3",
- "react-style-singleton": "^2.2.1",
- "tslib": "^2.1.0",
- "use-callback-ref": "^1.3.0",
- "use-sidecar": "^1.1.2"
+ "@radix-ui/react-compose-refs": "1.1.0"
},
- "engines": {
- "node": ">=10"
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-accordion/node_modules/@radix-ui/react-use-callback-ref": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz",
+ "integrity": "sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==",
+ "license": "MIT",
"peerDependencies": {
- "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0",
- "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
@@ -9469,17 +9766,17 @@
}
}
},
- "node_modules/@radix-ui/react-direction": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.0.1.tgz",
- "integrity": "sha512-RXcvnXgyvYvBEOhCBuddKecVkoMiI10Jcm5cTI7abJRAHYfFxeu+FBQs/DvdxSYucxR5mna0dNsL6QFlds5TMA==",
+ "node_modules/@radix-ui/react-accordion/node_modules/@radix-ui/react-use-controllable-state": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.1.0.tgz",
+ "integrity": "sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==",
"license": "MIT",
"dependencies": {
- "@babel/runtime": "^7.13.10"
+ "@radix-ui/react-use-callback-ref": "1.1.0"
},
"peerDependencies": {
"@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0"
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
@@ -9487,18 +9784,29 @@
}
}
},
- "node_modules/@radix-ui/react-dismissable-layer": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.0.5.tgz",
- "integrity": "sha512-aJeDjQhywg9LBu2t/At58hCvr7pEm0o2Ke1x33B+MhjNmmZ17sy4KImo0KPLgsnc/zN7GPdce8Cnn0SWvwZO7g==",
+ "node_modules/@radix-ui/react-accordion/node_modules/@radix-ui/react-use-layout-effect": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz",
+ "integrity": "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-arrow": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.0.3.tgz",
+ "integrity": "sha512-wSP+pHsB/jQRaL6voubsQ/ZlrGBHHrOjmBnr19hxYgtS0WvAFwZhK2WP/YY5yF9uKECCEEDGxuLxq1NBK51wFA==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.13.10",
- "@radix-ui/primitive": "1.0.1",
- "@radix-ui/react-compose-refs": "1.0.1",
- "@radix-ui/react-primitive": "1.0.3",
- "@radix-ui/react-use-callback-ref": "1.0.1",
- "@radix-ui/react-use-escape-keydown": "1.0.3"
+ "@radix-ui/react-primitive": "1.0.3"
},
"peerDependencies": {
"@types/react": "*",
@@ -9515,26 +9823,26 @@
}
}
},
- "node_modules/@radix-ui/react-dropdown-menu": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.0.6.tgz",
- "integrity": "sha512-i6TuFOoWmLWq+M/eCLGd/bQ2HfAX1RJgvrBQ6AQLmzfvsLdefxbWu8G9zczcPFfcSPehz9GcpF6K9QYreFV8hA==",
+ "node_modules/@radix-ui/react-checkbox": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-checkbox/-/react-checkbox-1.1.2.tgz",
+ "integrity": "sha512-/i0fl686zaJbDQLNKrkCbMyDm6FQMt4jg323k7HuqitoANm9sE23Ql8yOK3Wusk34HSLKDChhMux05FnP6KUkw==",
"license": "MIT",
"dependencies": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/primitive": "1.0.1",
- "@radix-ui/react-compose-refs": "1.0.1",
- "@radix-ui/react-context": "1.0.1",
- "@radix-ui/react-id": "1.0.1",
- "@radix-ui/react-menu": "2.0.6",
- "@radix-ui/react-primitive": "1.0.3",
- "@radix-ui/react-use-controllable-state": "1.0.1"
+ "@radix-ui/primitive": "1.1.0",
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-context": "1.1.1",
+ "@radix-ui/react-presence": "1.1.1",
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-use-controllable-state": "1.1.0",
+ "@radix-ui/react-use-previous": "1.1.0",
+ "@radix-ui/react-use-size": "1.1.0"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0",
- "react-dom": "^16.8 || ^17.0 || ^18.0"
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
@@ -9545,40 +9853,79 @@
}
}
},
- "node_modules/@radix-ui/react-focus-guards": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.0.1.tgz",
- "integrity": "sha512-Rect2dWbQ8waGzhMavsIbmSVCgYxkXLxxR3ZvCX79JOglzdEy4JXMb98lq4hPxUbLr77nP0UOGf4rcMU+s1pUA==",
+ "node_modules/@radix-ui/react-checkbox/node_modules/@radix-ui/primitive": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.0.tgz",
+ "integrity": "sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==",
+ "license": "MIT"
+ },
+ "node_modules/@radix-ui/react-checkbox/node_modules/@radix-ui/react-compose-refs": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.0.tgz",
+ "integrity": "sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-checkbox/node_modules/@radix-ui/react-context": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.1.tgz",
+ "integrity": "sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-checkbox/node_modules/@radix-ui/react-presence": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.1.tgz",
+ "integrity": "sha512-IeFXVi4YS1K0wVZzXNrbaaUvIJ3qdY+/Ih4eHFhWA9SwGR9UDX7Ck8abvL57C4cv3wwMvUE0OG69Qc3NCcTe/A==",
"license": "MIT",
"dependencies": {
- "@babel/runtime": "^7.13.10"
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-use-layout-effect": "1.1.0"
},
"peerDependencies": {
"@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0"
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
}
}
},
- "node_modules/@radix-ui/react-focus-scope": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.0.4.tgz",
- "integrity": "sha512-sL04Mgvf+FmyvZeYfNu1EPAaaxD+aw7cYeIB9L9Fvq8+urhltTRaEo5ysKOpHuKPclsZcSUMKlN05x4u+CINpA==",
+ "node_modules/@radix-ui/react-checkbox/node_modules/@radix-ui/react-primitive": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.0.tgz",
+ "integrity": "sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw==",
"license": "MIT",
"dependencies": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/react-compose-refs": "1.0.1",
- "@radix-ui/react-primitive": "1.0.3",
- "@radix-ui/react-use-callback-ref": "1.0.1"
+ "@radix-ui/react-slot": "1.1.0"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0",
- "react-dom": "^16.8 || ^17.0 || ^18.0"
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
@@ -9589,18 +9936,17 @@
}
}
},
- "node_modules/@radix-ui/react-id": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.0.1.tgz",
- "integrity": "sha512-tI7sT/kqYp8p96yGWY1OAnLHrqDgzHefRBKQ2YAkBS5ja7QLcZ9Z/uY7bEjPUatf8RomoXM8/1sMj1IJaE5UzQ==",
+ "node_modules/@radix-ui/react-checkbox/node_modules/@radix-ui/react-slot": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.0.tgz",
+ "integrity": "sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==",
"license": "MIT",
"dependencies": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/react-use-layout-effect": "1.0.1"
+ "@radix-ui/react-compose-refs": "1.1.0"
},
"peerDependencies": {
"@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0"
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
@@ -9608,37 +9954,107 @@
}
}
},
- "node_modules/@radix-ui/react-menu": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.0.6.tgz",
- "integrity": "sha512-BVkFLS+bUC8HcImkRKPSiVumA1VPOOEC5WBMiT+QAVsPzW1FJzI9KnqgGxVDPBcql5xXrHkD3JOVoXWEXD8SYA==",
+ "node_modules/@radix-ui/react-checkbox/node_modules/@radix-ui/react-use-callback-ref": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz",
+ "integrity": "sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-checkbox/node_modules/@radix-ui/react-use-controllable-state": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.1.0.tgz",
+ "integrity": "sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==",
"license": "MIT",
"dependencies": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/primitive": "1.0.1",
- "@radix-ui/react-collection": "1.0.3",
- "@radix-ui/react-compose-refs": "1.0.1",
- "@radix-ui/react-context": "1.0.1",
- "@radix-ui/react-direction": "1.0.1",
- "@radix-ui/react-dismissable-layer": "1.0.5",
- "@radix-ui/react-focus-guards": "1.0.1",
- "@radix-ui/react-focus-scope": "1.0.4",
- "@radix-ui/react-id": "1.0.1",
- "@radix-ui/react-popper": "1.1.3",
- "@radix-ui/react-portal": "1.0.4",
- "@radix-ui/react-presence": "1.0.1",
- "@radix-ui/react-primitive": "1.0.3",
- "@radix-ui/react-roving-focus": "1.0.4",
- "@radix-ui/react-slot": "1.0.2",
- "@radix-ui/react-use-callback-ref": "1.0.1",
- "aria-hidden": "^1.1.1",
- "react-remove-scroll": "2.5.5"
+ "@radix-ui/react-use-callback-ref": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-checkbox/node_modules/@radix-ui/react-use-layout-effect": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz",
+ "integrity": "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-checkbox/node_modules/@radix-ui/react-use-previous": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.0.tgz",
+ "integrity": "sha512-Z/e78qg2YFnnXcW88A4JmTtm4ADckLno6F7OXotmkQfeuCVaKuYzqAATPhVzl3delXE7CxIV8shofPn3jPc5Og==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-checkbox/node_modules/@radix-ui/react-use-size": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.0.tgz",
+ "integrity": "sha512-XW3/vWuIXHa+2Uwcc2ABSfcCledmXhhQPlGbfcRXbiUQI5Icjcg19BGCZVKKInYbvUCut/ufbbLLPFC5cbb1hw==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-use-layout-effect": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-collapsible": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.1.1.tgz",
+ "integrity": "sha512-1///SnrfQHJEofLokyczERxQbWfCGQlQ2XsCZMucVs6it+lq9iw4vXy+uDn1edlb58cOZOWSldnfPAYcT4O/Yg==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.1.0",
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-context": "1.1.1",
+ "@radix-ui/react-id": "1.1.0",
+ "@radix-ui/react-presence": "1.1.1",
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-use-controllable-state": "1.1.0",
+ "@radix-ui/react-use-layout-effect": "1.1.0"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0",
- "react-dom": "^16.8 || ^17.0 || ^18.0"
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
@@ -9649,24 +10065,53 @@
}
}
},
- "node_modules/@radix-ui/react-menu/node_modules/react-remove-scroll": {
- "version": "2.5.5",
- "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.5.tgz",
- "integrity": "sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw==",
+ "node_modules/@radix-ui/react-collapsible/node_modules/@radix-ui/primitive": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.0.tgz",
+ "integrity": "sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==",
+ "license": "MIT"
+ },
+ "node_modules/@radix-ui/react-collapsible/node_modules/@radix-ui/react-compose-refs": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.0.tgz",
+ "integrity": "sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw==",
"license": "MIT",
- "dependencies": {
- "react-remove-scroll-bar": "^2.3.3",
- "react-style-singleton": "^2.2.1",
- "tslib": "^2.1.0",
- "use-callback-ref": "^1.3.0",
- "use-sidecar": "^1.1.2"
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
- "engines": {
- "node": ">=10"
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-collapsible/node_modules/@radix-ui/react-context": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.1.tgz",
+ "integrity": "sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-collapsible/node_modules/@radix-ui/react-id": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.0.tgz",
+ "integrity": "sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-use-layout-effect": "1.1.0"
},
"peerDependencies": {
- "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0",
- "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
@@ -9674,33 +10119,20 @@
}
}
},
- "node_modules/@radix-ui/react-navigation-menu": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-navigation-menu/-/react-navigation-menu-1.1.3.tgz",
- "integrity": "sha512-x4Uv0N47ABx3/frJazYXxvMpZeKJe0qmRIgQ2o3lhTqnTVg+CaZfVVO4nQLn3QJcDkTz8icElKffhFng47XIBA==",
+ "node_modules/@radix-ui/react-collapsible/node_modules/@radix-ui/react-presence": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.1.tgz",
+ "integrity": "sha512-IeFXVi4YS1K0wVZzXNrbaaUvIJ3qdY+/Ih4eHFhWA9SwGR9UDX7Ck8abvL57C4cv3wwMvUE0OG69Qc3NCcTe/A==",
"license": "MIT",
"dependencies": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/primitive": "1.0.1",
- "@radix-ui/react-collection": "1.0.3",
- "@radix-ui/react-compose-refs": "1.0.1",
- "@radix-ui/react-context": "1.0.1",
- "@radix-ui/react-direction": "1.0.1",
- "@radix-ui/react-dismissable-layer": "1.0.4",
- "@radix-ui/react-id": "1.0.1",
- "@radix-ui/react-presence": "1.0.1",
- "@radix-ui/react-primitive": "1.0.3",
- "@radix-ui/react-use-callback-ref": "1.0.1",
- "@radix-ui/react-use-controllable-state": "1.0.1",
- "@radix-ui/react-use-layout-effect": "1.0.1",
- "@radix-ui/react-use-previous": "1.0.1",
- "@radix-ui/react-visually-hidden": "1.0.3"
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-use-layout-effect": "1.1.0"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0",
- "react-dom": "^16.8 || ^17.0 || ^18.0"
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
@@ -9711,24 +10143,2386 @@
}
}
},
- "node_modules/@radix-ui/react-navigation-menu/node_modules/@radix-ui/react-dismissable-layer": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.0.4.tgz",
- "integrity": "sha512-7UpBa/RKMoHJYjie1gkF1DlK8l1fdU/VKDpoS3rCCo8YBJR294GwcEHyxHw72yvphJ7ld0AXEcSLAzY2F/WyCg==",
+ "node_modules/@radix-ui/react-collapsible/node_modules/@radix-ui/react-primitive": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.0.tgz",
+ "integrity": "sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw==",
"license": "MIT",
"dependencies": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/primitive": "1.0.1",
- "@radix-ui/react-compose-refs": "1.0.1",
- "@radix-ui/react-primitive": "1.0.3",
- "@radix-ui/react-use-callback-ref": "1.0.1",
- "@radix-ui/react-use-escape-keydown": "1.0.3"
+ "@radix-ui/react-slot": "1.1.0"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0",
- "react-dom": "^16.8 || ^17.0 || ^18.0"
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-collapsible/node_modules/@radix-ui/react-slot": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.0.tgz",
+ "integrity": "sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-compose-refs": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-collapsible/node_modules/@radix-ui/react-use-callback-ref": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz",
+ "integrity": "sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-collapsible/node_modules/@radix-ui/react-use-controllable-state": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.1.0.tgz",
+ "integrity": "sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-use-callback-ref": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-collapsible/node_modules/@radix-ui/react-use-layout-effect": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz",
+ "integrity": "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-collection": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.0.3.tgz",
+ "integrity": "sha512-3SzW+0PW7yBBoQlT8wNcGtaxaD0XSu0uLUFgrtHY08Acx05TaHaOmVLR73c0j/cqpDy53KBMO7s0dx2wmOIDIA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.13.10",
+ "@radix-ui/react-compose-refs": "1.0.1",
+ "@radix-ui/react-context": "1.0.1",
+ "@radix-ui/react-primitive": "1.0.3",
+ "@radix-ui/react-slot": "1.0.2"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0",
+ "react-dom": "^16.8 || ^17.0 || ^18.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-compose-refs": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.0.1.tgz",
+ "integrity": "sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.13.10"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-context": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.0.1.tgz",
+ "integrity": "sha512-ebbrdFoYTcuZ0v4wG5tedGnp9tzcV8awzsxYph7gXUyvnNLuTIcCk1q17JEbnVhXAKG9oX3KtchwiMIAYp9NLg==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.13.10"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-dialog": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.0.5.tgz",
+ "integrity": "sha512-GjWJX/AUpB703eEBanuBnIWdIXg6NvJFCXcNlSZk4xdszCdhrJgBoUd1cGk67vFO+WdA2pfI/plOpqz/5GUP6Q==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.13.10",
+ "@radix-ui/primitive": "1.0.1",
+ "@radix-ui/react-compose-refs": "1.0.1",
+ "@radix-ui/react-context": "1.0.1",
+ "@radix-ui/react-dismissable-layer": "1.0.5",
+ "@radix-ui/react-focus-guards": "1.0.1",
+ "@radix-ui/react-focus-scope": "1.0.4",
+ "@radix-ui/react-id": "1.0.1",
+ "@radix-ui/react-portal": "1.0.4",
+ "@radix-ui/react-presence": "1.0.1",
+ "@radix-ui/react-primitive": "1.0.3",
+ "@radix-ui/react-slot": "1.0.2",
+ "@radix-ui/react-use-controllable-state": "1.0.1",
+ "aria-hidden": "^1.1.1",
+ "react-remove-scroll": "2.5.5"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0",
+ "react-dom": "^16.8 || ^17.0 || ^18.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-dialog/node_modules/react-remove-scroll": {
+ "version": "2.5.5",
+ "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.5.tgz",
+ "integrity": "sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw==",
+ "license": "MIT",
+ "dependencies": {
+ "react-remove-scroll-bar": "^2.3.3",
+ "react-style-singleton": "^2.2.1",
+ "tslib": "^2.1.0",
+ "use-callback-ref": "^1.3.0",
+ "use-sidecar": "^1.1.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0",
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-direction": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.0.1.tgz",
+ "integrity": "sha512-RXcvnXgyvYvBEOhCBuddKecVkoMiI10Jcm5cTI7abJRAHYfFxeu+FBQs/DvdxSYucxR5mna0dNsL6QFlds5TMA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.13.10"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-dismissable-layer": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.0.5.tgz",
+ "integrity": "sha512-aJeDjQhywg9LBu2t/At58hCvr7pEm0o2Ke1x33B+MhjNmmZ17sy4KImo0KPLgsnc/zN7GPdce8Cnn0SWvwZO7g==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.13.10",
+ "@radix-ui/primitive": "1.0.1",
+ "@radix-ui/react-compose-refs": "1.0.1",
+ "@radix-ui/react-primitive": "1.0.3",
+ "@radix-ui/react-use-callback-ref": "1.0.1",
+ "@radix-ui/react-use-escape-keydown": "1.0.3"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0",
+ "react-dom": "^16.8 || ^17.0 || ^18.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-dropdown-menu": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.0.6.tgz",
+ "integrity": "sha512-i6TuFOoWmLWq+M/eCLGd/bQ2HfAX1RJgvrBQ6AQLmzfvsLdefxbWu8G9zczcPFfcSPehz9GcpF6K9QYreFV8hA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.13.10",
+ "@radix-ui/primitive": "1.0.1",
+ "@radix-ui/react-compose-refs": "1.0.1",
+ "@radix-ui/react-context": "1.0.1",
+ "@radix-ui/react-id": "1.0.1",
+ "@radix-ui/react-menu": "2.0.6",
+ "@radix-ui/react-primitive": "1.0.3",
+ "@radix-ui/react-use-controllable-state": "1.0.1"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0",
+ "react-dom": "^16.8 || ^17.0 || ^18.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-focus-guards": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.0.1.tgz",
+ "integrity": "sha512-Rect2dWbQ8waGzhMavsIbmSVCgYxkXLxxR3ZvCX79JOglzdEy4JXMb98lq4hPxUbLr77nP0UOGf4rcMU+s1pUA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.13.10"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-focus-scope": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.0.4.tgz",
+ "integrity": "sha512-sL04Mgvf+FmyvZeYfNu1EPAaaxD+aw7cYeIB9L9Fvq8+urhltTRaEo5ysKOpHuKPclsZcSUMKlN05x4u+CINpA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.13.10",
+ "@radix-ui/react-compose-refs": "1.0.1",
+ "@radix-ui/react-primitive": "1.0.3",
+ "@radix-ui/react-use-callback-ref": "1.0.1"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0",
+ "react-dom": "^16.8 || ^17.0 || ^18.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-id": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.0.1.tgz",
+ "integrity": "sha512-tI7sT/kqYp8p96yGWY1OAnLHrqDgzHefRBKQ2YAkBS5ja7QLcZ9Z/uY7bEjPUatf8RomoXM8/1sMj1IJaE5UzQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.13.10",
+ "@radix-ui/react-use-layout-effect": "1.0.1"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-label": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-label/-/react-label-2.1.0.tgz",
+ "integrity": "sha512-peLblDlFw/ngk3UWq0VnYaOLy6agTZZ+MUO/WhVfm14vJGML+xH4FAl2XQGLqdefjNb7ApRg6Yn7U42ZhmYXdw==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-primitive": "2.0.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-label/node_modules/@radix-ui/react-compose-refs": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.0.tgz",
+ "integrity": "sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-label/node_modules/@radix-ui/react-primitive": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.0.tgz",
+ "integrity": "sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-slot": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-label/node_modules/@radix-ui/react-slot": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.0.tgz",
+ "integrity": "sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-compose-refs": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-menu": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.0.6.tgz",
+ "integrity": "sha512-BVkFLS+bUC8HcImkRKPSiVumA1VPOOEC5WBMiT+QAVsPzW1FJzI9KnqgGxVDPBcql5xXrHkD3JOVoXWEXD8SYA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.13.10",
+ "@radix-ui/primitive": "1.0.1",
+ "@radix-ui/react-collection": "1.0.3",
+ "@radix-ui/react-compose-refs": "1.0.1",
+ "@radix-ui/react-context": "1.0.1",
+ "@radix-ui/react-direction": "1.0.1",
+ "@radix-ui/react-dismissable-layer": "1.0.5",
+ "@radix-ui/react-focus-guards": "1.0.1",
+ "@radix-ui/react-focus-scope": "1.0.4",
+ "@radix-ui/react-id": "1.0.1",
+ "@radix-ui/react-popper": "1.1.3",
+ "@radix-ui/react-portal": "1.0.4",
+ "@radix-ui/react-presence": "1.0.1",
+ "@radix-ui/react-primitive": "1.0.3",
+ "@radix-ui/react-roving-focus": "1.0.4",
+ "@radix-ui/react-slot": "1.0.2",
+ "@radix-ui/react-use-callback-ref": "1.0.1",
+ "aria-hidden": "^1.1.1",
+ "react-remove-scroll": "2.5.5"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0",
+ "react-dom": "^16.8 || ^17.0 || ^18.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-menu/node_modules/react-remove-scroll": {
+ "version": "2.5.5",
+ "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.5.tgz",
+ "integrity": "sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw==",
+ "license": "MIT",
+ "dependencies": {
+ "react-remove-scroll-bar": "^2.3.3",
+ "react-style-singleton": "^2.2.1",
+ "tslib": "^2.1.0",
+ "use-callback-ref": "^1.3.0",
+ "use-sidecar": "^1.1.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0",
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-navigation-menu": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-navigation-menu/-/react-navigation-menu-1.1.3.tgz",
+ "integrity": "sha512-x4Uv0N47ABx3/frJazYXxvMpZeKJe0qmRIgQ2o3lhTqnTVg+CaZfVVO4nQLn3QJcDkTz8icElKffhFng47XIBA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.13.10",
+ "@radix-ui/primitive": "1.0.1",
+ "@radix-ui/react-collection": "1.0.3",
+ "@radix-ui/react-compose-refs": "1.0.1",
+ "@radix-ui/react-context": "1.0.1",
+ "@radix-ui/react-direction": "1.0.1",
+ "@radix-ui/react-dismissable-layer": "1.0.4",
+ "@radix-ui/react-id": "1.0.1",
+ "@radix-ui/react-presence": "1.0.1",
+ "@radix-ui/react-primitive": "1.0.3",
+ "@radix-ui/react-use-callback-ref": "1.0.1",
+ "@radix-ui/react-use-controllable-state": "1.0.1",
+ "@radix-ui/react-use-layout-effect": "1.0.1",
+ "@radix-ui/react-use-previous": "1.0.1",
+ "@radix-ui/react-visually-hidden": "1.0.3"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0",
+ "react-dom": "^16.8 || ^17.0 || ^18.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-navigation-menu/node_modules/@radix-ui/react-dismissable-layer": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.0.4.tgz",
+ "integrity": "sha512-7UpBa/RKMoHJYjie1gkF1DlK8l1fdU/VKDpoS3rCCo8YBJR294GwcEHyxHw72yvphJ7ld0AXEcSLAzY2F/WyCg==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.13.10",
+ "@radix-ui/primitive": "1.0.1",
+ "@radix-ui/react-compose-refs": "1.0.1",
+ "@radix-ui/react-primitive": "1.0.3",
+ "@radix-ui/react-use-callback-ref": "1.0.1",
+ "@radix-ui/react-use-escape-keydown": "1.0.3"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0",
+ "react-dom": "^16.8 || ^17.0 || ^18.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-popover": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.1.1.tgz",
+ "integrity": "sha512-3y1A3isulwnWhvTTwmIreiB8CF4L+qRjZnK1wYLO7pplddzXKby/GnZ2M7OZY3qgnl6p9AodUIHRYGXNah8Y7g==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.1.0",
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-context": "1.1.0",
+ "@radix-ui/react-dismissable-layer": "1.1.0",
+ "@radix-ui/react-focus-guards": "1.1.0",
+ "@radix-ui/react-focus-scope": "1.1.0",
+ "@radix-ui/react-id": "1.1.0",
+ "@radix-ui/react-popper": "1.2.0",
+ "@radix-ui/react-portal": "1.1.1",
+ "@radix-ui/react-presence": "1.1.0",
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-slot": "1.1.0",
+ "@radix-ui/react-use-controllable-state": "1.1.0",
+ "aria-hidden": "^1.1.1",
+ "react-remove-scroll": "2.5.7"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-popover/node_modules/@floating-ui/react-dom": {
+ "version": "2.1.6",
+ "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.6.tgz",
+ "integrity": "sha512-4JX6rEatQEvlmgU80wZyq9RT96HZJa88q8hp0pBd+LrczeDI4o6uA2M+uvxngVHo4Ihr8uibXxH6+70zhAFrVw==",
+ "license": "MIT",
+ "dependencies": {
+ "@floating-ui/dom": "^1.7.4"
+ },
+ "peerDependencies": {
+ "react": ">=16.8.0",
+ "react-dom": ">=16.8.0"
+ }
+ },
+ "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/primitive": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.0.tgz",
+ "integrity": "sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==",
+ "license": "MIT"
+ },
+ "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-arrow": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.0.tgz",
+ "integrity": "sha512-FmlW1rCg7hBpEBwFbjHwCW6AmWLQM6g/v0Sn8XbP9NvmSZ2San1FpQeyPtufzOMSIx7Y4dzjlHoifhp+7NkZhw==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-primitive": "2.0.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-compose-refs": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.0.tgz",
+ "integrity": "sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-context": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.0.tgz",
+ "integrity": "sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-dismissable-layer": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.0.tgz",
+ "integrity": "sha512-/UovfmmXGptwGcBQawLzvn2jOfM0t4z3/uKffoBlj724+n3FvBbZ7M0aaBOmkp6pqFYpO4yx8tSVJjx3Fl2jig==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.1.0",
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-use-callback-ref": "1.1.0",
+ "@radix-ui/react-use-escape-keydown": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-focus-guards": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.0.tgz",
+ "integrity": "sha512-w6XZNUPVv6xCpZUqb/yN9DL6auvpGX3C/ee6Hdi16v2UUy25HV2Q5bcflsiDyT/g5RwbPQ/GIT1vLkeRb+ITBw==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-focus-scope": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.0.tgz",
+ "integrity": "sha512-200UD8zylvEyL8Bx+z76RJnASR2gRMuxlgFCPAe/Q/679a/r0eK3MBVYMb7vZODZcffZBdob1EGnky78xmVvcA==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-use-callback-ref": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-id": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.0.tgz",
+ "integrity": "sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-use-layout-effect": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-popper": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.0.tgz",
+ "integrity": "sha512-ZnRMshKF43aBxVWPWvbj21+7TQCvhuULWJ4gNIKYpRlQt5xGRhLx66tMp8pya2UkGHTSlhpXwmjqltDYHhw7Vg==",
+ "license": "MIT",
+ "dependencies": {
+ "@floating-ui/react-dom": "^2.0.0",
+ "@radix-ui/react-arrow": "1.1.0",
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-context": "1.1.0",
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-use-callback-ref": "1.1.0",
+ "@radix-ui/react-use-layout-effect": "1.1.0",
+ "@radix-ui/react-use-rect": "1.1.0",
+ "@radix-ui/react-use-size": "1.1.0",
+ "@radix-ui/rect": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-portal": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.1.tgz",
+ "integrity": "sha512-A3UtLk85UtqhzFqtoC8Q0KvR2GbXF3mtPgACSazajqq6A41mEQgo53iPzY4i6BwDxlIFqWIhiQ2G729n+2aw/g==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-use-layout-effect": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-presence": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.0.tgz",
+ "integrity": "sha512-Gq6wuRN/asf9H/E/VzdKoUtT8GC9PQc9z40/vEr0VCJ4u5XvvhWIrSsCB6vD2/cH7ugTdSfYq9fLJCcM00acrQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-use-layout-effect": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-primitive": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.0.tgz",
+ "integrity": "sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-slot": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-slot": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.0.tgz",
+ "integrity": "sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-compose-refs": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-use-callback-ref": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz",
+ "integrity": "sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-use-controllable-state": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.1.0.tgz",
+ "integrity": "sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-use-callback-ref": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-use-escape-keydown": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.0.tgz",
+ "integrity": "sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-use-callback-ref": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-use-layout-effect": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz",
+ "integrity": "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-use-rect": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.0.tgz",
+ "integrity": "sha512-0Fmkebhr6PiseyZlYAOtLS+nb7jLmpqTrJyv61Pe68MKYW6OWdRE2kI70TaYY27u7H0lajqM3hSMMLFq18Z7nQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/rect": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-use-size": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.0.tgz",
+ "integrity": "sha512-XW3/vWuIXHa+2Uwcc2ABSfcCledmXhhQPlGbfcRXbiUQI5Icjcg19BGCZVKKInYbvUCut/ufbbLLPFC5cbb1hw==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-use-layout-effect": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/rect": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.0.tgz",
+ "integrity": "sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg==",
+ "license": "MIT"
+ },
+ "node_modules/@radix-ui/react-popover/node_modules/react-remove-scroll": {
+ "version": "2.5.7",
+ "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.7.tgz",
+ "integrity": "sha512-FnrTWO4L7/Bhhf3CYBNArEG/yROV0tKmTv7/3h9QCFvH6sndeFf1wPqOcbFVu5VAulS5dV1wGT3GZZ/1GawqiA==",
+ "license": "MIT",
+ "dependencies": {
+ "react-remove-scroll-bar": "^2.3.4",
+ "react-style-singleton": "^2.2.1",
+ "tslib": "^2.1.0",
+ "use-callback-ref": "^1.3.0",
+ "use-sidecar": "^1.1.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0",
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-popper": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.1.3.tgz",
+ "integrity": "sha512-cKpopj/5RHZWjrbF2846jBNacjQVwkP068DfmgrNJXpvVWrOvlAmE9xSiy5OqeE+Gi8D9fP+oDhUnPqNMY8/5w==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.13.10",
+ "@floating-ui/react-dom": "^2.0.0",
+ "@radix-ui/react-arrow": "1.0.3",
+ "@radix-ui/react-compose-refs": "1.0.1",
+ "@radix-ui/react-context": "1.0.1",
+ "@radix-ui/react-primitive": "1.0.3",
+ "@radix-ui/react-use-callback-ref": "1.0.1",
+ "@radix-ui/react-use-layout-effect": "1.0.1",
+ "@radix-ui/react-use-rect": "1.0.1",
+ "@radix-ui/react-use-size": "1.0.1",
+ "@radix-ui/rect": "1.0.1"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0",
+ "react-dom": "^16.8 || ^17.0 || ^18.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-popper/node_modules/@floating-ui/react-dom": {
+ "version": "2.1.6",
+ "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.6.tgz",
+ "integrity": "sha512-4JX6rEatQEvlmgU80wZyq9RT96HZJa88q8hp0pBd+LrczeDI4o6uA2M+uvxngVHo4Ihr8uibXxH6+70zhAFrVw==",
+ "license": "MIT",
+ "dependencies": {
+ "@floating-ui/dom": "^1.7.4"
+ },
+ "peerDependencies": {
+ "react": ">=16.8.0",
+ "react-dom": ">=16.8.0"
+ }
+ },
+ "node_modules/@radix-ui/react-portal": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.0.4.tgz",
+ "integrity": "sha512-Qki+C/EuGUVCQTOTD5vzJzJuMUlewbzuKyUy+/iHM2uwGiru9gZeBJtHAPKAEkB5KWGi9mP/CHKcY0wt1aW45Q==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.13.10",
+ "@radix-ui/react-primitive": "1.0.3"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0",
+ "react-dom": "^16.8 || ^17.0 || ^18.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-presence": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.0.1.tgz",
+ "integrity": "sha512-UXLW4UAbIY5ZjcvzjfRFo5gxva8QirC9hF7wRE4U5gz+TP0DbRk+//qyuAQ1McDxBt1xNMBTaciFGvEmJvAZCg==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.13.10",
+ "@radix-ui/react-compose-refs": "1.0.1",
+ "@radix-ui/react-use-layout-effect": "1.0.1"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0",
+ "react-dom": "^16.8 || ^17.0 || ^18.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-primitive": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-1.0.3.tgz",
+ "integrity": "sha512-yi58uVyoAcK/Nq1inRY56ZSjKypBNKTa/1mcL8qdl6oJeEaDbOldlzrGn7P6Q3Id5d+SYNGc5AJgc4vGhjs5+g==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.13.10",
+ "@radix-ui/react-slot": "1.0.2"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0",
+ "react-dom": "^16.8 || ^17.0 || ^18.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-radio-group": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-radio-group/-/react-radio-group-1.2.1.tgz",
+ "integrity": "sha512-kdbv54g4vfRjja9DNWPMxKvXblzqbpEC8kspEkZ6dVP7kQksGCn+iZHkcCz2nb00+lPdRvxrqy4WrvvV1cNqrQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.1.0",
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-context": "1.1.1",
+ "@radix-ui/react-direction": "1.1.0",
+ "@radix-ui/react-presence": "1.1.1",
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-roving-focus": "1.1.0",
+ "@radix-ui/react-use-controllable-state": "1.1.0",
+ "@radix-ui/react-use-previous": "1.1.0",
+ "@radix-ui/react-use-size": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-radio-group/node_modules/@radix-ui/primitive": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.0.tgz",
+ "integrity": "sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==",
+ "license": "MIT"
+ },
+ "node_modules/@radix-ui/react-radio-group/node_modules/@radix-ui/react-collection": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.0.tgz",
+ "integrity": "sha512-GZsZslMJEyo1VKm5L1ZJY8tGDxZNPAoUeQUIbKeJfoi7Q4kmig5AsgLMYYuyYbfjd8fBmFORAIwYAkXMnXZgZw==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-context": "1.1.0",
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-slot": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-radio-group/node_modules/@radix-ui/react-collection/node_modules/@radix-ui/react-context": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.0.tgz",
+ "integrity": "sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-radio-group/node_modules/@radix-ui/react-compose-refs": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.0.tgz",
+ "integrity": "sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-radio-group/node_modules/@radix-ui/react-context": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.1.tgz",
+ "integrity": "sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-radio-group/node_modules/@radix-ui/react-direction": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.0.tgz",
+ "integrity": "sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-radio-group/node_modules/@radix-ui/react-id": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.0.tgz",
+ "integrity": "sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-use-layout-effect": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-radio-group/node_modules/@radix-ui/react-presence": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.1.tgz",
+ "integrity": "sha512-IeFXVi4YS1K0wVZzXNrbaaUvIJ3qdY+/Ih4eHFhWA9SwGR9UDX7Ck8abvL57C4cv3wwMvUE0OG69Qc3NCcTe/A==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-use-layout-effect": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-radio-group/node_modules/@radix-ui/react-primitive": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.0.tgz",
+ "integrity": "sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-slot": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-radio-group/node_modules/@radix-ui/react-roving-focus": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.0.tgz",
+ "integrity": "sha512-EA6AMGeq9AEeQDeSH0aZgG198qkfHSbvWTf1HvoDmOB5bBG/qTxjYMWUKMnYiV6J/iP/J8MEFSuB2zRU2n7ODA==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.1.0",
+ "@radix-ui/react-collection": "1.1.0",
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-context": "1.1.0",
+ "@radix-ui/react-direction": "1.1.0",
+ "@radix-ui/react-id": "1.1.0",
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-use-callback-ref": "1.1.0",
+ "@radix-ui/react-use-controllable-state": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-radio-group/node_modules/@radix-ui/react-roving-focus/node_modules/@radix-ui/react-context": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.0.tgz",
+ "integrity": "sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-radio-group/node_modules/@radix-ui/react-slot": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.0.tgz",
+ "integrity": "sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-compose-refs": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-radio-group/node_modules/@radix-ui/react-use-callback-ref": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz",
+ "integrity": "sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-radio-group/node_modules/@radix-ui/react-use-controllable-state": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.1.0.tgz",
+ "integrity": "sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-use-callback-ref": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-radio-group/node_modules/@radix-ui/react-use-layout-effect": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz",
+ "integrity": "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-radio-group/node_modules/@radix-ui/react-use-previous": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.0.tgz",
+ "integrity": "sha512-Z/e78qg2YFnnXcW88A4JmTtm4ADckLno6F7OXotmkQfeuCVaKuYzqAATPhVzl3delXE7CxIV8shofPn3jPc5Og==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-radio-group/node_modules/@radix-ui/react-use-size": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.0.tgz",
+ "integrity": "sha512-XW3/vWuIXHa+2Uwcc2ABSfcCledmXhhQPlGbfcRXbiUQI5Icjcg19BGCZVKKInYbvUCut/ufbbLLPFC5cbb1hw==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-use-layout-effect": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-roving-focus": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.0.4.tgz",
+ "integrity": "sha512-2mUg5Mgcu001VkGy+FfzZyzbmuUWzgWkj3rvv4yu+mLw03+mTzbxZHvfcGyFp2b8EkQeMkpRQ5FiA2Vr2O6TeQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.13.10",
+ "@radix-ui/primitive": "1.0.1",
+ "@radix-ui/react-collection": "1.0.3",
+ "@radix-ui/react-compose-refs": "1.0.1",
+ "@radix-ui/react-context": "1.0.1",
+ "@radix-ui/react-direction": "1.0.1",
+ "@radix-ui/react-id": "1.0.1",
+ "@radix-ui/react-primitive": "1.0.3",
+ "@radix-ui/react-use-callback-ref": "1.0.1",
+ "@radix-ui/react-use-controllable-state": "1.0.1"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0",
+ "react-dom": "^16.8 || ^17.0 || ^18.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-select": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.1.2.tgz",
+ "integrity": "sha512-rZJtWmorC7dFRi0owDmoijm6nSJH1tVw64QGiNIZ9PNLyBDtG+iAq+XGsya052At4BfarzY/Dhv9wrrUr6IMZA==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/number": "1.1.0",
+ "@radix-ui/primitive": "1.1.0",
+ "@radix-ui/react-collection": "1.1.0",
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-context": "1.1.1",
+ "@radix-ui/react-direction": "1.1.0",
+ "@radix-ui/react-dismissable-layer": "1.1.1",
+ "@radix-ui/react-focus-guards": "1.1.1",
+ "@radix-ui/react-focus-scope": "1.1.0",
+ "@radix-ui/react-id": "1.1.0",
+ "@radix-ui/react-popper": "1.2.0",
+ "@radix-ui/react-portal": "1.1.2",
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-slot": "1.1.0",
+ "@radix-ui/react-use-callback-ref": "1.1.0",
+ "@radix-ui/react-use-controllable-state": "1.1.0",
+ "@radix-ui/react-use-layout-effect": "1.1.0",
+ "@radix-ui/react-use-previous": "1.1.0",
+ "@radix-ui/react-visually-hidden": "1.1.0",
+ "aria-hidden": "^1.1.1",
+ "react-remove-scroll": "2.6.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-select/node_modules/@floating-ui/react-dom": {
+ "version": "2.1.6",
+ "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.6.tgz",
+ "integrity": "sha512-4JX6rEatQEvlmgU80wZyq9RT96HZJa88q8hp0pBd+LrczeDI4o6uA2M+uvxngVHo4Ihr8uibXxH6+70zhAFrVw==",
+ "license": "MIT",
+ "dependencies": {
+ "@floating-ui/dom": "^1.7.4"
+ },
+ "peerDependencies": {
+ "react": ">=16.8.0",
+ "react-dom": ">=16.8.0"
+ }
+ },
+ "node_modules/@radix-ui/react-select/node_modules/@radix-ui/primitive": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.0.tgz",
+ "integrity": "sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==",
+ "license": "MIT"
+ },
+ "node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-arrow": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.0.tgz",
+ "integrity": "sha512-FmlW1rCg7hBpEBwFbjHwCW6AmWLQM6g/v0Sn8XbP9NvmSZ2San1FpQeyPtufzOMSIx7Y4dzjlHoifhp+7NkZhw==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-primitive": "2.0.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-collection": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.0.tgz",
+ "integrity": "sha512-GZsZslMJEyo1VKm5L1ZJY8tGDxZNPAoUeQUIbKeJfoi7Q4kmig5AsgLMYYuyYbfjd8fBmFORAIwYAkXMnXZgZw==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-context": "1.1.0",
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-slot": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-collection/node_modules/@radix-ui/react-context": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.0.tgz",
+ "integrity": "sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-compose-refs": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.0.tgz",
+ "integrity": "sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-context": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.1.tgz",
+ "integrity": "sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-direction": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.0.tgz",
+ "integrity": "sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-dismissable-layer": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.1.tgz",
+ "integrity": "sha512-QSxg29lfr/xcev6kSz7MAlmDnzbP1eI/Dwn3Tp1ip0KT5CUELsxkekFEMVBEoykI3oV39hKT4TKZzBNMbcTZYQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.1.0",
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-use-callback-ref": "1.1.0",
+ "@radix-ui/react-use-escape-keydown": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-focus-guards": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.1.tgz",
+ "integrity": "sha512-pSIwfrT1a6sIoDASCSpFwOasEwKTZWDw/iBdtnqKO7v6FeOzYJ7U53cPzYFVR3geGGXgVHaH+CdngrrAzqUGxg==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-focus-scope": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.0.tgz",
+ "integrity": "sha512-200UD8zylvEyL8Bx+z76RJnASR2gRMuxlgFCPAe/Q/679a/r0eK3MBVYMb7vZODZcffZBdob1EGnky78xmVvcA==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-use-callback-ref": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-id": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.0.tgz",
+ "integrity": "sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-use-layout-effect": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-popper": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.0.tgz",
+ "integrity": "sha512-ZnRMshKF43aBxVWPWvbj21+7TQCvhuULWJ4gNIKYpRlQt5xGRhLx66tMp8pya2UkGHTSlhpXwmjqltDYHhw7Vg==",
+ "license": "MIT",
+ "dependencies": {
+ "@floating-ui/react-dom": "^2.0.0",
+ "@radix-ui/react-arrow": "1.1.0",
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-context": "1.1.0",
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-use-callback-ref": "1.1.0",
+ "@radix-ui/react-use-layout-effect": "1.1.0",
+ "@radix-ui/react-use-rect": "1.1.0",
+ "@radix-ui/react-use-size": "1.1.0",
+ "@radix-ui/rect": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-popper/node_modules/@radix-ui/react-context": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.0.tgz",
+ "integrity": "sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-portal": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.2.tgz",
+ "integrity": "sha512-WeDYLGPxJb/5EGBoedyJbT0MpoULmwnIPMJMSldkuiMsBAv7N1cRdsTWZWht9vpPOiN3qyiGAtbK2is47/uMFg==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-use-layout-effect": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-primitive": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.0.tgz",
+ "integrity": "sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-slot": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-slot": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.0.tgz",
+ "integrity": "sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-compose-refs": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-use-callback-ref": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz",
+ "integrity": "sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-use-controllable-state": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.1.0.tgz",
+ "integrity": "sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-use-callback-ref": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-use-escape-keydown": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.0.tgz",
+ "integrity": "sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-use-callback-ref": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-use-layout-effect": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz",
+ "integrity": "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-use-previous": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.0.tgz",
+ "integrity": "sha512-Z/e78qg2YFnnXcW88A4JmTtm4ADckLno6F7OXotmkQfeuCVaKuYzqAATPhVzl3delXE7CxIV8shofPn3jPc5Og==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-use-rect": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.0.tgz",
+ "integrity": "sha512-0Fmkebhr6PiseyZlYAOtLS+nb7jLmpqTrJyv61Pe68MKYW6OWdRE2kI70TaYY27u7H0lajqM3hSMMLFq18Z7nQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/rect": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-use-size": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.0.tgz",
+ "integrity": "sha512-XW3/vWuIXHa+2Uwcc2ABSfcCledmXhhQPlGbfcRXbiUQI5Icjcg19BGCZVKKInYbvUCut/ufbbLLPFC5cbb1hw==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-use-layout-effect": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-visually-hidden": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.1.0.tgz",
+ "integrity": "sha512-N8MDZqtgCgG5S3aV60INAB475osJousYpZ4cTJ2cFbMpdHS5Y6loLTH8LPtkj2QN0x93J30HT/M3qJXM0+lyeQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-primitive": "2.0.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-select/node_modules/@radix-ui/rect": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.0.tgz",
+ "integrity": "sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg==",
+ "license": "MIT"
+ },
+ "node_modules/@radix-ui/react-select/node_modules/react-remove-scroll": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.6.0.tgz",
+ "integrity": "sha512-I2U4JVEsQenxDAKaVa3VZ/JeJZe0/2DxPWL8Tj8yLKctQJQiZM52pn/GWFpSp8dftjM3pSAHVJZscAnC/y+ySQ==",
+ "license": "MIT",
+ "dependencies": {
+ "react-remove-scroll-bar": "^2.3.6",
+ "react-style-singleton": "^2.2.1",
+ "tslib": "^2.1.0",
+ "use-callback-ref": "^1.3.0",
+ "use-sidecar": "^1.1.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0",
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-slot": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.2.tgz",
+ "integrity": "sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.13.10",
+ "@radix-ui/react-compose-refs": "1.0.1"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-switch": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-switch/-/react-switch-1.1.1.tgz",
+ "integrity": "sha512-diPqDDoBcZPSicYoMWdWx+bCPuTRH4QSp9J+65IvtdS0Kuzt67bI6n32vCj8q6NZmYW/ah+2orOtMwcX5eQwIg==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.1.0",
+ "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-context": "1.1.1",
+ "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-use-controllable-state": "1.1.0",
+ "@radix-ui/react-use-previous": "1.1.0",
+ "@radix-ui/react-use-size": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-switch/node_modules/@radix-ui/primitive": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.0.tgz",
+ "integrity": "sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==",
+ "license": "MIT"
+ },
+ "node_modules/@radix-ui/react-switch/node_modules/@radix-ui/react-compose-refs": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.0.tgz",
+ "integrity": "sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-switch/node_modules/@radix-ui/react-context": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.1.tgz",
+ "integrity": "sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-switch/node_modules/@radix-ui/react-primitive": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.0.tgz",
+ "integrity": "sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-slot": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-switch/node_modules/@radix-ui/react-slot": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.0.tgz",
+ "integrity": "sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-compose-refs": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-switch/node_modules/@radix-ui/react-use-callback-ref": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz",
+ "integrity": "sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-switch/node_modules/@radix-ui/react-use-controllable-state": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.1.0.tgz",
+ "integrity": "sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-use-callback-ref": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-switch/node_modules/@radix-ui/react-use-layout-effect": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz",
+ "integrity": "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-switch/node_modules/@radix-ui/react-use-previous": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.0.tgz",
+ "integrity": "sha512-Z/e78qg2YFnnXcW88A4JmTtm4ADckLno6F7OXotmkQfeuCVaKuYzqAATPhVzl3delXE7CxIV8shofPn3jPc5Og==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-switch/node_modules/@radix-ui/react-use-size": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.0.tgz",
+ "integrity": "sha512-XW3/vWuIXHa+2Uwcc2ABSfcCledmXhhQPlGbfcRXbiUQI5Icjcg19BGCZVKKInYbvUCut/ufbbLLPFC5cbb1hw==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-use-layout-effect": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-tabs": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.1.3.tgz",
+ "integrity": "sha512-9mFyI30cuRDImbmFF6O2KUJdgEOsGh9Vmx9x/Dh9tOhL7BngmQPQfwW4aejKm5OHpfWIdmeV6ySyuxoOGjtNng==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.1.1",
+ "@radix-ui/react-context": "1.1.1",
+ "@radix-ui/react-direction": "1.1.0",
+ "@radix-ui/react-id": "1.1.0",
+ "@radix-ui/react-presence": "1.1.2",
+ "@radix-ui/react-primitive": "2.0.2",
+ "@radix-ui/react-roving-focus": "1.1.2",
+ "@radix-ui/react-use-controllable-state": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-tabs/node_modules/@radix-ui/primitive": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.1.tgz",
+ "integrity": "sha512-SJ31y+Q/zAyShtXJc8x83i9TYdbAfHZ++tUZnvjJJqFjzsdUnKsxPL6IEtBlxKkU7yzer//GQtZSV4GbldL3YA==",
+ "license": "MIT"
+ },
+ "node_modules/@radix-ui/react-tabs/node_modules/@radix-ui/react-collection": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.2.tgz",
+ "integrity": "sha512-9z54IEKRxIa9VityapoEYMuByaG42iSy1ZXlY2KcuLSEtq8x4987/N6m15ppoMffgZX72gER2uHe1D9Y6Unlcw==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-compose-refs": "1.1.1",
+ "@radix-ui/react-context": "1.1.1",
+ "@radix-ui/react-primitive": "2.0.2",
+ "@radix-ui/react-slot": "1.1.2"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-tabs/node_modules/@radix-ui/react-compose-refs": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.1.tgz",
+ "integrity": "sha512-Y9VzoRDSJtgFMUCoiZBDVo084VQ5hfpXxVE+NgkdNsjiDBByiImMZKKhxMwCbdHvhlENG6a833CbFkOQvTricw==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-tabs/node_modules/@radix-ui/react-context": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.1.tgz",
+ "integrity": "sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-tabs/node_modules/@radix-ui/react-direction": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.0.tgz",
+ "integrity": "sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-tabs/node_modules/@radix-ui/react-id": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.0.tgz",
+ "integrity": "sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-use-layout-effect": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-tabs/node_modules/@radix-ui/react-presence": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.2.tgz",
+ "integrity": "sha512-18TFr80t5EVgL9x1SwF/YGtfG+l0BS0PRAlCWBDoBEiDQjeKgnNZRVJp/oVBl24sr3Gbfwc/Qpj4OcWTQMsAEg==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-compose-refs": "1.1.1",
+ "@radix-ui/react-use-layout-effect": "1.1.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
@@ -9739,27 +12533,13 @@
}
}
},
- "node_modules/@radix-ui/react-popover": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.1.1.tgz",
- "integrity": "sha512-3y1A3isulwnWhvTTwmIreiB8CF4L+qRjZnK1wYLO7pplddzXKby/GnZ2M7OZY3qgnl6p9AodUIHRYGXNah8Y7g==",
+ "node_modules/@radix-ui/react-tabs/node_modules/@radix-ui/react-primitive": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.2.tgz",
+ "integrity": "sha512-Ec/0d38EIuvDF+GZjcMU/Ze6MxntVJYO/fRlCPhCaVUyPY9WTalHJw54tp9sXeJo3tlShWpy41vQRgLRGOuz+w==",
"license": "MIT",
"dependencies": {
- "@radix-ui/primitive": "1.1.0",
- "@radix-ui/react-compose-refs": "1.1.0",
- "@radix-ui/react-context": "1.1.0",
- "@radix-ui/react-dismissable-layer": "1.1.0",
- "@radix-ui/react-focus-guards": "1.1.0",
- "@radix-ui/react-focus-scope": "1.1.0",
- "@radix-ui/react-id": "1.1.0",
- "@radix-ui/react-popper": "1.2.0",
- "@radix-ui/react-portal": "1.1.1",
- "@radix-ui/react-presence": "1.1.0",
- "@radix-ui/react-primitive": "2.0.0",
- "@radix-ui/react-slot": "1.1.0",
- "@radix-ui/react-use-controllable-state": "1.1.0",
- "aria-hidden": "^1.1.1",
- "react-remove-scroll": "2.5.7"
+ "@radix-ui/react-slot": "1.1.2"
},
"peerDependencies": {
"@types/react": "*",
@@ -9776,32 +12556,21 @@
}
}
},
- "node_modules/@radix-ui/react-popover/node_modules/@floating-ui/react-dom": {
- "version": "2.1.6",
- "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.6.tgz",
- "integrity": "sha512-4JX6rEatQEvlmgU80wZyq9RT96HZJa88q8hp0pBd+LrczeDI4o6uA2M+uvxngVHo4Ihr8uibXxH6+70zhAFrVw==",
- "license": "MIT",
- "dependencies": {
- "@floating-ui/dom": "^1.7.4"
- },
- "peerDependencies": {
- "react": ">=16.8.0",
- "react-dom": ">=16.8.0"
- }
- },
- "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/primitive": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.0.tgz",
- "integrity": "sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==",
- "license": "MIT"
- },
- "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-arrow": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.0.tgz",
- "integrity": "sha512-FmlW1rCg7hBpEBwFbjHwCW6AmWLQM6g/v0Sn8XbP9NvmSZ2San1FpQeyPtufzOMSIx7Y4dzjlHoifhp+7NkZhw==",
+ "node_modules/@radix-ui/react-tabs/node_modules/@radix-ui/react-roving-focus": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.2.tgz",
+ "integrity": "sha512-zgMQWkNO169GtGqRvYrzb0Zf8NhMHS2DuEB/TiEmVnpr5OqPU3i8lfbxaAmC2J/KYuIQxyoQQ6DxepyXp61/xw==",
"license": "MIT",
"dependencies": {
- "@radix-ui/react-primitive": "2.0.0"
+ "@radix-ui/primitive": "1.1.1",
+ "@radix-ui/react-collection": "1.1.2",
+ "@radix-ui/react-compose-refs": "1.1.1",
+ "@radix-ui/react-context": "1.1.1",
+ "@radix-ui/react-direction": "1.1.0",
+ "@radix-ui/react-id": "1.1.0",
+ "@radix-ui/react-primitive": "2.0.2",
+ "@radix-ui/react-use-callback-ref": "1.1.0",
+ "@radix-ui/react-use-controllable-state": "1.1.0"
},
"peerDependencies": {
"@types/react": "*",
@@ -9818,11 +12587,14 @@
}
}
},
- "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-compose-refs": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.0.tgz",
- "integrity": "sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw==",
+ "node_modules/@radix-ui/react-tabs/node_modules/@radix-ui/react-slot": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.2.tgz",
+ "integrity": "sha512-YAKxaiGsSQJ38VzKH86/BPRC4rh+b1Jpa+JneA5LRE7skmLPNAyeG8kPJj/oo4STLvlrs8vkf/iYyc3A5stYCQ==",
"license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-compose-refs": "1.1.1"
+ },
"peerDependencies": {
"@types/react": "*",
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
@@ -9833,10 +12605,10 @@
}
}
},
- "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-context": {
+ "node_modules/@radix-ui/react-tabs/node_modules/@radix-ui/react-use-callback-ref": {
"version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.0.tgz",
- "integrity": "sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz",
+ "integrity": "sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==",
"license": "MIT",
"peerDependencies": {
"@types/react": "*",
@@ -9848,37 +12620,28 @@
}
}
},
- "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-dismissable-layer": {
+ "node_modules/@radix-ui/react-tabs/node_modules/@radix-ui/react-use-controllable-state": {
"version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.0.tgz",
- "integrity": "sha512-/UovfmmXGptwGcBQawLzvn2jOfM0t4z3/uKffoBlj724+n3FvBbZ7M0aaBOmkp6pqFYpO4yx8tSVJjx3Fl2jig==",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.1.0.tgz",
+ "integrity": "sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==",
"license": "MIT",
"dependencies": {
- "@radix-ui/primitive": "1.1.0",
- "@radix-ui/react-compose-refs": "1.1.0",
- "@radix-ui/react-primitive": "2.0.0",
- "@radix-ui/react-use-callback-ref": "1.1.0",
- "@radix-ui/react-use-escape-keydown": "1.1.0"
+ "@radix-ui/react-use-callback-ref": "1.1.0"
},
"peerDependencies": {
"@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
- },
- "@types/react-dom": {
- "optional": true
}
}
},
- "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-focus-guards": {
+ "node_modules/@radix-ui/react-tabs/node_modules/@radix-ui/react-use-layout-effect": {
"version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.0.tgz",
- "integrity": "sha512-w6XZNUPVv6xCpZUqb/yN9DL6auvpGX3C/ee6Hdi16v2UUy25HV2Q5bcflsiDyT/g5RwbPQ/GIT1vLkeRb+ITBw==",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz",
+ "integrity": "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==",
"license": "MIT",
"peerDependencies": {
"@types/react": "*",
@@ -9890,15 +12653,56 @@
}
}
},
- "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-focus-scope": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.0.tgz",
- "integrity": "sha512-200UD8zylvEyL8Bx+z76RJnASR2gRMuxlgFCPAe/Q/679a/r0eK3MBVYMb7vZODZcffZBdob1EGnky78xmVvcA==",
+ "node_modules/@radix-ui/react-toast": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-toast/-/react-toast-1.2.4.tgz",
+ "integrity": "sha512-Sch9idFJHJTMH9YNpxxESqABcAFweJG4tKv+0zo0m5XBvUSL8FM5xKcJLFLXononpePs8IclyX1KieL5SDUNgA==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.1.1",
+ "@radix-ui/react-collection": "1.1.1",
+ "@radix-ui/react-compose-refs": "1.1.1",
+ "@radix-ui/react-context": "1.1.1",
+ "@radix-ui/react-dismissable-layer": "1.1.3",
+ "@radix-ui/react-portal": "1.1.3",
+ "@radix-ui/react-presence": "1.1.2",
+ "@radix-ui/react-primitive": "2.0.1",
+ "@radix-ui/react-use-callback-ref": "1.1.0",
+ "@radix-ui/react-use-controllable-state": "1.1.0",
+ "@radix-ui/react-use-layout-effect": "1.1.0",
+ "@radix-ui/react-visually-hidden": "1.1.1"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-toast/node_modules/@radix-ui/primitive": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.1.tgz",
+ "integrity": "sha512-SJ31y+Q/zAyShtXJc8x83i9TYdbAfHZ++tUZnvjJJqFjzsdUnKsxPL6IEtBlxKkU7yzer//GQtZSV4GbldL3YA==",
+ "license": "MIT"
+ },
+ "node_modules/@radix-ui/react-toast/node_modules/@radix-ui/react-collection": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.1.tgz",
+ "integrity": "sha512-LwT3pSho9Dljg+wY2KN2mrrh6y3qELfftINERIzBUO9e0N+t0oMTyn3k9iv+ZqgrwGkRnLpNJrsMv9BZlt2yuA==",
"license": "MIT",
"dependencies": {
- "@radix-ui/react-compose-refs": "1.1.0",
- "@radix-ui/react-primitive": "2.0.0",
- "@radix-ui/react-use-callback-ref": "1.1.0"
+ "@radix-ui/react-compose-refs": "1.1.1",
+ "@radix-ui/react-context": "1.1.1",
+ "@radix-ui/react-primitive": "2.0.1",
+ "@radix-ui/react-slot": "1.1.1"
},
"peerDependencies": {
"@types/react": "*",
@@ -9915,14 +12719,26 @@
}
}
},
- "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-id": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.0.tgz",
- "integrity": "sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==",
+ "node_modules/@radix-ui/react-toast/node_modules/@radix-ui/react-compose-refs": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.1.tgz",
+ "integrity": "sha512-Y9VzoRDSJtgFMUCoiZBDVo084VQ5hfpXxVE+NgkdNsjiDBByiImMZKKhxMwCbdHvhlENG6a833CbFkOQvTricw==",
"license": "MIT",
- "dependencies": {
- "@radix-ui/react-use-layout-effect": "1.1.0"
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-toast/node_modules/@radix-ui/react-context": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.1.tgz",
+ "integrity": "sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==",
+ "license": "MIT",
"peerDependencies": {
"@types/react": "*",
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
@@ -9933,22 +12749,17 @@
}
}
},
- "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-popper": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.0.tgz",
- "integrity": "sha512-ZnRMshKF43aBxVWPWvbj21+7TQCvhuULWJ4gNIKYpRlQt5xGRhLx66tMp8pya2UkGHTSlhpXwmjqltDYHhw7Vg==",
+ "node_modules/@radix-ui/react-toast/node_modules/@radix-ui/react-dismissable-layer": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.3.tgz",
+ "integrity": "sha512-onrWn/72lQoEucDmJnr8uczSNTujT0vJnA/X5+3AkChVPowr8n1yvIKIabhWyMQeMvvmdpsvcyDqx3X1LEXCPg==",
"license": "MIT",
"dependencies": {
- "@floating-ui/react-dom": "^2.0.0",
- "@radix-ui/react-arrow": "1.1.0",
- "@radix-ui/react-compose-refs": "1.1.0",
- "@radix-ui/react-context": "1.1.0",
- "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/primitive": "1.1.1",
+ "@radix-ui/react-compose-refs": "1.1.1",
+ "@radix-ui/react-primitive": "2.0.1",
"@radix-ui/react-use-callback-ref": "1.1.0",
- "@radix-ui/react-use-layout-effect": "1.1.0",
- "@radix-ui/react-use-rect": "1.1.0",
- "@radix-ui/react-use-size": "1.1.0",
- "@radix-ui/rect": "1.1.0"
+ "@radix-ui/react-use-escape-keydown": "1.1.0"
},
"peerDependencies": {
"@types/react": "*",
@@ -9965,13 +12776,13 @@
}
}
},
- "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-portal": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.1.tgz",
- "integrity": "sha512-A3UtLk85UtqhzFqtoC8Q0KvR2GbXF3mtPgACSazajqq6A41mEQgo53iPzY4i6BwDxlIFqWIhiQ2G729n+2aw/g==",
+ "node_modules/@radix-ui/react-toast/node_modules/@radix-ui/react-portal": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.3.tgz",
+ "integrity": "sha512-NciRqhXnGojhT93RPyDaMPfLH3ZSl4jjIFbZQ1b/vxvZEdHsBZ49wP9w8L3HzUQwep01LcWtkUvm0OVB5JAHTw==",
"license": "MIT",
"dependencies": {
- "@radix-ui/react-primitive": "2.0.0",
+ "@radix-ui/react-primitive": "2.0.1",
"@radix-ui/react-use-layout-effect": "1.1.0"
},
"peerDependencies": {
@@ -9989,13 +12800,13 @@
}
}
},
- "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-presence": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.0.tgz",
- "integrity": "sha512-Gq6wuRN/asf9H/E/VzdKoUtT8GC9PQc9z40/vEr0VCJ4u5XvvhWIrSsCB6vD2/cH7ugTdSfYq9fLJCcM00acrQ==",
+ "node_modules/@radix-ui/react-toast/node_modules/@radix-ui/react-presence": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.2.tgz",
+ "integrity": "sha512-18TFr80t5EVgL9x1SwF/YGtfG+l0BS0PRAlCWBDoBEiDQjeKgnNZRVJp/oVBl24sr3Gbfwc/Qpj4OcWTQMsAEg==",
"license": "MIT",
"dependencies": {
- "@radix-ui/react-compose-refs": "1.1.0",
+ "@radix-ui/react-compose-refs": "1.1.1",
"@radix-ui/react-use-layout-effect": "1.1.0"
},
"peerDependencies": {
@@ -10013,13 +12824,13 @@
}
}
},
- "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-primitive": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.0.tgz",
- "integrity": "sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw==",
+ "node_modules/@radix-ui/react-toast/node_modules/@radix-ui/react-primitive": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.1.tgz",
+ "integrity": "sha512-sHCWTtxwNn3L3fH8qAfnF3WbUZycW93SM1j3NFDzXBiz8D6F5UTTy8G1+WFEaiCdvCVRJWj6N2R4Xq6HdiHmDg==",
"license": "MIT",
"dependencies": {
- "@radix-ui/react-slot": "1.1.0"
+ "@radix-ui/react-slot": "1.1.1"
},
"peerDependencies": {
"@types/react": "*",
@@ -10036,13 +12847,13 @@
}
}
},
- "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-slot": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.0.tgz",
- "integrity": "sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==",
+ "node_modules/@radix-ui/react-toast/node_modules/@radix-ui/react-slot": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.1.tgz",
+ "integrity": "sha512-RApLLOcINYJA+dMVbOju7MYv1Mb2EBp2nH4HdDzXTSyaR5optlm6Otrz1euW3HbdOR8UmmFK06TD+A9frYWv+g==",
"license": "MIT",
"dependencies": {
- "@radix-ui/react-compose-refs": "1.1.0"
+ "@radix-ui/react-compose-refs": "1.1.1"
},
"peerDependencies": {
"@types/react": "*",
@@ -10054,7 +12865,7 @@
}
}
},
- "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-use-callback-ref": {
+ "node_modules/@radix-ui/react-toast/node_modules/@radix-ui/react-use-callback-ref": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz",
"integrity": "sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==",
@@ -10069,7 +12880,7 @@
}
}
},
- "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-use-controllable-state": {
+ "node_modules/@radix-ui/react-toast/node_modules/@radix-ui/react-use-controllable-state": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.1.0.tgz",
"integrity": "sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==",
@@ -10087,7 +12898,7 @@
}
}
},
- "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-use-escape-keydown": {
+ "node_modules/@radix-ui/react-toast/node_modules/@radix-ui/react-use-escape-keydown": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.0.tgz",
"integrity": "sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw==",
@@ -10105,7 +12916,7 @@
}
}
},
- "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-use-layout-effect": {
+ "node_modules/@radix-ui/react-toast/node_modules/@radix-ui/react-use-layout-effect": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz",
"integrity": "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==",
@@ -10120,96 +12931,105 @@
}
}
},
- "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-use-rect": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.0.tgz",
- "integrity": "sha512-0Fmkebhr6PiseyZlYAOtLS+nb7jLmpqTrJyv61Pe68MKYW6OWdRE2kI70TaYY27u7H0lajqM3hSMMLFq18Z7nQ==",
+ "node_modules/@radix-ui/react-toast/node_modules/@radix-ui/react-visually-hidden": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.1.1.tgz",
+ "integrity": "sha512-vVfA2IZ9q/J+gEamvj761Oq1FpWgCDaNOOIfbPVp2MVPLEomUr5+Vf7kJGwQ24YxZSlQVar7Bes8kyTo5Dshpg==",
"license": "MIT",
"dependencies": {
- "@radix-ui/rect": "1.1.0"
+ "@radix-ui/react-primitive": "2.0.1"
},
"peerDependencies": {
"@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
}
}
},
- "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-use-size": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.0.tgz",
- "integrity": "sha512-XW3/vWuIXHa+2Uwcc2ABSfcCledmXhhQPlGbfcRXbiUQI5Icjcg19BGCZVKKInYbvUCut/ufbbLLPFC5cbb1hw==",
+ "node_modules/@radix-ui/react-toggle": {
+ "version": "1.1.9",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle/-/react-toggle-1.1.9.tgz",
+ "integrity": "sha512-ZoFkBBz9zv9GWer7wIjvdRxmh2wyc2oKWw6C6CseWd6/yq1DK/l5lJ+wnsmFwJZbBYqr02mrf8A2q/CVCuM3ZA==",
"license": "MIT",
"dependencies": {
- "@radix-ui/react-use-layout-effect": "1.1.0"
+ "@radix-ui/primitive": "1.1.2",
+ "@radix-ui/react-primitive": "2.1.3",
+ "@radix-ui/react-use-controllable-state": "1.2.2"
},
"peerDependencies": {
"@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
}
}
},
- "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/rect": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.0.tgz",
- "integrity": "sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg==",
- "license": "MIT"
- },
- "node_modules/@radix-ui/react-popover/node_modules/react-remove-scroll": {
- "version": "2.5.7",
- "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.7.tgz",
- "integrity": "sha512-FnrTWO4L7/Bhhf3CYBNArEG/yROV0tKmTv7/3h9QCFvH6sndeFf1wPqOcbFVu5VAulS5dV1wGT3GZZ/1GawqiA==",
+ "node_modules/@radix-ui/react-toggle-group": {
+ "version": "1.1.9",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle-group/-/react-toggle-group-1.1.9.tgz",
+ "integrity": "sha512-HJ6gXdYVN38q/5KDdCcd+JTuXUyFZBMJbwXaU/82/Gi+V2ps6KpiZ2sQecAeZCV80POGRfkUBdUIj6hIdF6/MQ==",
"license": "MIT",
"dependencies": {
- "react-remove-scroll-bar": "^2.3.4",
- "react-style-singleton": "^2.2.1",
- "tslib": "^2.1.0",
- "use-callback-ref": "^1.3.0",
- "use-sidecar": "^1.1.2"
- },
- "engines": {
- "node": ">=10"
+ "@radix-ui/primitive": "1.1.2",
+ "@radix-ui/react-context": "1.1.2",
+ "@radix-ui/react-direction": "1.1.1",
+ "@radix-ui/react-primitive": "2.1.2",
+ "@radix-ui/react-roving-focus": "1.1.9",
+ "@radix-ui/react-toggle": "1.1.8",
+ "@radix-ui/react-use-controllable-state": "1.2.2"
},
"peerDependencies": {
- "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0",
- "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
}
}
},
- "node_modules/@radix-ui/react-popper": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.1.3.tgz",
- "integrity": "sha512-cKpopj/5RHZWjrbF2846jBNacjQVwkP068DfmgrNJXpvVWrOvlAmE9xSiy5OqeE+Gi8D9fP+oDhUnPqNMY8/5w==",
+ "node_modules/@radix-ui/react-toggle-group/node_modules/@radix-ui/primitive": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.2.tgz",
+ "integrity": "sha512-XnbHrrprsNqZKQhStrSwgRUQzoCI1glLzdw79xiZPoofhGICeZRSQ3dIxAKH1gb3OHfNf4d6f+vAv3kil2eggA==",
+ "license": "MIT"
+ },
+ "node_modules/@radix-ui/react-toggle-group/node_modules/@radix-ui/react-collection": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.6.tgz",
+ "integrity": "sha512-PbhRFK4lIEw9ADonj48tiYWzkllz81TM7KVYyyMMw2cwHO7D5h4XKEblL8NlaRisTK3QTe6tBEhDccFUryxHBQ==",
"license": "MIT",
"dependencies": {
- "@babel/runtime": "^7.13.10",
- "@floating-ui/react-dom": "^2.0.0",
- "@radix-ui/react-arrow": "1.0.3",
- "@radix-ui/react-compose-refs": "1.0.1",
- "@radix-ui/react-context": "1.0.1",
- "@radix-ui/react-primitive": "1.0.3",
- "@radix-ui/react-use-callback-ref": "1.0.1",
- "@radix-ui/react-use-layout-effect": "1.0.1",
- "@radix-ui/react-use-rect": "1.0.1",
- "@radix-ui/react-use-size": "1.0.1",
- "@radix-ui/rect": "1.0.1"
+ "@radix-ui/react-compose-refs": "1.1.2",
+ "@radix-ui/react-context": "1.1.2",
+ "@radix-ui/react-primitive": "2.1.2",
+ "@radix-ui/react-slot": "1.2.2"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0",
- "react-dom": "^16.8 || ^17.0 || ^18.0"
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
@@ -10220,33 +13040,82 @@
}
}
},
- "node_modules/@radix-ui/react-popper/node_modules/@floating-ui/react-dom": {
- "version": "2.1.6",
- "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.6.tgz",
- "integrity": "sha512-4JX6rEatQEvlmgU80wZyq9RT96HZJa88q8hp0pBd+LrczeDI4o6uA2M+uvxngVHo4Ihr8uibXxH6+70zhAFrVw==",
+ "node_modules/@radix-ui/react-toggle-group/node_modules/@radix-ui/react-compose-refs": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz",
+ "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-toggle-group/node_modules/@radix-ui/react-context": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.2.tgz",
+ "integrity": "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-toggle-group/node_modules/@radix-ui/react-direction": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.1.tgz",
+ "integrity": "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-toggle-group/node_modules/@radix-ui/react-id": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.1.tgz",
+ "integrity": "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==",
"license": "MIT",
"dependencies": {
- "@floating-ui/dom": "^1.7.4"
+ "@radix-ui/react-use-layout-effect": "1.1.1"
},
"peerDependencies": {
- "react": ">=16.8.0",
- "react-dom": ">=16.8.0"
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
}
},
- "node_modules/@radix-ui/react-portal": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.0.4.tgz",
- "integrity": "sha512-Qki+C/EuGUVCQTOTD5vzJzJuMUlewbzuKyUy+/iHM2uwGiru9gZeBJtHAPKAEkB5KWGi9mP/CHKcY0wt1aW45Q==",
+ "node_modules/@radix-ui/react-toggle-group/node_modules/@radix-ui/react-primitive": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.2.tgz",
+ "integrity": "sha512-uHa+l/lKfxuDD2zjN/0peM/RhhSmRjr5YWdk/37EnSv1nJ88uvG85DPexSm8HdFQROd2VdERJ6ynXbkCFi+APw==",
"license": "MIT",
"dependencies": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/react-primitive": "1.0.3"
+ "@radix-ui/react-slot": "1.2.2"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0",
- "react-dom": "^16.8 || ^17.0 || ^18.0"
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
@@ -10257,21 +13126,27 @@
}
}
},
- "node_modules/@radix-ui/react-presence": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.0.1.tgz",
- "integrity": "sha512-UXLW4UAbIY5ZjcvzjfRFo5gxva8QirC9hF7wRE4U5gz+TP0DbRk+//qyuAQ1McDxBt1xNMBTaciFGvEmJvAZCg==",
+ "node_modules/@radix-ui/react-toggle-group/node_modules/@radix-ui/react-roving-focus": {
+ "version": "1.1.9",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.9.tgz",
+ "integrity": "sha512-ZzrIFnMYHHCNqSNCsuN6l7wlewBEq0O0BCSBkabJMFXVO51LRUTq71gLP1UxFvmrXElqmPjA5VX7IqC9VpazAQ==",
"license": "MIT",
"dependencies": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/react-compose-refs": "1.0.1",
- "@radix-ui/react-use-layout-effect": "1.0.1"
+ "@radix-ui/primitive": "1.1.2",
+ "@radix-ui/react-collection": "1.1.6",
+ "@radix-ui/react-compose-refs": "1.1.2",
+ "@radix-ui/react-context": "1.1.2",
+ "@radix-ui/react-direction": "1.1.1",
+ "@radix-ui/react-id": "1.1.1",
+ "@radix-ui/react-primitive": "2.1.2",
+ "@radix-ui/react-use-callback-ref": "1.1.1",
+ "@radix-ui/react-use-controllable-state": "1.2.2"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0",
- "react-dom": "^16.8 || ^17.0 || ^18.0"
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
@@ -10282,20 +13157,39 @@
}
}
},
- "node_modules/@radix-ui/react-primitive": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-1.0.3.tgz",
- "integrity": "sha512-yi58uVyoAcK/Nq1inRY56ZSjKypBNKTa/1mcL8qdl6oJeEaDbOldlzrGn7P6Q3Id5d+SYNGc5AJgc4vGhjs5+g==",
+ "node_modules/@radix-ui/react-toggle-group/node_modules/@radix-ui/react-slot": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.2.tgz",
+ "integrity": "sha512-y7TBO4xN4Y94FvcWIOIh18fM4R1A8S4q1jhoz4PNzOoHsFcN8pogcFmZrTYAm4F9VRUrWP/Mw7xSKybIeRI+CQ==",
"license": "MIT",
"dependencies": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/react-slot": "1.0.2"
+ "@radix-ui/react-compose-refs": "1.1.2"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-toggle-group/node_modules/@radix-ui/react-toggle": {
+ "version": "1.1.8",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle/-/react-toggle-1.1.8.tgz",
+ "integrity": "sha512-hrpa59m3zDnsa35LrTOH5s/a3iGv/VD+KKQjjiCTo/W4r0XwPpiWQvAv6Xl1nupSoaZeNNxW6sJH9ZydsjKdYQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.1.2",
+ "@radix-ui/react-primitive": "2.1.2",
+ "@radix-ui/react-use-controllable-state": "1.2.2"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0",
- "react-dom": "^16.8 || ^17.0 || ^18.0"
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
@@ -10306,28 +13200,89 @@
}
}
},
- "node_modules/@radix-ui/react-roving-focus": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.0.4.tgz",
- "integrity": "sha512-2mUg5Mgcu001VkGy+FfzZyzbmuUWzgWkj3rvv4yu+mLw03+mTzbxZHvfcGyFp2b8EkQeMkpRQ5FiA2Vr2O6TeQ==",
+ "node_modules/@radix-ui/react-toggle-group/node_modules/@radix-ui/react-use-callback-ref": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.1.tgz",
+ "integrity": "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-toggle-group/node_modules/@radix-ui/react-use-controllable-state": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.2.tgz",
+ "integrity": "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==",
"license": "MIT",
"dependencies": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/primitive": "1.0.1",
- "@radix-ui/react-collection": "1.0.3",
- "@radix-ui/react-compose-refs": "1.0.1",
- "@radix-ui/react-context": "1.0.1",
- "@radix-ui/react-direction": "1.0.1",
- "@radix-ui/react-id": "1.0.1",
- "@radix-ui/react-primitive": "1.0.3",
- "@radix-ui/react-use-callback-ref": "1.0.1",
- "@radix-ui/react-use-controllable-state": "1.0.1"
+ "@radix-ui/react-use-effect-event": "0.0.2",
+ "@radix-ui/react-use-layout-effect": "1.1.1"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-toggle-group/node_modules/@radix-ui/react-use-layout-effect": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.1.tgz",
+ "integrity": "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-toggle/node_modules/@radix-ui/primitive": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.2.tgz",
+ "integrity": "sha512-XnbHrrprsNqZKQhStrSwgRUQzoCI1glLzdw79xiZPoofhGICeZRSQ3dIxAKH1gb3OHfNf4d6f+vAv3kil2eggA==",
+ "license": "MIT"
+ },
+ "node_modules/@radix-ui/react-toggle/node_modules/@radix-ui/react-compose-refs": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz",
+ "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-toggle/node_modules/@radix-ui/react-primitive": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz",
+ "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-slot": "1.2.3"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0",
- "react-dom": "^16.8 || ^17.0 || ^18.0"
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
@@ -10338,18 +13293,51 @@
}
}
},
- "node_modules/@radix-ui/react-slot": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.2.tgz",
- "integrity": "sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg==",
+ "node_modules/@radix-ui/react-toggle/node_modules/@radix-ui/react-slot": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz",
+ "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==",
"license": "MIT",
"dependencies": {
- "@babel/runtime": "^7.13.10",
- "@radix-ui/react-compose-refs": "1.0.1"
+ "@radix-ui/react-compose-refs": "1.1.2"
},
"peerDependencies": {
"@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0"
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-toggle/node_modules/@radix-ui/react-use-controllable-state": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.2.tgz",
+ "integrity": "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-use-effect-event": "0.0.2",
+ "@radix-ui/react-use-layout-effect": "1.1.1"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-toggle/node_modules/@radix-ui/react-use-layout-effect": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.1.tgz",
+ "integrity": "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
@@ -10429,6 +13417,39 @@
}
}
},
+ "node_modules/@radix-ui/react-use-effect-event": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.2.tgz",
+ "integrity": "sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==",
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-use-layout-effect": "1.1.1"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-use-effect-event/node_modules/@radix-ui/react-use-layout-effect": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.1.tgz",
+ "integrity": "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
"node_modules/@radix-ui/react-use-escape-keydown": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.0.3.tgz",
@@ -14218,6 +17239,62 @@
"node": ">=20.0.0"
}
},
+ "node_modules/@svgdotjs/svg.draggable.js": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/@svgdotjs/svg.draggable.js/-/svg.draggable.js-3.0.6.tgz",
+ "integrity": "sha512-7iJFm9lL3C40HQcqzEfezK2l+dW2CpoVY3b77KQGqc8GXWa6LhhmX5Ckv7alQfUXBuZbjpICZ+Dvq1czlGx7gA==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@svgdotjs/svg.js": "^3.2.4"
+ }
+ },
+ "node_modules/@svgdotjs/svg.filter.js": {
+ "version": "3.0.9",
+ "resolved": "https://registry.npmjs.org/@svgdotjs/svg.filter.js/-/svg.filter.js-3.0.9.tgz",
+ "integrity": "sha512-/69XMRCDoam2HgC4ldHIaDgeQf1ViHIsa0Ld4uWgiXtZ+E24DWHe/9Ib6kbNiZ7WRIdlVokUDR1Fg0kjIpkfbw==",
+ "license": "MIT",
+ "dependencies": {
+ "@svgdotjs/svg.js": "^3.2.4"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/@svgdotjs/svg.js": {
+ "version": "3.2.5",
+ "resolved": "https://registry.npmjs.org/@svgdotjs/svg.js/-/svg.js-3.2.5.tgz",
+ "integrity": "sha512-/VNHWYhNu+BS7ktbYoVGrCmsXDh+chFMaONMwGNdIBcFHrWqk2jY8fNyr3DLdtQUIalvkPfM554ZSFa3dm3nxQ==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/Fuzzyma"
+ }
+ },
+ "node_modules/@svgdotjs/svg.resize.js": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@svgdotjs/svg.resize.js/-/svg.resize.js-2.0.5.tgz",
+ "integrity": "sha512-4heRW4B1QrJeENfi7326lUPYBCevj78FJs8kfeDxn5st0IYPIRXoTtOSYvTzFWgaWWXd3YCDE6ao4fmv91RthA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 14.18"
+ },
+ "peerDependencies": {
+ "@svgdotjs/svg.js": "^3.2.4",
+ "@svgdotjs/svg.select.js": "^4.0.1"
+ }
+ },
+ "node_modules/@svgdotjs/svg.select.js": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/@svgdotjs/svg.select.js/-/svg.select.js-4.0.3.tgz",
+ "integrity": "sha512-qkMgso1sd2hXKd1FZ1weO7ANq12sNmQJeGDjs46QwDVsxSRcHmvWKL2NDF7Yimpwf3sl5esOLkPqtV2bQ3v/Jg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 14.18"
+ },
+ "peerDependencies": {
+ "@svgdotjs/svg.js": "^3.2.4"
+ }
+ },
"node_modules/@swagger-api/apidom-ast": {
"version": "1.0.0-rc.3",
"resolved": "https://registry.npmjs.org/@swagger-api/apidom-ast/-/apidom-ast-1.0.0-rc.3.tgz",
@@ -14836,6 +17913,65 @@
"tailwindcss": ">=3.2.0"
}
},
+ "node_modules/@tanstack/query-core": {
+ "version": "5.69.0",
+ "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.69.0.tgz",
+ "integrity": "sha512-Kn410jq6vs1P8Nm+ZsRj9H+U3C0kjuEkYLxbiCyn3MDEiYor1j2DGVULqAz62SLZtUZ/e9Xt6xMXiJ3NJ65WyQ==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/tannerlinsley"
+ }
+ },
+ "node_modules/@tanstack/react-query": {
+ "version": "5.69.0",
+ "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.69.0.tgz",
+ "integrity": "sha512-Ift3IUNQqTcaFa1AiIQ7WCb/PPy8aexZdq9pZWLXhfLcLxH0+PZqJ2xFImxCpdDZrFRZhLJrh76geevS5xjRhA==",
+ "license": "MIT",
+ "dependencies": {
+ "@tanstack/query-core": "5.69.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/tannerlinsley"
+ },
+ "peerDependencies": {
+ "react": "^18 || ^19"
+ }
+ },
+ "node_modules/@tanstack/react-table": {
+ "version": "8.20.5",
+ "resolved": "https://registry.npmjs.org/@tanstack/react-table/-/react-table-8.20.5.tgz",
+ "integrity": "sha512-WEHopKw3znbUZ61s9i0+i9g8drmDo6asTWbrQh8Us63DAk/M0FkmIqERew6P71HI75ksZ2Pxyuf4vvKh9rAkiA==",
+ "license": "MIT",
+ "dependencies": {
+ "@tanstack/table-core": "8.20.5"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/tannerlinsley"
+ },
+ "peerDependencies": {
+ "react": ">=16.8",
+ "react-dom": ">=16.8"
+ }
+ },
+ "node_modules/@tanstack/table-core": {
+ "version": "8.20.5",
+ "resolved": "https://registry.npmjs.org/@tanstack/table-core/-/table-core-8.20.5.tgz",
+ "integrity": "sha512-P9dF7XbibHph2PFRz8gfBKEXEY/HJPOhym8CHmjF8y3q5mWpKx9xtZapXQUWCgkqvsK0R46Azuz+VaxD4Xl+Tg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/tannerlinsley"
+ }
+ },
"node_modules/@tybys/wasm-util": {
"version": "0.10.1",
"resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz",
@@ -16136,12 +19272,62 @@
"node": ">=16"
}
},
+ "node_modules/@wry/caches": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@wry/caches/-/caches-1.0.1.tgz",
+ "integrity": "sha512-bXuaUNLVVkD20wcGBWRyo7j9N3TxePEWFZj2Y+r9OoUzfqmavM84+mFykRicNsBqatba5JLay1t48wxaXaWnlA==",
+ "dependencies": {
+ "tslib": "^2.3.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@wry/context": {
+ "version": "0.7.4",
+ "resolved": "https://registry.npmjs.org/@wry/context/-/context-0.7.4.tgz",
+ "integrity": "sha512-jmT7Sb4ZQWI5iyu3lobQxICu2nC/vbUhP0vIdd6tHC9PTfenmRmuIFqktc6GH9cgi+ZHnsLWPvfSvc4DrYmKiQ==",
+ "dependencies": {
+ "tslib": "^2.3.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@wry/equality": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/@wry/equality/-/equality-0.5.7.tgz",
+ "integrity": "sha512-BRFORjsTuQv5gxcXsuDXx6oGRhuVsEGwZy6LOzRRfgu+eSfxbhUQ9L9YtSEIuIjY/o7g3iWFjrc5eSY1GXP2Dw==",
+ "dependencies": {
+ "tslib": "^2.3.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@wry/trie": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/@wry/trie/-/trie-0.5.0.tgz",
+ "integrity": "sha512-FNoYzHawTMk/6KMQoEG5O4PuioX19UbwdQKF44yw0nLfOypfQdjtfZzo/UIJWAJ23sNIFbD1Ug9lbaDGMwbqQA==",
+ "dependencies": {
+ "tslib": "^2.3.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/@yarnpkg/lockfile": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz",
"integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==",
"license": "BSD-2-Clause"
},
+ "node_modules/@yr/monotone-cubic-spline": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@yr/monotone-cubic-spline/-/monotone-cubic-spline-1.0.3.tgz",
+ "integrity": "sha512-FQXkOta0XBSUPHndIKON2Y9JeQz5ZeMqLYZVVK93FliNBFm7LNMIZmY6FrMEB9XPcDbE2bekMbZD6kzDkxwYjA==",
+ "license": "MIT"
+ },
"node_modules/@zksync/contracts": {
"name": "era-contracts",
"version": "0.1.0",
@@ -16488,6 +19674,20 @@
"node": ">= 8"
}
},
+ "node_modules/apexcharts": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/apexcharts/-/apexcharts-4.5.0.tgz",
+ "integrity": "sha512-E7ZkrVqPNBUWy/Rmg8DEIqHNBmElzICE/oxOX5Ekvs2ICQUOK/VkEkMH09JGJu+O/EA0NL31hxlmF+wrwrSLaQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@svgdotjs/svg.draggable.js": "^3.0.4",
+ "@svgdotjs/svg.filter.js": "^3.0.8",
+ "@svgdotjs/svg.js": "^3.2.4",
+ "@svgdotjs/svg.resize.js": "^2.0.2",
+ "@svgdotjs/svg.select.js": "^4.0.1",
+ "@yr/monotone-cubic-spline": "^1.0.3"
+ }
+ },
"node_modules/apg-lite": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/apg-lite/-/apg-lite-1.0.5.tgz",
@@ -17104,6 +20304,43 @@
"tslib": "^2.3.0"
}
},
+ "node_modules/autoprefixer": {
+ "version": "10.4.21",
+ "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.21.tgz",
+ "integrity": "sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/autoprefixer"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "browserslist": "^4.24.4",
+ "caniuse-lite": "^1.0.30001702",
+ "fraction.js": "^4.3.7",
+ "normalize-range": "^0.1.2",
+ "picocolors": "^1.1.1",
+ "postcss-value-parser": "^4.2.0"
+ },
+ "bin": {
+ "autoprefixer": "bin/autoprefixer"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ },
+ "peerDependencies": {
+ "postcss": "^8.1.0"
+ }
+ },
"node_modules/available-typed-arrays": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz",
@@ -21254,6 +24491,19 @@
"node": ">=18.3.0"
}
},
+ "node_modules/fraction.js": {
+ "version": "4.3.7",
+ "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz",
+ "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==",
+ "license": "MIT",
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "type": "patreon",
+ "url": "https://github.com/sponsors/rawify"
+ }
+ },
"node_modules/fresh": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
@@ -21657,6 +24907,29 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/graphql": {
+ "version": "16.12.0",
+ "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.12.0.tgz",
+ "integrity": "sha512-DKKrynuQRne0PNpEbzuEdHlYOMksHSUI8Zc9Unei5gTsMNA2/vMpoMz/yKba50pejK56qj98qM0SjYxAKi13gQ==",
+ "peer": true,
+ "engines": {
+ "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0"
+ }
+ },
+ "node_modules/graphql-tag": {
+ "version": "2.12.6",
+ "resolved": "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.12.6.tgz",
+ "integrity": "sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg==",
+ "dependencies": {
+ "tslib": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "graphql": "^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0"
+ }
+ },
"node_modules/h3": {
"version": "1.15.4",
"resolved": "https://registry.npmjs.org/h3/-/h3-1.15.4.tgz",
@@ -22341,6 +25614,19 @@
"node": "*"
}
},
+ "node_modules/hoist-non-react-statics": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
+ "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
+ "dependencies": {
+ "react-is": "^16.7.0"
+ }
+ },
+ "node_modules/hoist-non-react-statics/node_modules/react-is": {
+ "version": "16.13.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
+ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
+ },
"node_modules/htm": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/htm/-/htm-3.1.1.tgz",
@@ -29899,6 +33185,15 @@
"node": ">=0.10.0"
}
},
+ "node_modules/normalize-range": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
+ "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/normalize-url": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.1.0.tgz",
@@ -30234,6 +33529,17 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/optimism": {
+ "version": "0.18.1",
+ "resolved": "https://registry.npmjs.org/optimism/-/optimism-0.18.1.tgz",
+ "integrity": "sha512-mLXNwWPa9dgFyDqkNi54sjDyNJ9/fTI6WGBLgnXku1vdKY/jovHfZT5r+aiVeFFLOz+foPNOm5YJ4mqgld2GBQ==",
+ "dependencies": {
+ "@wry/caches": "^1.0.0",
+ "@wry/context": "^0.7.0",
+ "@wry/trie": "^0.5.0",
+ "tslib": "^2.3.0"
+ }
+ },
"node_modules/optionator": {
"version": "0.9.4",
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
@@ -31259,6 +34565,34 @@
"node": "^14.15.0 || >=16.0.0"
}
},
+ "node_modules/prettier-plugin-solidity": {
+ "version": "1.4.3",
+ "resolved": "https://registry.npmjs.org/prettier-plugin-solidity/-/prettier-plugin-solidity-1.4.3.tgz",
+ "integrity": "sha512-Mrr/iiR9f9IaeGRMZY2ApumXcn/C5Gs3S7B7hWB3gigBFML06C0yEyW86oLp0eqiA0qg+46FaChgLPJCj/pIlg==",
+ "dev": true,
+ "dependencies": {
+ "@solidity-parser/parser": "^0.20.1",
+ "semver": "^7.7.1"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "prettier": ">=2.3.0"
+ }
+ },
+ "node_modules/prettier-plugin-solidity/node_modules/semver": {
+ "version": "7.7.3",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
+ "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/pretty-format": {
"version": "29.7.0",
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz",
@@ -31726,6 +35060,19 @@
"node": ">=0.10.0"
}
},
+ "node_modules/react-apexcharts": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/react-apexcharts/-/react-apexcharts-1.7.0.tgz",
+ "integrity": "sha512-03oScKJyNLRf0Oe+ihJxFZliBQM9vW3UWwomVn4YVRTN1jsIR58dLWt0v1sb8RwJVHDMbeHiKQueM0KGpn7nOA==",
+ "license": "MIT",
+ "dependencies": {
+ "prop-types": "^15.8.1"
+ },
+ "peerDependencies": {
+ "apexcharts": ">=4.0.0",
+ "react": ">=0.13"
+ }
+ },
"node_modules/react-copy-to-clipboard": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/react-copy-to-clipboard/-/react-copy-to-clipboard-5.1.0.tgz",
@@ -31798,6 +35145,22 @@
"react": "^18.3.1"
}
},
+ "node_modules/react-hook-form": {
+ "version": "7.53.1",
+ "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.53.1.tgz",
+ "integrity": "sha512-6aiQeBda4zjcuaugWvim9WsGqisoUk+etmFEsSUMm451/Ic8L/UAb7sRtMj3V+Hdzm6mMjU1VhiSzYUZeBm0Vg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/react-hook-form"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17 || ^18 || ^19"
+ }
+ },
"node_modules/react-immutable-proptypes": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/react-immutable-proptypes/-/react-immutable-proptypes-2.2.0.tgz",
@@ -32430,6 +35793,23 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/rehackt": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/rehackt/-/rehackt-0.1.0.tgz",
+ "integrity": "sha512-7kRDOuLHB87D/JESKxQoRwv4DzbIdwkAGQ7p6QKGdVlY1IZheUnVhlk/4UZlNUVxdAXpyxikE3URsG067ybVzw==",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "*"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "react": {
+ "optional": true
+ }
+ }
+ },
"node_modules/rehype": {
"version": "13.0.2",
"resolved": "https://registry.npmjs.org/rehype/-/rehype-13.0.2.tgz",
@@ -33287,7 +36667,8 @@
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz",
"integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==",
- "license": "MIT"
+ "license": "MIT",
+ "peer": true
},
"node_modules/search-insights": {
"version": "2.17.3",
@@ -33921,6 +37302,20 @@
"resolved": "git+ssh://git@github.com/smartcontractkit/chainlink-solhint-rules.git#2f0a3a6c3475607bb0cf8ab1a1df979534453ba9",
"dev": true
},
+ "node_modules/solhint-plugin-prettier": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/solhint-plugin-prettier/-/solhint-plugin-prettier-0.1.0.tgz",
+ "integrity": "sha512-SDOTSM6tZxZ6hamrzl3GUgzF77FM6jZplgL2plFBclj/OjKP8Z3eIPojKU73gRr0MvOS8ACZILn8a5g0VTz/Gw==",
+ "dev": true,
+ "dependencies": {
+ "@prettier/sync": "^0.3.0",
+ "prettier-linter-helpers": "^1.0.0"
+ },
+ "peerDependencies": {
+ "prettier": "^3.0.0",
+ "prettier-plugin-solidity": "^1.0.0"
+ }
+ },
"node_modules/solhint/node_modules/ajv": {
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
@@ -34038,6 +37433,16 @@
"atomic-sleep": "^1.0.0"
}
},
+ "node_modules/sonner": {
+ "version": "1.7.3",
+ "resolved": "https://registry.npmjs.org/sonner/-/sonner-1.7.3.tgz",
+ "integrity": "sha512-KXLWQfyR6AHpYZuQk8eO8fCbZSJY3JOpgsu/tbGc++jgPjj8JsR1ZpO8vFhqR/OxvWMQCSAmnSShY0gr4FPqHg==",
+ "license": "MIT",
+ "peerDependencies": {
+ "react": "^18.0.0 || ^19.0.0 || ^19.0.0-rc",
+ "react-dom": "^18.0.0 || ^19.0.0 || ^19.0.0-rc"
+ }
+ },
"node_modules/source-map": {
"version": "0.7.6",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz",
@@ -34706,6 +38111,14 @@
"@types/trusted-types": "^2.0.7"
}
},
+ "node_modules/symbol-observable": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-4.0.0.tgz",
+ "integrity": "sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==",
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
"node_modules/synckit": {
"version": "0.11.11",
"resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.11.tgz",
@@ -34809,33 +38222,33 @@
}
},
"node_modules/tailwindcss": {
- "version": "3.4.4",
- "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.4.tgz",
- "integrity": "sha512-ZoyXOdJjISB7/BcLTR6SEsLgKtDStYyYZVLsUtWChO4Ps20CBad7lfJKVDiejocV4ME1hLmyY0WJE3hSDcmQ2A==",
+ "version": "3.4.18",
+ "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.18.tgz",
+ "integrity": "sha512-6A2rnmW5xZMdw11LYjhcI5846rt9pbLSabY5XPxo+XWdxwZaFEn47Go4NzFiHu9sNNmr/kXivP1vStfvMaK1GQ==",
"license": "MIT",
"dependencies": {
"@alloc/quick-lru": "^5.2.0",
"arg": "^5.0.2",
- "chokidar": "^3.5.3",
+ "chokidar": "^3.6.0",
"didyoumean": "^1.2.2",
"dlv": "^1.1.3",
- "fast-glob": "^3.3.0",
+ "fast-glob": "^3.3.2",
"glob-parent": "^6.0.2",
"is-glob": "^4.0.3",
- "jiti": "^1.21.0",
- "lilconfig": "^2.1.0",
- "micromatch": "^4.0.5",
+ "jiti": "^1.21.7",
+ "lilconfig": "^3.1.3",
+ "micromatch": "^4.0.8",
"normalize-path": "^3.0.0",
"object-hash": "^3.0.0",
- "picocolors": "^1.0.0",
- "postcss": "^8.4.23",
+ "picocolors": "^1.1.1",
+ "postcss": "^8.4.47",
"postcss-import": "^15.1.0",
"postcss-js": "^4.0.1",
- "postcss-load-config": "^4.0.1",
- "postcss-nested": "^6.0.1",
- "postcss-selector-parser": "^6.0.11",
- "resolve": "^1.22.2",
- "sucrase": "^3.32.0"
+ "postcss-load-config": "^4.0.2 || ^5.0 || ^6.0",
+ "postcss-nested": "^6.2.0",
+ "postcss-selector-parser": "^6.1.2",
+ "resolve": "^1.22.8",
+ "sucrase": "^3.35.0"
},
"bin": {
"tailwind": "lib/cli.js",
@@ -34854,6 +38267,19 @@
"tailwindcss": ">=3.0.0 || insiders"
}
},
+ "node_modules/tailwindcss/node_modules/chokidar/node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "extraneous": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
"node_modules/tailwindcss/node_modules/jiti": {
"version": "1.21.7",
"resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz",
@@ -34863,13 +38289,32 @@
"jiti": "bin/jiti.js"
}
},
- "node_modules/tailwindcss/node_modules/lilconfig": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz",
- "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==",
+ "node_modules/tailwindcss/node_modules/postcss": {
+ "version": "8.5.6",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
+ "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
"license": "MIT",
+ "dependencies": {
+ "nanoid": "^3.3.11",
+ "picocolors": "^1.1.1",
+ "source-map-js": "^1.2.1"
+ },
"engines": {
- "node": ">=10"
+ "node": "^10 || ^12 || >=14"
}
},
"node_modules/tar": {
@@ -35251,6 +38696,17 @@
"integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==",
"license": "Apache-2.0"
},
+ "node_modules/ts-invariant": {
+ "version": "0.10.3",
+ "resolved": "https://registry.npmjs.org/ts-invariant/-/ts-invariant-0.10.3.tgz",
+ "integrity": "sha512-uivwYcQaxAucv1CzRp2n/QdYPo4ILf9VXgH19zEIjFx2EJufV16P0JtJVpYHy89DItG6Kwj2oIUjrcK5au+4tQ==",
+ "dependencies": {
+ "tslib": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/ts-jest": {
"version": "29.4.6",
"resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.4.6.tgz",
@@ -37253,6 +40709,19 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/zen-observable": {
+ "version": "0.8.15",
+ "resolved": "https://registry.npmjs.org/zen-observable/-/zen-observable-0.8.15.tgz",
+ "integrity": "sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ=="
+ },
+ "node_modules/zen-observable-ts": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/zen-observable-ts/-/zen-observable-ts-1.2.5.tgz",
+ "integrity": "sha512-QZWQekv6iB72Naeake9hS1KxHlotfRpe+WGNbNx5/ta+R3DNjVO2bswf63gXlWDcs+EMd7XY8HfVQyP1X6T4Zg==",
+ "dependencies": {
+ "zen-observable": "0.8.15"
+ }
+ },
"node_modules/zenscroll": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/zenscroll/-/zenscroll-4.0.2.tgz",
diff --git a/package.json b/package.json
index 04bab6311b8..717078aeac6 100644
--- a/package.json
+++ b/package.json
@@ -55,6 +55,8 @@
},
"dependencies": {
"@11ty/eleventy-fetch": "^4.0.1",
+ "@algolia/client-search": "^5.41.0",
+ "@apollo/client": "^3.14.0",
"@astro-community/astro-embed-youtube": "^0.5.9",
"@astrojs/mdx": "^4.3.12",
"@astrojs/partytown": "^2.1.4",
@@ -62,6 +64,8 @@
"@astrojs/prism": "^3.3.0",
"@astrojs/react": "^4.4.2",
"@astrojs/sitemap": "^3.6.0",
+ "@astrojs/tailwind": "^6.0.2",
+ "@chainlink/blocks": "^1.3.1",
"@astrojs/vercel": "^8.2.11",
"@chainlink/cl-search-frontend": "^0.12.1",
"@chainlink/components": "^0.4.18",
@@ -149,6 +153,9 @@
"remark-stringify": "^11.0.0",
"solhint": "^6.0.1",
"solhint-plugin-chainlink-solidity": "github:smartcontractkit/chainlink-solhint-rules#v1.3.0",
+ "prettier-plugin-solidity": "^1.4.3",
+ "solhint-plugin-prettier": "^0.1.0",
+ "tailwindcss": "^3.4.18",
"ts-jest": "^29.4.6",
"tsconfig-paths": "^4.2.0",
"tsx": "^4.21.0",
diff --git a/public/assets/icons/Arrow Right.svg b/public/assets/icons/Arrow Right.svg
new file mode 100644
index 00000000000..c73460f5326
--- /dev/null
+++ b/public/assets/icons/Arrow Right.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/public/assets/icons/add.svg b/public/assets/icons/add.svg
new file mode 100644
index 00000000000..6a3c331c298
--- /dev/null
+++ b/public/assets/icons/add.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/public/assets/icons/generic-verifier.svg b/public/assets/icons/generic-verifier.svg
new file mode 100644
index 00000000000..275f1c8400c
--- /dev/null
+++ b/public/assets/icons/generic-verifier.svg
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/public/assets/icons/upper-right-arrow.svg b/public/assets/icons/upper-right-arrow.svg
new file mode 100644
index 00000000000..7f588a0dcbd
--- /dev/null
+++ b/public/assets/icons/upper-right-arrow.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/public/images/architecture.png b/public/images/architecture.png
new file mode 100644
index 00000000000..076b0418e4f
Binary files /dev/null and b/public/images/architecture.png differ
diff --git a/public/images/ccip-logo.svg b/public/images/ccip-logo.svg
new file mode 100644
index 00000000000..79f05e8a605
--- /dev/null
+++ b/public/images/ccip-logo.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/public/images/ccip/ccip-hero-bg.png b/public/images/ccip/ccip-hero-bg.png
new file mode 100644
index 00000000000..5f3bc5df559
Binary files /dev/null and b/public/images/ccip/ccip-hero-bg.png differ
diff --git a/public/images/ccip/ccip-hero.png b/public/images/ccip/ccip-hero.png
new file mode 100644
index 00000000000..306b8cb3ed3
Binary files /dev/null and b/public/images/ccip/ccip-hero.png differ
diff --git a/public/images/certification/Imagedevhubresources.png b/public/images/certification/Imagedevhubresources.png
new file mode 100644
index 00000000000..fb41186977b
Binary files /dev/null and b/public/images/certification/Imagedevhubresources.png differ
diff --git a/public/images/certification/Imagedevhubvideo.png b/public/images/certification/Imagedevhubvideo.png
new file mode 100644
index 00000000000..259ea7d8d4f
Binary files /dev/null and b/public/images/certification/Imagedevhubvideo.png differ
diff --git a/public/images/certification/Tailless--Arrow-Down.svg b/public/images/certification/Tailless--Arrow-Down.svg
new file mode 100644
index 00000000000..2a3ca0873aa
--- /dev/null
+++ b/public/images/certification/Tailless--Arrow-Down.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/public/images/certification/image-1.png b/public/images/certification/image-1.png
new file mode 100644
index 00000000000..850eff21ee0
Binary files /dev/null and b/public/images/certification/image-1.png differ
diff --git a/public/images/certification/image-200.png b/public/images/certification/image-200.png
new file mode 100644
index 00000000000..dcf069cc5e1
Binary files /dev/null and b/public/images/certification/image-200.png differ
diff --git a/public/images/certification/image-201.png b/public/images/certification/image-201.png
new file mode 100644
index 00000000000..5975fc2082d
Binary files /dev/null and b/public/images/certification/image-201.png differ
diff --git a/public/images/certification/image-certificate.svg b/public/images/certification/image-certificate.svg
new file mode 100644
index 00000000000..6ba2805de44
--- /dev/null
+++ b/public/images/certification/image-certificate.svg
@@ -0,0 +1,248 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/public/images/certification/image-learnings.svg b/public/images/certification/image-learnings.svg
new file mode 100644
index 00000000000..4d6df7915c3
--- /dev/null
+++ b/public/images/certification/image-learnings.svg
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/public/images/code-sample.png b/public/images/code-sample.png
new file mode 100644
index 00000000000..89aa34475df
Binary files /dev/null and b/public/images/code-sample.png differ
diff --git a/public/images/demos/Demos thumbnails 1.png b/public/images/demos/Demos thumbnails 1.png
new file mode 100644
index 00000000000..ac2841680bd
Binary files /dev/null and b/public/images/demos/Demos thumbnails 1.png differ
diff --git a/public/images/demos/Demos thumbnails 2.png b/public/images/demos/Demos thumbnails 2.png
new file mode 100644
index 00000000000..a5b86705672
Binary files /dev/null and b/public/images/demos/Demos thumbnails 2.png differ
diff --git a/public/images/demos/Demos thumbnails 3.png b/public/images/demos/Demos thumbnails 3.png
new file mode 100644
index 00000000000..ab5a48f2b63
Binary files /dev/null and b/public/images/demos/Demos thumbnails 3.png differ
diff --git a/public/images/demos/Demos thumbnails 4.png b/public/images/demos/Demos thumbnails 4.png
new file mode 100644
index 00000000000..da2a2a0a583
Binary files /dev/null and b/public/images/demos/Demos thumbnails 4.png differ
diff --git a/public/images/direct-stacking-logo.svg b/public/images/direct-stacking-logo.svg
new file mode 100644
index 00000000000..1814e384a6a
--- /dev/null
+++ b/public/images/direct-stacking-logo.svg
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/public/images/foundry-logo.svg b/public/images/foundry-logo.svg
new file mode 100644
index 00000000000..2315253caf3
--- /dev/null
+++ b/public/images/foundry-logo.svg
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/public/images/hardhat-logo.svg b/public/images/hardhat-logo.svg
new file mode 100644
index 00000000000..6077c84afae
--- /dev/null
+++ b/public/images/hardhat-logo.svg
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/public/images/hero-1.png b/public/images/hero-1.png
new file mode 100644
index 00000000000..f921b02c1ec
Binary files /dev/null and b/public/images/hero-1.png differ
diff --git a/public/images/hero-dotted.png b/public/images/hero-dotted.png
new file mode 100644
index 00000000000..fbcd97a909d
Binary files /dev/null and b/public/images/hero-dotted.png differ
diff --git a/public/images/info-sidebar-img.png b/public/images/info-sidebar-img.png
new file mode 100644
index 00000000000..44eadb5cfb2
Binary files /dev/null and b/public/images/info-sidebar-img.png differ
diff --git a/public/images/js-logo.svg b/public/images/js-logo.svg
new file mode 100644
index 00000000000..a4baee9a679
--- /dev/null
+++ b/public/images/js-logo.svg
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/public/images/npm-logo.png b/public/images/npm-logo.png
new file mode 100644
index 00000000000..481f9493e8d
Binary files /dev/null and b/public/images/npm-logo.png differ
diff --git a/public/images/tryitout.png b/public/images/tryitout.png
new file mode 100644
index 00000000000..330416da8c9
Binary files /dev/null and b/public/images/tryitout.png differ
diff --git a/public/images/ts-logo.svg b/public/images/ts-logo.svg
new file mode 100644
index 00000000000..047caf543cc
--- /dev/null
+++ b/public/images/ts-logo.svg
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/src/assets/icons/remix-logo.svg b/src/assets/icons/remix-logo.svg
new file mode 100644
index 00000000000..4580f3bf83b
--- /dev/null
+++ b/src/assets/icons/remix-logo.svg
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/icons/token-icon.svg b/src/assets/icons/token-icon.svg
new file mode 100644
index 00000000000..2b8c333d430
--- /dev/null
+++ b/src/assets/icons/token-icon.svg
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/product-logos/automated-compliance-engine.svg b/src/assets/product-logos/automated-compliance-engine.svg
new file mode 100644
index 00000000000..e786648eddd
--- /dev/null
+++ b/src/assets/product-logos/automated-compliance-engine.svg
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/src/assets/product-logos/chainlink-local-2-logo.svg b/src/assets/product-logos/chainlink-local-2-logo.svg
new file mode 100644
index 00000000000..f3a6360b201
--- /dev/null
+++ b/src/assets/product-logos/chainlink-local-2-logo.svg
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/src/assets/product-logos/data-link-vault.svg b/src/assets/product-logos/data-link-vault.svg
new file mode 100644
index 00000000000..292b03b63a5
--- /dev/null
+++ b/src/assets/product-logos/data-link-vault.svg
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/product-logos/general-globe-logo.svg b/src/assets/product-logos/general-globe-logo.svg
new file mode 100644
index 00000000000..11804ee8b1e
--- /dev/null
+++ b/src/assets/product-logos/general-globe-logo.svg
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/src/assets/product-logos/nodes-logo.svg b/src/assets/product-logos/nodes-logo.svg
new file mode 100644
index 00000000000..016dae52333
--- /dev/null
+++ b/src/assets/product-logos/nodes-logo.svg
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/CCIP/AddButton/AddButton.astro b/src/components/CCIP/AddButton/AddButton.astro
new file mode 100644
index 00000000000..f2ade415216
--- /dev/null
+++ b/src/components/CCIP/AddButton/AddButton.astro
@@ -0,0 +1,42 @@
+---
+export interface Props {
+ href: string
+ text: string
+}
+
+const { href, text } = Astro.props
+---
+
+
+
+ {text}
+
+
+
diff --git a/src/components/CCIP/Cards/Card.css b/src/components/CCIP/Cards/Card.css
new file mode 100644
index 00000000000..bb77dae5555
--- /dev/null
+++ b/src/components/CCIP/Cards/Card.css
@@ -0,0 +1,40 @@
+.card__container {
+ display: flex;
+ padding: var(--space-6x);
+ gap: var(--space-3x);
+ width: 100%;
+ background: var(--white);
+ border: 1px solid var(--gray-200);
+ border-radius: var(--space-1x);
+ /* Optimize rendering performance */
+ contain: layout style paint;
+ will-change: background-color;
+}
+
+.card__container:hover {
+ background-color: var(--gray-50);
+}
+
+.card__container img,
+.card__container object,
+.card__container object img {
+ width: var(--space-10x);
+ height: var(--space-10x);
+ margin-top: auto;
+ margin-bottom: auto;
+}
+
+.card__container h3 {
+ font-size: var(--space-4x);
+ font-weight: var(--font-weight-medium);
+ line-height: var(--space-6x);
+ color: var(--gray-950);
+ margin-bottom: var(--space-1x);
+}
+
+.card__container p {
+ margin-bottom: 0;
+ font-size: var(--space-3x);
+ line-height: var(--space-5x);
+ color: var(--gray-500);
+}
diff --git a/src/components/CCIP/Cards/Card.tsx b/src/components/CCIP/Cards/Card.tsx
new file mode 100644
index 00000000000..669bd9155ff
--- /dev/null
+++ b/src/components/CCIP/Cards/Card.tsx
@@ -0,0 +1,43 @@
+import { memo, type ReactNode } from "react"
+import "./Card.css"
+
+interface CardProps {
+ logo: ReactNode
+ title: string
+ subtitle?: string
+ link?: string
+ onClick?: () => void
+ ariaLabel?: string
+}
+
+const Card = memo(function Card({ logo, title, subtitle, link, onClick, ariaLabel }: CardProps) {
+ const content = (
+ <>
+ {logo}
+
+
{title}
+ {subtitle &&
{subtitle}
}
+
+ >
+ )
+
+ if (link) {
+ return (
+
+ {content}
+
+ )
+ }
+
+ if (onClick) {
+ return (
+
+ {content}
+
+ )
+ }
+
+ return {content}
+})
+
+export default Card
diff --git a/src/components/CCIP/Cards/NetworkCard.tsx b/src/components/CCIP/Cards/NetworkCard.tsx
index 839f4389d4d..5d5ee0f4e99 100644
--- a/src/components/CCIP/Cards/NetworkCard.tsx
+++ b/src/components/CCIP/Cards/NetworkCard.tsx
@@ -1,5 +1,5 @@
import { memo } from "react"
-import "./NetworkCard.css"
+import Card from "./Card.tsx"
interface NetworkCardProps {
name: string
@@ -9,17 +9,9 @@ interface NetworkCardProps {
}
const NetworkCard = memo(function NetworkCard({ name, totalLanes, totalTokens, logo }: NetworkCardProps) {
- return (
-
-
-
-
{name}
-
- {totalLanes} {totalLanes > 1 ? "lanes" : "lane"} | {totalTokens} {totalTokens > 1 ? "tokens" : "token"}
-
-
-
- )
+ const subtitle = `${totalLanes} ${totalLanes === 1 ? "lane" : "lanes"} | ${totalTokens} ${totalTokens === 1 ? "token" : "tokens"}`
+
+ return } title={name} subtitle={subtitle} />
})
export default NetworkCard
diff --git a/src/components/CCIP/Cards/TokenCard.css b/src/components/CCIP/Cards/TokenCard.css
index c2d092aa132..ae035e97a19 100644
--- a/src/components/CCIP/Cards/TokenCard.css
+++ b/src/components/CCIP/Cards/TokenCard.css
@@ -1,19 +1,11 @@
.token-card__container {
display: flex;
- width: 100%;
- height: 110px;
- min-width: 110px;
- margin: 0 auto;
- flex-direction: column;
- align-items: center;
- text-align: center;
- padding: var(--space-4x);
+ padding: var(--space-6x);
gap: var(--space-3x);
- background: #ffffff;
+ width: 100%;
+ background: var(--white);
border: 1px solid var(--gray-200);
border-radius: var(--space-1x);
- justify-content: center;
- cursor: pointer;
/* Optimize rendering performance */
contain: layout style paint;
will-change: background-color;
@@ -27,14 +19,24 @@
.token-card__container object img {
width: var(--space-10x);
height: var(--space-10x);
+ margin-top: auto;
+ margin-bottom: auto;
border-radius: 50%;
}
.token-card__container h3 {
font-size: var(--space-4x);
- font-weight: 500;
+ font-weight: var(--font-weight-medium);
+ line-height: var(--space-6x);
color: var(--gray-950);
+ margin-bottom: var(--space-1x);
+}
+
+.token-card__container p {
margin-bottom: 0;
+ font-size: var(--space-3x);
+ line-height: var(--space-5x);
+ color: var(--gray-500);
}
.truncate {
@@ -49,3 +51,58 @@
height: 124px;
}
}
+
+/* Square variant styles */
+.token-card__square-container {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ padding: var(--space-6x);
+ width: 100%;
+ background: var(--white);
+ border: 1px solid var(--gray-200);
+ border-radius: var(--space-1x);
+ text-align: center;
+}
+
+.token-card__square-container:hover {
+ background-color: var(--gray-50);
+}
+
+.token-card__square-logo {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ margin-bottom: var(--space-4x);
+}
+
+.token-card__square-logo object,
+.token-card__square-logo object img {
+ width: var(--space-16x);
+ height: var(--space-16x);
+ border-radius: 50%;
+}
+
+.token-card__square-content {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+}
+
+.token-card__square-content h3 {
+ font-size: var(--space-4x);
+ font-weight: var(--font-weight-medium);
+ line-height: var(--space-6x);
+ color: var(--gray-950);
+ margin-bottom: var(--space-1x);
+ text-align: center;
+}
+
+.token-card__square-content p {
+ margin-bottom: 0;
+ font-size: var(--space-3x);
+ line-height: var(--space-5x);
+ color: var(--gray-500);
+ text-align: center;
+}
diff --git a/src/components/CCIP/Cards/TokenCard.tsx b/src/components/CCIP/Cards/TokenCard.tsx
index 653908ec260..51372209112 100644
--- a/src/components/CCIP/Cards/TokenCard.tsx
+++ b/src/components/CCIP/Cards/TokenCard.tsx
@@ -1,5 +1,6 @@
import { memo } from "react"
import { fallbackTokenIconUrl } from "~/features/utils/index.ts"
+import Card from "./Card.tsx"
import "./TokenCard.css"
interface TokenCardProps {
@@ -7,42 +8,71 @@ interface TokenCardProps {
logo?: string
link?: string
onClick?: () => void
+ totalNetworks?: number
+ variant?: "default" | "square"
}
-const TokenCard = memo(function TokenCard({ id, logo, link, onClick }: TokenCardProps) {
- if (link) {
- return (
-
-
- {/* We cannot use the normal Image/onError syntax as a fallback as the element is server rendered
- and the onerror does not seem to work correctly. Using Picture will also not work. */}
-
-
-
+const TokenCard = memo(function TokenCard({
+ id,
+ logo,
+ link,
+ onClick,
+ totalNetworks,
+ variant = "default",
+}: TokenCardProps) {
+ const logoElement = (
+
+
+
+ )
+
+ const subtitle =
+ totalNetworks !== undefined ? `${totalNetworks} ${totalNetworks === 1 ? "network" : "networks"}` : undefined
+
+ if (variant === "square") {
+ const content = (
+ <>
+
{logoElement}
+
{id}
+ {subtitle &&
{subtitle}
}
-
+ >
)
- }
- if (onClick) {
- return (
-
-
-
-
- {id}
-
- )
+ if (link) {
+ return (
+
+ {content}
+
+ )
+ }
+
+ if (onClick) {
+ return (
+
+ {content}
+
+ )
+ }
+
+ return
{content}
}
return (
-
-
-
-
-
{id}
-
+
)
})
diff --git a/src/components/CCIP/Chain/Chain.astro b/src/components/CCIP/Chain/Chain.astro
index fd726a209a2..c236891c8b8 100644
--- a/src/components/CCIP/Chain/Chain.astro
+++ b/src/components/CCIP/Chain/Chain.astro
@@ -6,6 +6,7 @@ import {
Network,
getAllNetworkLanes,
getAllNetworks,
+ getAllUniqueVerifiers,
getSearchLanes,
getTokensOfChain,
Version,
@@ -17,6 +18,7 @@ import ChainTokenGrid from "./ChainTokenGrid"
import { generateChainStructuredData } from "~/utils/ccipStructuredData"
import StructuredData from "~/components/StructuredData.astro"
import { DOCS_BASE_URL } from "~/utils/structuredData"
+import AddButton from "~/components/CCIP/AddButton/AddButton.astro"
interface Props {
environment: Environment
@@ -48,6 +50,11 @@ const lanes = await getAllNetworkLanes({
const searchLanes = getSearchLanes({ environment })
+const allVerifiers = getAllUniqueVerifiers({
+ environment,
+ version: Version.V1_2_0,
+})
+
// Generate dynamic metadata for this specific chain
const environmentText = environment === Environment.Mainnet ? "Mainnet" : "Testnet"
const logoPath = network.logo || ""
@@ -106,6 +113,7 @@ const chainStructuredData = generateChainStructuredData(
network={network}
environment={environment}
lanes={searchLanes}
+ verifiers={allVerifiers}
client:load
/>
@@ -128,14 +136,7 @@ const chainStructuredData = generateChainStructuredData(
Tokens ({allTokens.length})
{
network.chainType !== "solana" && network.chainType !== "aptos" && (
-
-
- Add my token
-
+
)
}
@@ -193,8 +194,12 @@ const chainStructuredData = generateChainStructuredData(
display: grid;
--doc-padding: var(--space-10x);
padding: var(--doc-padding) var(--space-8x);
- grid-template-columns: 1fr 1fr;
- gap: var(--space-24x);
+ grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
+ gap: var(--space-8x);
+ }
+
+ .layout > div {
+ min-width: 0;
}
.networks__grid {
diff --git a/src/components/CCIP/Chain/ChainTokenGrid.css b/src/components/CCIP/Chain/ChainTokenGrid.css
index 9f61a1e8472..aa0bcdbcc86 100644
--- a/src/components/CCIP/Chain/ChainTokenGrid.css
+++ b/src/components/CCIP/Chain/ChainTokenGrid.css
@@ -6,7 +6,6 @@
@media (min-width: 992px) {
.tokens__grid {
- min-height: 420px;
grid-template-columns: 1fr 1fr 1fr 1fr;
gap: var(--space-4x);
}
diff --git a/src/components/CCIP/Chain/ChainTokenGrid.tsx b/src/components/CCIP/Chain/ChainTokenGrid.tsx
index fd267bcfd56..1459faf37f4 100644
--- a/src/components/CCIP/Chain/ChainTokenGrid.tsx
+++ b/src/components/CCIP/Chain/ChainTokenGrid.tsx
@@ -36,6 +36,7 @@ function ChainTokenGrid({ tokens, network, environment }: ChainTokenGridProps) {
id={token.id}
logo={token.logo}
key={token.id}
+ variant="square"
onClick={() => {
const selectedNetwork = Object.keys(data)
.map((key) => {
diff --git a/src/components/CCIP/ChainHero/ChainHero.css b/src/components/CCIP/ChainHero/ChainHero.css
index 34c38f7ae17..98d1d58b11b 100644
--- a/src/components/CCIP/ChainHero/ChainHero.css
+++ b/src/components/CCIP/ChainHero/ChainHero.css
@@ -1,7 +1,6 @@
.ccip-chain-hero {
- background-color: var(--gray-100);
+ background: var(--Page-Background-Alt);
border-bottom: 1px solid var(--gray-200);
- min-height: 241px;
}
.ccip-chain-hero__heading {
@@ -17,6 +16,12 @@
margin: 0;
font-size: 28px;
font-weight: 500;
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ position: relative;
+ overflow: visible;
+ line-height: var(--space-6x);
}
.ccip-chain-hero__heading img {
@@ -121,7 +126,8 @@
.ccip-chain-hero__token-logo__symbol {
font-weight: 500;
font-size: 18px;
- color: var(--gray-700);
+ color: var(--Page-Foreground-Muted, #6c7585);
+ align-self: self-end;
}
.ccip-chain-hero__feeTokens__list {
diff --git a/src/components/CCIP/ChainHero/ChainHero.tsx b/src/components/CCIP/ChainHero/ChainHero.tsx
index 6d49ef92b17..bc4b18ab7c6 100644
--- a/src/components/CCIP/ChainHero/ChainHero.tsx
+++ b/src/components/CCIP/ChainHero/ChainHero.tsx
@@ -46,6 +46,13 @@ interface ChainHeroProps {
}
lane: LaneConfig
}[]
+ verifiers?: {
+ id: string
+ name: string
+ type: string
+ logo: string
+ totalNetworks: number
+ }[]
network?: Network
token?: {
id: string
@@ -54,9 +61,22 @@ interface ChainHeroProps {
symbol: string
}
environment: Environment
+ breadcrumbItems?: Array<{
+ name: string
+ url: string
+ }>
}
-function ChainHero({ chains, tokens, network, token, environment, lanes }: ChainHeroProps) {
+function ChainHero({
+ chains,
+ tokens,
+ network,
+ token,
+ environment,
+ lanes,
+ verifiers = [],
+ breadcrumbItems,
+}: ChainHeroProps) {
// Get chain-specific tooltip configuration
const chainTooltipConfig = network?.chain ? getChainTooltip(network.chain) : null
@@ -99,55 +119,58 @@ function ChainHero({ chains, tokens, network, token, environment, lanes }: Chain
-
-
{
- currentTarget.onerror = null // prevents looping
- currentTarget.src = fallbackTokenIconUrl
- }}
- />
-
- {network?.name || token?.id}
- {token?.name}
+ {(network || token) && (
+
+
{
+ currentTarget.onerror = null // prevents looping
+ currentTarget.src = fallbackTokenIconUrl
+ }}
+ />
+
+ {network?.name || token?.name}
+ {token?.id}
- {chainTooltipConfig && (
-
- )}
-
-
+ {chainTooltipConfig && (
+
+ )}
+
+
+ )}
{network && (
diff --git a/src/components/CCIP/ChainHero/LaneDetailsHero.css b/src/components/CCIP/ChainHero/LaneDetailsHero.css
index 706ee384876..638ed72b3d3 100644
--- a/src/components/CCIP/ChainHero/LaneDetailsHero.css
+++ b/src/components/CCIP/ChainHero/LaneDetailsHero.css
@@ -1,5 +1,5 @@
.lane-details-hero {
- background-color: var(--gray-100);
+ background: var(--Page-Background-Alt);
padding: var(--space-6x);
border-bottom: 1px solid var(--gray-200);
}
@@ -42,9 +42,16 @@
}
.lane-details-hero__details {
- display: grid;
- grid-template-columns: 1fr 1fr;
- gap: var(--space-6x);
+ display: flex;
+ flex-direction: column;
+ gap: var(--space-10x);
+}
+
+.lane-details-hero__details__item {
+ display: flex;
+ flex-direction: column;
+ gap: var(--space-4x);
+ min-width: var(--space-45x);
}
.lane-details-hero__details__label {
@@ -61,10 +68,6 @@
padding: var(--space-6x) var(--space-10x) var(--space-10x);
}
- .lane-details-hero__details {
- grid-template-columns: 1fr 2fr;
- }
-
.lane-details-hero__networks {
flex-direction: row;
align-items: center;
@@ -74,4 +77,9 @@
transform: rotate(0deg);
margin-left: 0;
}
+
+ .lane-details-hero__details {
+ flex-direction: row;
+ flex-wrap: wrap;
+ }
}
diff --git a/src/components/CCIP/ChainHero/LaneDetailsHero.tsx b/src/components/CCIP/ChainHero/LaneDetailsHero.tsx
index 8c96ef2fde5..32c2a7e98fe 100644
--- a/src/components/CCIP/ChainHero/LaneDetailsHero.tsx
+++ b/src/components/CCIP/ChainHero/LaneDetailsHero.tsx
@@ -19,8 +19,8 @@ interface LaneDetailsHeroProps {
}
onRamp: string
offRamp: string
+ sourceAddress: string
destinationAddress: string
- enforceOutOfOrder?: boolean
explorer: ExplorerInfo
inOutbound: LaneFilter
}
@@ -69,13 +69,13 @@ const DetailItem = ({
clipboardType?: string
tooltip?: React.ReactNode
}) => (
- <>
+
{label}
{tooltip}
{children}
- >
+
)
function LaneDetailsHero({
@@ -83,18 +83,11 @@ function LaneDetailsHero({
destinationNetwork,
onRamp,
offRamp,
+ sourceAddress,
destinationAddress,
- enforceOutOfOrder,
explorer,
inOutbound,
}: LaneDetailsHeroProps) {
- // Map boolean values to display strings
- const getOutOfOrderText = (value?: boolean) => {
- if (value === true) return "Required"
- if (value === false) return "Optional"
- return "N/A"
- }
-
return (
{/* Display networks with direction based on lane type */}
@@ -115,16 +108,7 @@ function LaneDetailsHero({
- {/* Display address information based on lane type */}
- {inOutbound === LaneFilter.Inbound ? (
-
-
-
- ) : (
+ {onRamp && (
)}
-
- {destinationAddress ? : "n/a"}{" "}
-
+ {offRamp && (
+
+
+
+ )}
+
+ {sourceAddress && (
+
}
+ >
+
+
+ )}
- {inOutbound === LaneFilter.Outbound && (
+ {destinationAddress && (
- }
+ label="Destination chain selector"
+ clipboardType="destination-chain-selector"
+ tooltip={
}
>
- {getOutOfOrderText(enforceOutOfOrder)}
+
)}
diff --git a/src/components/CCIP/Drawer/Drawer.css b/src/components/CCIP/Drawer/Drawer.css
index f42721fad1d..0b8d48a4d6a 100644
--- a/src/components/CCIP/Drawer/Drawer.css
+++ b/src/components/CCIP/Drawer/Drawer.css
@@ -52,6 +52,11 @@
width: 75%;
}
+ /* Wide drawer for lane details - full width minus ESC button width and spacing */
+ .drawer__container--wide {
+ width: calc(100% - var(--space-12x) - var(--space-8x));
+ }
+
.drawer__closeMobile {
display: none;
}
diff --git a/src/components/CCIP/Drawer/Drawer.tsx b/src/components/CCIP/Drawer/Drawer.tsx
index 9120bb98b0f..7846947b9dc 100644
--- a/src/components/CCIP/Drawer/Drawer.tsx
+++ b/src/components/CCIP/Drawer/Drawer.tsx
@@ -1,6 +1,6 @@
import { useStore } from "@nanostores/react"
import "./Drawer.css"
-import { drawerContentStore } from "./drawerStore.ts"
+import { drawerContentStore, drawerWidthStore, DrawerWidth } from "./drawerStore.ts"
import { useRef, useEffect, useState } from "react"
import { clsx } from "~/lib/clsx/clsx.ts"
import type { ReactNode } from "react"
@@ -9,6 +9,7 @@ function Drawer() {
const drawerRef = useRef
(null)
const drawerContentRef = useRef(null)
const $drawerContent = useStore(drawerContentStore) as (() => ReactNode) | ReactNode | null
+ const $drawerWidth = useStore(drawerWidthStore)
const [isOpened, setIsOpened] = useState(false)
// exit when press esc
@@ -47,6 +48,7 @@ function Drawer() {
// Use transitionend event instead of setTimeout for better performance
const handleTransitionEnd = () => {
drawerContentStore.set(null)
+ drawerWidthStore.set(DrawerWidth.Default)
drawerRef.current?.removeEventListener("transitionend", handleTransitionEnd)
}
@@ -62,7 +64,12 @@ function Drawer() {
ref={drawerRef}
onClick={handleClickOutside}
>
-
+
diff --git a/src/components/CCIP/Drawer/LaneDrawer.tsx b/src/components/CCIP/Drawer/LaneDrawer.tsx
index 18f91339c21..693277167cf 100644
--- a/src/components/CCIP/Drawer/LaneDrawer.tsx
+++ b/src/components/CCIP/Drawer/LaneDrawer.tsx
@@ -1,14 +1,17 @@
import Address from "~/components/AddressReact.tsx"
import "../Tables/Table.css"
-import { Environment, LaneConfig, LaneFilter, Version } from "~/config/data/ccip/types.ts"
-import { getNetwork, getTokenData } from "~/config/data/ccip/data.ts"
+import { Environment, LaneConfig, LaneFilter } from "~/config/data/ccip/types.ts"
+import { getNetwork } from "~/config/data/ccip/data.ts"
import { determineTokenMechanism } from "~/config/data/ccip/utils.ts"
import { useState } from "react"
import LaneDetailsHero from "../ChainHero/LaneDetailsHero.tsx"
-import { getExplorerAddressUrl, getTokenIconUrl, fallbackTokenIconUrl } from "~/features/utils/index.ts"
+import { getExplorerAddressUrl, fallbackTokenIconUrl } from "~/features/utils/index.ts"
import TableSearchInput from "../Tables/TableSearchInput.tsx"
import { Tooltip } from "~/features/common/Tooltip/Tooltip.tsx"
import { ChainType, ExplorerInfo } from "@config/types.ts"
+import { useTokenRateLimits } from "~/hooks/useTokenRateLimits.ts"
+import { RateLimitCell } from "~/components/CCIP/RateLimitCell.tsx"
+import { useLaneTokens } from "~/hooks/useLaneTokens.ts"
function LaneDrawer({
lane,
@@ -26,6 +29,7 @@ function LaneDrawer({
inOutbound: LaneFilter
}) {
const [search, setSearch] = useState("")
+
const destinationNetworkDetails = getNetwork({
filter: environment,
chain: destinationNetwork.key,
@@ -36,9 +40,25 @@ function LaneDrawer({
chain: sourceNetwork.key,
})
+ // Determine source and destination based on inOutbound filter
+ const source = inOutbound === LaneFilter.Outbound ? sourceNetwork.key : destinationNetwork.key
+ const destination = inOutbound === LaneFilter.Outbound ? destinationNetwork.key : sourceNetwork.key
+
+ // Fetch rate limits data using custom hook
+ const { rateLimits, isLoading: isLoadingRateLimits } = useTokenRateLimits(source, destination, environment)
+
+ // Process tokens with hook
+ const { tokens: processedTokens, count: tokenCount } = useLaneTokens({
+ tokens: lane.supportedTokens,
+ environment,
+ rateLimitsData: rateLimits,
+ inOutbound,
+ searchQuery: search,
+ })
+
return (
<>
- Lane details
+ Lane Details
@@ -62,7 +82,7 @@ function LaneDrawer({
- Tokens ({lane?.supportedTokens ? lane.supportedTokens.length : 0})
+ Tokens ({tokenCount})
@@ -72,7 +92,7 @@ function LaneDrawer({
Ticker
- Token address (Source)
+ Source token address
Decimals
Mechanism
@@ -90,123 +110,161 @@ function LaneDrawer({
/>
- Rate limit capacity
-
+
+ Rate limit capacity
+
+
+
+ (Tokens)
+
- Rate limit refill rate
-
+
+ Rate limit refill rate
+
+
+
+ (Tokens/sec)
+
+
+
+
+ FTF Rate limit capacity
+
+
+
+ (Tokens)
+
+
+
+
+ FTF Rate limit refill rate
+
+
+
+ (Tokens/sec)
+
- {lane.supportedTokens &&
- lane.supportedTokens
- .filter((token) => token.toLowerCase().includes(search.toLowerCase()))
- .map((token, index) => {
- const data = getTokenData({
- environment,
- version: Version.V1_2_0,
- tokenId: token || "",
- })
- if (!Object.keys(data).length) return null
- const logo = getTokenIconUrl(token)
-
- // TODO: Fetch rate limits from API for both inbound and outbound
- // Token pause detection requires rate limiter data from API
- // A token is paused when rate limit capacity is 0
- const tokenPaused = false
+ {processedTokens.map((token, index) => (
+
+
+
+
+
{
+ currentTarget.onerror = null // prevents looping
+ currentTarget.src = fallbackTokenIconUrl
+ }}
+ />
+ {token.id}
+ {token.isPaused && (
+
+ ⏸️
+
+ )}
+
+
+
+
+
+
+ {token.data[sourceNetwork.key].decimals}
+
+ {inOutbound === LaneFilter.Outbound
+ ? determineTokenMechanism(
+ token.data[sourceNetwork.key].pool.type,
+ token.data[destinationNetwork.key].pool.type
+ )
+ : determineTokenMechanism(
+ token.data[destinationNetwork.key].pool.type,
+ token.data[sourceNetwork.key].pool.type
+ )}
+
- return (
-
-
-
-
-
{
- currentTarget.onerror = null // prevents looping
- currentTarget.src = fallbackTokenIconUrl
- }}
- />
- {token}
- {tokenPaused && (
-
- ⏸️
-
- )}
-
-
-
-
-
-
- {data[sourceNetwork.key].decimals}
-
- {inOutbound === LaneFilter.Outbound
- ? determineTokenMechanism(
- data[sourceNetwork.key].pool.type,
- data[destinationNetwork.key].pool.type
- )
- : determineTokenMechanism(
- data[destinationNetwork.key].pool.type,
- data[sourceNetwork.key].pool.type
- )}
-
-
-
- {/* TODO: Fetch rate limits from API for both inbound and outbound
- GET /api/ccip/v1/lanes/by-internal-id/{source}/{destination}/supported-tokens?environment={environment}
- Response will contain both standard and custom rate limits per token */}
- Disabled
-
-
- {/* TODO: Fetch rate limits from API for both inbound and outbound
- Display refill rate from standard.in/out or custom.in/out based on inOutbound filter */}
- Disabled
-
-
- )
- })}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ))}
-
- {lane.supportedTokens &&
- lane.supportedTokens.filter((token) => token.toLowerCase().includes(search.toLowerCase())).length === 0 && (
- <>No tokens found>
- )}
-
+ {processedTokens.length === 0 && <>No tokens found>}
>
)
diff --git a/src/components/CCIP/Drawer/TokenDrawer.tsx b/src/components/CCIP/Drawer/TokenDrawer.tsx
index 77bea831f25..19d31f1cbbe 100644
--- a/src/components/CCIP/Drawer/TokenDrawer.tsx
+++ b/src/components/CCIP/Drawer/TokenDrawer.tsx
@@ -1,5 +1,5 @@
import "../Tables/Table.css"
-import { drawerContentStore } from "../Drawer/drawerStore.ts"
+import { drawerContentStore, drawerWidthStore, DrawerWidth } from "../Drawer/drawerStore.ts"
import TokenDetailsHero from "../ChainHero/TokenDetailsHero.tsx"
import {
Environment,
@@ -12,13 +12,26 @@ import {
PoolType,
getTokenData,
LaneConfig,
+ getVerifiersByNetwork,
+ getVerifierTypeDisplay,
} from "~/config/data/ccip/index.ts"
-import { useState } from "react"
+import { useState, useMemo } from "react"
import { ChainType, ExplorerInfo, SupportedChain } from "~/config/index.ts"
+import { getExplorerAddressUrl } from "~/features/utils/index.ts"
+import Address from "~/components/AddressReact.tsx"
import LaneDrawer from "../Drawer/LaneDrawer.tsx"
import TableSearchInput from "../Tables/TableSearchInput.tsx"
import Tabs from "../Tables/Tabs.tsx"
import { Tooltip } from "~/features/common/Tooltip/Tooltip.tsx"
+import { useMultiLaneRateLimits } from "~/hooks/useMultiLaneRateLimits.ts"
+import { RateLimitCell } from "~/components/CCIP/RateLimitCell.tsx"
+import { realtimeDataService } from "~/lib/ccip/services/realtime-data-instance.ts"
+
+enum TokenTab {
+ Outbound = "outbound",
+ Inbound = "inbound",
+ Verifiers = "verifiers",
+}
function TokenDrawer({
token,
@@ -53,7 +66,26 @@ function TokenDrawer({
environment: Environment
}) {
const [search, setSearch] = useState("")
- const [inOutbound, setInOutbound] = useState
(LaneFilter.Outbound)
+ const [activeTab, setActiveTab] = useState(TokenTab.Outbound)
+
+ // Get verifiers for the current network
+ const verifiers = getVerifiersByNetwork({
+ networkId: network.key,
+ environment,
+ version: Version.V1_2_0,
+ })
+
+ // Filter verifiers based on search
+ const filteredVerifiers = useMemo(() => {
+ if (!search) return verifiers
+ const searchLower = search.toLowerCase()
+ return verifiers.filter(
+ (verifier) =>
+ verifier.name.toLowerCase().includes(searchLower) ||
+ verifier.address.toLowerCase().includes(searchLower) ||
+ verifier.type.toLowerCase().includes(searchLower)
+ )
+ }, [verifiers, search])
type LaneRow = {
networkDetails: {
@@ -65,6 +97,17 @@ function TokenDrawer({
destinationPoolType: PoolType
}
+ // Build lane configurations for fetching rate limits
+ const laneConfigs = useMemo(() => {
+ return Object.keys(destinationLanes).map((destinationChain) => ({
+ source: activeTab === TokenTab.Outbound ? network.key : destinationChain,
+ destination: activeTab === TokenTab.Outbound ? destinationChain : network.key,
+ }))
+ }, [destinationLanes, network.key, activeTab])
+
+ // Fetch rate limits for all lanes using custom hook
+ const { rateLimitsMap, isLoading: isLoadingRateLimits } = useMultiLaneRateLimits(laneConfigs, environment)
+
const laneRows: LaneRow[] = Object.keys(destinationLanes)
.map((destinationChain) => {
const networkDetails = getNetwork({
@@ -138,140 +181,212 @@ function TokenDrawer({
tabs={[
{
name: "Outbound lanes",
- key: LaneFilter.Outbound,
+ key: TokenTab.Outbound,
},
{
name: "Inbound lanes",
- key: LaneFilter.Inbound,
+ key: TokenTab.Inbound,
+ },
+ {
+ name: "Verifiers",
+ key: TokenTab.Verifiers,
},
]}
- onChange={(key) => setInOutbound(key as LaneFilter)}
+ onChange={(key) => setActiveTab(key as TokenTab)}
/>
-
- {" "}
-
-
-
- {inOutbound === LaneFilter.Inbound ? "Source" : "Destination"} network
-
- Rate limit capacity
-
-
-
- Rate limit refill rate
-
-
-
- Mechanism
-
-
- {/* Status */}
-
-
-
- {laneRows
- ?.filter(
- ({ networkDetails }) =>
- networkDetails && networkDetails.name.toLowerCase().includes(search.toLowerCase())
- )
- .map(({ networkDetails, laneData, destinationChain, destinationPoolType }) => {
- if (!laneData || !networkDetails) return null
-
- // TODO: Fetch rate limits from API for both inbound and outbound
- // Token pause detection requires rate limiter data from API
- // A token is paused when rate limit capacity is 0
- const tokenPaused = false
-
- return (
-
+ {activeTab === TokenTab.Verifiers ? (
+
+
+
+
+ Verifier
+ Verifier address
+ Verifier type
+ Threshold amount
+
+
+
+ {verifiers.length === 0 ? (
+
+
+ No verifiers configured
+
+
+ ) : (
+ filteredVerifiers.map((verifier) => (
+
- {
- drawerContentStore.set(() => (
-
- ))
- }}
- aria-label={`View lane details for ${networkDetails?.name}`}
- >
+
- {networkDetails?.name}
- {tokenPaused && (
-
- ⏸️
-
- )}
-
-
-
- {/* TODO: Fetch rate limits from API for both inbound and outbound
- GET /api/ccip/v1/lanes/by-internal-id/{source}/{destination}/supported-tokens?environment={environment}
- Response will contain both standard and custom rate limits per token */}
- Disabled
+ {verifier.name}
+
- {/* TODO: Fetch rate limits from API for both inbound and outbound
- Display refill rate from standard.in/out or custom.in/out based on inOutbound filter */}
- Disabled
+
-
- {inOutbound === LaneFilter.Outbound
- ? determineTokenMechanism(network.tokenPoolType, destinationPoolType)
- : determineTokenMechanism(destinationPoolType, network.tokenPoolType)}
-
- {/*
+ {getVerifierTypeDisplay(verifier.type)}
+ N/A
+
+ ))
+ )}
+
+
+
+ ) : (
+
+ {" "}
+
+
+
+ {activeTab === TokenTab.Inbound ? "Source" : "Destination"} network
+
+ Rate limit capacity
+
+
+
+ Rate limit refill rate
+
+
+ FTF Rate limit capacity
+ FTF Rate limit refill rate
+
+ Mechanism
+
+
+ {/* Status */}
+
+
+
+ {laneRows
+ ?.filter(
+ ({ networkDetails }) =>
+ networkDetails && networkDetails.name.toLowerCase().includes(search.toLowerCase())
+ )
+ .map(({ networkDetails, laneData, destinationChain, destinationPoolType }) => {
+ if (!laneData || !networkDetails) return null
+
+ // Get rate limit data for this lane
+ const source = activeTab === TokenTab.Outbound ? network.key : destinationChain
+ const destination = activeTab === TokenTab.Outbound ? destinationChain : network.key
+ const laneKey = `${source}-${destination}`
+ const laneRateLimits = rateLimitsMap[laneKey]
+ const tokenRateLimits = laneRateLimits?.[token.id]
+
+ const direction = activeTab === TokenTab.Outbound ? "out" : "in"
+
+ // Get standard and FTF rate limits
+ const allLimits = realtimeDataService.getAllRateLimitsForDirection(tokenRateLimits, direction)
+
+ // Token is paused if standard rate limit capacity is 0
+ const tokenPaused = allLimits.standard?.capacity === "0"
+
+ return (
+
+
+ {
+ drawerWidthStore.set(DrawerWidth.Wide)
+ drawerContentStore.set(() => (
+
+ ))
+ }}
+ aria-label={`View lane details for ${networkDetails?.name}`}
+ >
+
+ {networkDetails?.name}
+ {tokenPaused && (
+
+ ⏸️
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {activeTab === TokenTab.Outbound
+ ? determineTokenMechanism(network.tokenPoolType, destinationPoolType)
+ : determineTokenMechanism(destinationPoolType, network.tokenPoolType)}
+
+ {/*
*/}
-
- )
- })}
-
-
-
+
+ )
+ })}
+
+
+
+ )}
-
- {laneRows?.filter(
- ({ networkDetails }) => networkDetails && networkDetails.name.toLowerCase().includes(search.toLowerCase())
- ).length === 0 && <>No lanes found>}
-
+ {activeTab !== TokenTab.Verifiers && (
+
+ {laneRows?.filter(
+ ({ networkDetails }) => networkDetails && networkDetails.name.toLowerCase().includes(search.toLowerCase())
+ ).length === 0 && <>No lanes found>}
+
+ )}
)
diff --git a/src/components/CCIP/Drawer/drawerStore.ts b/src/components/CCIP/Drawer/drawerStore.ts
index 44a1dc6c30f..127d82104fb 100644
--- a/src/components/CCIP/Drawer/drawerStore.ts
+++ b/src/components/CCIP/Drawer/drawerStore.ts
@@ -2,4 +2,10 @@
import { atom } from "nanostores"
import type { JSX } from "preact"
+export enum DrawerWidth {
+ Default = "default",
+ Wide = "wide",
+}
+
export const drawerContentStore = atom<(() => JSX.Element) | null>(null)
+export const drawerWidthStore = atom
(DrawerWidth.Default)
diff --git a/src/components/CCIP/Hero/Hero.css b/src/components/CCIP/Hero/Hero.css
index 8c856f9ffc7..57bc1db56aa 100644
--- a/src/components/CCIP/Hero/Hero.css
+++ b/src/components/CCIP/Hero/Hero.css
@@ -1,10 +1,12 @@
.ccip-hero {
- background-color: var(--gray-100);
+ background: var(--Page-Background-Alt);
border-bottom: 1px solid var(--gray-200);
}
.ccip-hero__heading {
color: var(--gray-900);
+ font-size: 2.5rem;
+ margin-bottom: var(--space-6x);
}
.ccip-hero__content {
@@ -15,3 +17,10 @@
align-items: center;
gap: var(--space-4x);
}
+
+@media screen and (max-width: 768px) {
+ .ccip-hero__heading {
+ font-size: 2rem;
+ margin-bottom: var(--space-4x);
+ }
+}
diff --git a/src/components/CCIP/Hero/Hero.tsx b/src/components/CCIP/Hero/Hero.tsx
index 4655b535e92..2886a4c2a95 100644
--- a/src/components/CCIP/Hero/Hero.tsx
+++ b/src/components/CCIP/Hero/Hero.tsx
@@ -2,6 +2,7 @@ import { Environment, LaneConfig } from "~/config/data/ccip/index.ts"
import Search from "../Search/Search.tsx"
import "./Hero.css"
import { ChainType, ExplorerInfo } from "~/config/types.ts"
+import { Typography } from "@chainlink/blocks"
interface HeroProps {
chains: {
@@ -32,15 +33,24 @@ interface HeroProps {
}
lane: LaneConfig
}[]
+ verifiers?: {
+ id: string
+ name: string
+ type: string
+ logo: string
+ totalNetworks: number
+ }[]
environment: Environment
}
-function Hero({ chains, tokens, environment, lanes }: HeroProps) {
+function Hero({ chains, tokens, environment, lanes, verifiers = [] }: HeroProps) {
return (
-
CCIP Directory
-
+
+ CCIP Directory
+
+
)
diff --git a/src/components/CCIP/Landing/Grid.css b/src/components/CCIP/Landing/Grid.css
new file mode 100644
index 00000000000..14c77deb4b0
--- /dev/null
+++ b/src/components/CCIP/Landing/Grid.css
@@ -0,0 +1,12 @@
+.grid {
+ display: grid;
+ grid-template-columns: 1fr;
+ gap: var(--space-2x);
+}
+
+@media (min-width: 992px) {
+ .grid {
+ grid-template-columns: 1fr 1fr 1fr 1fr;
+ gap: var(--space-4x);
+ }
+}
diff --git a/src/components/CCIP/Landing/Grid.tsx b/src/components/CCIP/Landing/Grid.tsx
new file mode 100644
index 00000000000..cdc929b6b64
--- /dev/null
+++ b/src/components/CCIP/Landing/Grid.tsx
@@ -0,0 +1,27 @@
+import { useState, type ReactNode } from "react"
+import SeeMore from "../SeeMore/SeeMore.tsx"
+import "./Grid.css"
+
+interface GridProps {
+ items: any[]
+ renderItem: (item: any, index: number) => ReactNode
+ initialDisplayCount: number
+ seeMoreLabel: string
+ className?: string
+ seeMoreLink?: string
+}
+
+function Grid({ items, renderItem, initialDisplayCount, seeMoreLabel, className = "grid", seeMoreLink }: GridProps) {
+ const [seeMore, setSeeMore] = useState(items.length <= initialDisplayCount)
+
+ return (
+ <>
+
+ {items.slice(0, seeMore ? items.length : initialDisplayCount).map((item, index) => renderItem(item, index))}
+
+ {!seeMore && setSeeMore(!seeMore)} label={seeMoreLabel} href={seeMoreLink} />}
+ >
+ )
+}
+
+export default Grid
diff --git a/src/components/CCIP/Landing/NetworkGrid.css b/src/components/CCIP/Landing/NetworkGrid.css
index acf154ba8dc..191be522985 100644
--- a/src/components/CCIP/Landing/NetworkGrid.css
+++ b/src/components/CCIP/Landing/NetworkGrid.css
@@ -6,7 +6,7 @@
@media (min-width: 992px) {
.networks__grid {
- grid-template-columns: 1fr 1fr;
+ grid-template-columns: 1fr 1fr 1fr 1fr;
gap: var(--space-6x);
}
}
diff --git a/src/components/CCIP/Landing/NetworkGrid.tsx b/src/components/CCIP/Landing/NetworkGrid.tsx
index fc4ff7b26d9..13728a0260c 100644
--- a/src/components/CCIP/Landing/NetworkGrid.tsx
+++ b/src/components/CCIP/Landing/NetworkGrid.tsx
@@ -1,7 +1,5 @@
-import { useState } from "react"
-import NetworkCard from "../Cards/NetworkCard.tsx"
-import SeeMore from "../SeeMore/SeeMore.tsx"
-import "./NetworkGrid.css"
+import Card from "../Cards/Card.tsx"
+import Grid from "./Grid.tsx"
interface NetworkGridProps {
networks: {
@@ -14,27 +12,27 @@ interface NetworkGridProps {
environment: string
}
-const BEFORE_SEE_MORE = 2 * 7 // Number of networks to show before the "See more" button, 2 rows x 7 items
+const BEFORE_SEE_MORE = 2 * 4 // Number of networks to show before the "See more" button, 2 rows x 4 items
function NetworkGrid({ networks, environment }: NetworkGridProps) {
- const [seeMore, setSeeMore] = useState(networks.length <= BEFORE_SEE_MORE)
return (
- <>
-
- {networks.slice(0, seeMore ? networks.length : BEFORE_SEE_MORE).map((chain) => (
-
-
-
- ))}
-
- {!seeMore && setSeeMore(!seeMore)} />}
- >
+ {
+ const subtitle = `${chain.totalLanes} ${chain.totalLanes === 1 ? "lane" : "lanes"} | ${chain.totalTokens} ${chain.totalTokens === 1 ? "token" : "tokens"}`
+ return (
+ }
+ title={chain.name}
+ subtitle={subtitle}
+ link={`/ccip/directory/${environment}/chain/${chain.chain}`}
+ />
+ )
+ }}
+ />
)
}
diff --git a/src/components/CCIP/Landing/ccip-landing.astro b/src/components/CCIP/Landing/ccip-landing.astro
index e1135ffcb4b..f65de34c258 100644
--- a/src/components/CCIP/Landing/ccip-landing.astro
+++ b/src/components/CCIP/Landing/ccip-landing.astro
@@ -6,6 +6,7 @@ import {
Environment,
getAllNetworks,
getAllSupportedTokens,
+ getAllUniqueVerifiers,
getChainsOfToken,
getSearchLanes,
Version,
@@ -13,9 +14,11 @@ import {
import { getTokenIconUrl } from "~/features/utils"
import LazyNetworkGrid from "./LazyNetworkGrid"
import LazyTokenGrid from "../TokenGrid/LazyTokenGrid"
+import LazyVerifierGrid from "../VerifierGrid/LazyVerifierGrid"
import StructuredData from "~/components/StructuredData.astro"
import { generateDirectoryStructuredData } from "~/utils/ccipStructuredData"
import { DOCS_BASE_URL } from "~/utils/structuredData"
+import AddButton from "~/components/CCIP/AddButton/AddButton.astro"
export type Props = {
environment: Environment
@@ -43,6 +46,10 @@ const allTokens = tokens.map((token) => {
totalNetworks: getChainsOfToken({ token, filter: environment }).length,
}
})
+const allVerifiers = getAllUniqueVerifiers({
+ environment,
+ version: Version.V1_2_0,
+})
const searchLanes = getSearchLanes({ environment })
// Generate directory-level structured data (DataCatalog/Dataset)
@@ -65,7 +72,14 @@ const directoryStructuredData = generateDirectoryStructuredData(environment, net
}}
suppressDefaultStructuredData={true}
>
-
+
@@ -76,10 +90,16 @@ const directoryStructuredData = generateDirectoryStructuredData(environment, net
+
+
+
Verifiers ({allVerifiers.length})
+
+
+
@@ -125,11 +145,9 @@ const directoryStructuredData = generateDirectoryStructuredData(environment, net
@media (min-width: 992px) {
.layout {
--doc-padding: var(--space-10x);
- display: grid;
padding-top: var(--doc-padding);
padding-bottom: var(--doc-padding);
- grid-template-columns: 1fr 1fr;
- gap: var(--space-24x);
+ gap: var(--space-10x);
}
}
diff --git a/src/components/CCIP/RateLimitCell.tsx b/src/components/CCIP/RateLimitCell.tsx
new file mode 100644
index 00000000000..61a4a8c7aa1
--- /dev/null
+++ b/src/components/CCIP/RateLimitCell.tsx
@@ -0,0 +1,46 @@
+import { Tooltip } from "~/features/common/Tooltip/Tooltip.tsx"
+import type { RateLimiterConfig } from "~/lib/ccip/types/index.ts"
+import { formatRateLimit } from "~/lib/ccip/utils/rate-limit-formatter.ts"
+
+interface RateLimitCellProps {
+ isLoading: boolean
+ rateLimit: RateLimiterConfig | null | undefined
+ type: "capacity" | "rate"
+ showUnavailableTooltip?: boolean
+}
+
+/**
+ * Component for displaying rate limit values in table cells
+ * Handles loading, disabled, unavailable, and value states
+ */
+export function RateLimitCell({ isLoading, rateLimit, type, showUnavailableTooltip = false }: RateLimitCellProps) {
+ if (isLoading) {
+ return <>Loading...>
+ }
+
+ if (!rateLimit) {
+ if (showUnavailableTooltip) {
+ return (
+
+ Unavailable
+
+
+ )
+ }
+ return <>N/A>
+ }
+
+ if (!rateLimit.isEnabled) {
+ return <>Disabled>
+ }
+
+ const value = type === "capacity" ? rateLimit.capacity : rateLimit.rate
+ return <>{formatRateLimit(value)}>
+}
diff --git a/src/components/CCIP/Search/Search.css b/src/components/CCIP/Search/Search.css
index 1134619167d..484a9e80960 100644
--- a/src/components/CCIP/Search/Search.css
+++ b/src/components/CCIP/Search/Search.css
@@ -33,6 +33,10 @@
outline: none;
}
+.ccip-hero__search input::placeholder {
+ font-style: normal;
+}
+
.ccip-hero__search input::-webkit-search-cancel-button {
-webkit-appearance: none;
height: 1em;
diff --git a/src/components/CCIP/Search/Search.tsx b/src/components/CCIP/Search/Search.tsx
index 92b0c776971..7d908596af7 100644
--- a/src/components/CCIP/Search/Search.tsx
+++ b/src/components/CCIP/Search/Search.tsx
@@ -4,7 +4,7 @@ import { clsx } from "~/lib/clsx/clsx.ts"
import { useClickOutside } from "~/hooks/useClickOutside.tsx"
import { Environment, LaneConfig, LaneFilter } from "~/config/data/ccip/types.ts"
import { directoryToSupportedChain, getExplorer, fallbackTokenIconUrl } from "~/features/utils/index.ts"
-import { drawerContentStore } from "../Drawer/drawerStore.ts"
+import { drawerContentStore, drawerWidthStore, DrawerWidth } from "../Drawer/drawerStore.ts"
import LaneDrawer from "../Drawer/LaneDrawer.tsx"
import { ChainType, ExplorerInfo } from "~/config/types.ts"
import type { WorkerMessage, WorkerResponse } from "~/workers/data-worker.ts"
@@ -38,11 +38,18 @@ interface SearchProps {
}
lane: LaneConfig
}[]
+ verifiers?: {
+ id: string
+ name: string
+ type: string
+ logo: string
+ totalNetworks: number
+ }[]
small?: boolean
environment: Environment
}
-function Search({ chains, tokens, small, environment, lanes }: SearchProps) {
+function Search({ chains, tokens, small, environment, lanes, verifiers = [] }: SearchProps) {
const [search, setSearch] = useState("")
const [debouncedSearch, setDebouncedSearch] = useState("")
const [openSearchMenu, setOpenSearchMenu] = useState(false)
@@ -50,6 +57,7 @@ function Search({ chains, tokens, small, environment, lanes }: SearchProps) {
const [networksResults, setNetworksResults] = useState
([])
const [tokensResults, setTokensResults] = useState([])
const [lanesResults, setLanesResults] = useState([])
+ const [verifiersResults, setVerifiersResults] = useState([])
const searchRef = useRef(null)
const workerRef = useRef(null)
const workerReadyRef = useRef(false)
@@ -59,10 +67,11 @@ function Search({ chains, tokens, small, environment, lanes }: SearchProps) {
if (workerReadyRef.current || typeof window === "undefined") return
workerRef.current = new Worker(new URL("~/workers/data-worker.ts", import.meta.url), { type: "module" })
workerRef.current.onmessage = (event: MessageEvent) => {
- const { networks, tokens: workerTokens, lanes: workerLanes } = event.data
+ const { networks, tokens: workerTokens, lanes: workerLanes, verifiers: workerVerifiers } = event.data
setNetworksResults(networks || [])
setTokensResults(workerTokens || [])
setLanesResults(workerLanes || [])
+ setVerifiersResults(workerVerifiers || [])
}
workerReadyRef.current = true
}
@@ -90,6 +99,7 @@ function Search({ chains, tokens, small, environment, lanes }: SearchProps) {
setNetworksResults([])
setTokensResults([])
setLanesResults([])
+ setVerifiersResults([])
return
}
@@ -102,11 +112,12 @@ function Search({ chains, tokens, small, environment, lanes }: SearchProps) {
chains,
tokens,
lanes,
+ verifiers,
},
}
workerRef.current.postMessage(message)
}
- }, [debouncedSearch, chains, tokens, lanes])
+ }, [debouncedSearch, chains, tokens, lanes, verifiers])
// Handle menu visibility
useEffect(() => {
@@ -146,7 +157,7 @@ function Search({ chains, tokens, small, environment, lanes }: SearchProps) {
setSearch(e.target.value)}
onFocus={() => {
@@ -154,7 +165,7 @@ function Search({ chains, tokens, small, environment, lanes }: SearchProps) {
ensureWorker()
}}
onBlur={() => setIsActive(false)}
- aria-label="Search networks, tokens, and lanes"
+ aria-label="Search networks, tokens, lanes, and verifiers"
aria-describedby={openSearchMenu ? "search-results" : undefined}
/>
{openSearchMenu && (
@@ -167,9 +178,12 @@ function Search({ chains, tokens, small, environment, lanes }: SearchProps) {
aria-live="polite"
aria-label="Search results"
>
- {networksResults.length === 0 && tokensResults.length === 0 && (
- No results found
- )}
+ {networksResults.length === 0 &&
+ tokensResults.length === 0 &&
+ lanesResults.length === 0 &&
+ verifiersResults.length === 0 && (
+ No results found
+ )}
{networksResults.length > 0 && (
<>
Networks
@@ -236,7 +250,8 @@ function Search({ chains, tokens, small, environment, lanes }: SearchProps) {
+ onClick={() => {
+ drawerWidthStore.set(DrawerWidth.Wide)
drawerContentStore.set(() => (
))
- }
+ }}
aria-label={`View lane from ${lane.sourceNetwork.name} to ${lane.destinationNetwork.name}`}
>
@@ -283,6 +298,36 @@ function Search({ chains, tokens, small, environment, lanes }: SearchProps) {
>
)}
+
+ {verifiersResults.length > 0 && (
+ <>
+
Verifiers
+
+ >
+ )}
)}
diff --git a/src/components/CCIP/SeeMore/SeeMore.css b/src/components/CCIP/SeeMore/SeeMore.css
index 8c4c9209c51..102d96cf4b1 100644
--- a/src/components/CCIP/SeeMore/SeeMore.css
+++ b/src/components/CCIP/SeeMore/SeeMore.css
@@ -7,6 +7,6 @@
}
.seeMore__container {
display: flex;
- justify-content: center;
+ justify-content: flex-start;
align-items: center;
}
diff --git a/src/components/CCIP/SeeMore/SeeMore.tsx b/src/components/CCIP/SeeMore/SeeMore.tsx
index 3e0b7c17278..cab963897c7 100644
--- a/src/components/CCIP/SeeMore/SeeMore.tsx
+++ b/src/components/CCIP/SeeMore/SeeMore.tsx
@@ -1,14 +1,22 @@
import "./SeeMore.css"
interface SeeMoreProps {
onClick?: () => void
+ label?: string
+ href?: string
}
-function SeeMore({ onClick }: SeeMoreProps) {
+function SeeMore({ onClick, label = "See more", href }: SeeMoreProps) {
return (
-
- See more
-
+ {href ? (
+
+ {label}
+
+ ) : (
+
+ {label}
+
+ )}
)
}
diff --git a/src/components/CCIP/Tables/ChainTable.tsx b/src/components/CCIP/Tables/ChainTable.tsx
index d487faf20ee..5e278233d20 100644
--- a/src/components/CCIP/Tables/ChainTable.tsx
+++ b/src/components/CCIP/Tables/ChainTable.tsx
@@ -4,7 +4,7 @@ import Tabs from "./Tabs.tsx"
import TableSearchInput from "./TableSearchInput.tsx"
import { useEffect, useState } from "react"
import { getExplorerAddressUrl } from "~/features/utils/index.ts"
-import { drawerContentStore } from "../Drawer/drawerStore.ts"
+import { drawerContentStore, drawerWidthStore, DrawerWidth } from "../Drawer/drawerStore.ts"
import LaneDrawer from "../Drawer/LaneDrawer.tsx"
import { Environment, Version, LaneFilter } from "~/config/data/ccip/types.ts"
import { getLane } from "~/config/data/ccip/data.ts"
@@ -130,6 +130,7 @@ function ChainTable({ lanes, explorer, sourceNetwork, environment }: TableProps)
version: Version.V1_2_0,
})
+ drawerWidthStore.set(DrawerWidth.Wide)
drawerContentStore.set(() => (
@@ -129,7 +135,7 @@ function TokenChainsTable({ networks, token, lanes, environment }: TableProps) {
{tokenPoolDisplay(network.tokenPoolType)}
@@ -140,20 +146,43 @@ function TokenChainsTable({ networks, token, lanes, environment }: TableProps) {
network.chainType
)(network.tokenPoolAddress)}
address={network.tokenPoolAddress}
- endLength={6}
+ endLength={4}
/>
{network.tokenPoolVersion}
- {/* TODO: Fetch from API - GET /api/ccip/v1/tokens/{tokenCanonicalSymbol}/finality?environment={environment}
- Custom finality is derived from minBlockConfirmation > 0
- Display: "Yes" | "No" | "N/A" (with tooltip for unavailable) */}
- -
+ {loading ? (
+ "-"
+ ) : finalityData[network.key] ? (
+ finalityData[network.key].hasCustomFinality === null ? (
+
+ ) : finalityData[network.key].hasCustomFinality ? (
+ "Yes"
+ ) : (
+ "No"
+ )
+ ) : (
+
+ )}
- {/* TODO: Fetch from API - GET /api/ccip/v1/tokens/{tokenCanonicalSymbol}/finality?environment={environment}
- Display minBlockConfirmation value or "-" if custom finality is disabled/unavailable */}
- -
+ {loading
+ ? "-"
+ : finalityData[network.key]
+ ? finalityData[network.key].minBlockConfirmation === null
+ ? "-"
+ : finalityData[network.key].minBlockConfirmation
+ : "-"}
)
diff --git a/src/components/CCIP/Tables/VerifiersTable.tsx b/src/components/CCIP/Tables/VerifiersTable.tsx
new file mode 100644
index 00000000000..dc79bf8753e
--- /dev/null
+++ b/src/components/CCIP/Tables/VerifiersTable.tsx
@@ -0,0 +1,124 @@
+import Address from "~/components/AddressReact.tsx"
+import "./Table.css"
+import { Environment, Verifier, getVerifierTypeDisplay } from "~/config/data/ccip/index.ts"
+import TableSearchInput from "./TableSearchInput.tsx"
+import { useState } from "react"
+import {
+ getExplorerAddressUrl,
+ fallbackVerifierIconUrl,
+ getChainIcon,
+ getTitle,
+ directoryToSupportedChain,
+ getExplorer,
+ getChainTypeAndFamily,
+} from "~/features/utils/index.ts"
+
+interface VerifiersTableProps {
+ verifiers: Verifier[]
+}
+
+function VerifiersTable({ verifiers }: VerifiersTableProps) {
+ const [search, setSearch] = useState("")
+
+ // Transform verifiers data to include network information
+ const verifiersWithNetworkInfo = verifiers.map((verifier) => {
+ const supportedChain = directoryToSupportedChain(verifier.network)
+ const networkName = getTitle(supportedChain) || verifier.network
+ const networkLogo = getChainIcon(supportedChain) || ""
+ const explorer = getExplorer(supportedChain)
+ const { chainType } = getChainTypeAndFamily(supportedChain)
+
+ return {
+ ...verifier,
+ networkName,
+ networkLogo,
+ supportedChain,
+ explorer,
+ chainType,
+ }
+ })
+
+ const filteredVerifiers = verifiersWithNetworkInfo.filter(
+ (verifier) =>
+ verifier.name.toLowerCase().includes(search.toLowerCase()) ||
+ verifier.networkName.toLowerCase().includes(search.toLowerCase()) ||
+ verifier.address.toLowerCase().includes(search.toLowerCase()) ||
+ getVerifierTypeDisplay(verifier.type).toLowerCase().includes(search.toLowerCase())
+ )
+
+ return (
+ <>
+
+
+ Verifiers ({verifiers.length})
+
+
+
+
+
+
+
+ Verifier
+ Network
+ Verifier address
+ Verifier type
+
+
+
+ {filteredVerifiers.map((verifier, index) => (
+
+
+
+
+ {
+ currentTarget.onerror = null // prevents looping
+ currentTarget.src = fallbackVerifierIconUrl
+ }}
+ />
+
+ {verifier.name}
+
+
+
+
+
+ {
+ currentTarget.onerror = null // prevents looping
+ currentTarget.src = fallbackVerifierIconUrl
+ }}
+ />
+
+ {verifier.networkName}
+
+
+
+
+
+ {getVerifierTypeDisplay(verifier.type)}
+
+ ))}
+
+
+
{filteredVerifiers.length === 0 && <>No verifiers found>}
+
+ >
+ )
+}
+
+export default VerifiersTable
diff --git a/src/components/CCIP/Token/Token.astro b/src/components/CCIP/Token/Token.astro
index 9ba14b50e4f..874fbdc18f2 100644
--- a/src/components/CCIP/Token/Token.astro
+++ b/src/components/CCIP/Token/Token.astro
@@ -5,6 +5,7 @@ import {
getAllNetworks,
getAllSupportedTokens,
getAllTokenLanes,
+ getAllUniqueVerifiers,
getChainsOfToken,
getSearchLanes,
getTokenData,
@@ -76,6 +77,11 @@ const tokenLanes = getAllTokenLanes({
const searchLanes = getSearchLanes({ environment })
+const allVerifiers = getAllUniqueVerifiers({
+ environment,
+ version: Version.V1_2_0,
+})
+
// Generate dynamic metadata for this specific token
const environmentText = environment === Environment.Mainnet ? "Mainnet" : "Testnet"
const tokenMetadata = {
@@ -117,6 +123,7 @@ const tokenStructuredData = generateTokenStructuredData(token, environment, chai
tokens={allTokens}
client:load
lanes={searchLanes}
+ verifiers={allVerifiers}
token={{
id: token,
name: data[firstSupportedChain]?.name || "",
@@ -172,9 +179,8 @@ const tokenStructuredData = generateTokenStructuredData(token, environment, chai
diff --git a/src/components/CCIP/TokenGrid/TokenGrid.tsx b/src/components/CCIP/TokenGrid/TokenGrid.tsx
index 9c303e264a5..7938ef0406a 100644
--- a/src/components/CCIP/TokenGrid/TokenGrid.tsx
+++ b/src/components/CCIP/TokenGrid/TokenGrid.tsx
@@ -1,35 +1,47 @@
-import { useState } from "react"
-import SeeMore from "../SeeMore/SeeMore.tsx"
-import "./TokenGrid.css"
-import TokenCard from "../Cards/TokenCard.tsx"
+import { fallbackTokenIconUrl } from "~/features/utils/index.ts"
+import Card from "../Cards/Card.tsx"
+import Grid from "../Landing/Grid.tsx"
interface TokenGridProps {
tokens: {
id: string
logo: string
+ totalNetworks?: number
}[]
environment: string
}
-const BEFORE_SEE_MORE = 6 * 4 // Number of networks to show before the "See more" button, 6 rows x 4 items
+const BEFORE_SEE_MORE = 2 * 4 // Number of tokens to show before the "See more" button, 2 rows x 4 items
-function NetworkGrid({ tokens, environment }: TokenGridProps) {
- const [seeMore, setSeeMore] = useState(tokens.length <= BEFORE_SEE_MORE)
+function TokenGrid({ tokens, environment }: TokenGridProps) {
return (
- <>
-
- {tokens.slice(0, seeMore ? tokens.length : BEFORE_SEE_MORE).map((token) => (
-
{
+ const subtitle =
+ token.totalNetworks !== undefined
+ ? `${token.totalNetworks} ${token.totalNetworks === 1 ? "network" : "networks"}`
+ : undefined
+ const logoElement = (
+
+
+
+ )
+ return (
+
- ))}
-
- {!seeMore &&
setSeeMore(!seeMore)} />}
- >
+ )
+ }}
+ />
)
}
-export default NetworkGrid
+export default TokenGrid
diff --git a/src/components/CCIP/Tooltip/RateTooltip.tsx b/src/components/CCIP/Tooltip/RateTooltip.tsx
index 836644ab53d..78b6c948d9c 100644
--- a/src/components/CCIP/Tooltip/RateTooltip.tsx
+++ b/src/components/CCIP/Tooltip/RateTooltip.tsx
@@ -7,14 +7,33 @@ function RateTooltip({
symbol,
decimals,
position,
+ showUnavailableText = false,
}: {
destinationLane: SupportedTokenConfig
inOutbound: LaneFilter
symbol: string
decimals: number
position?: "top" | "bottom" | "left" | "right"
+ showUnavailableText?: boolean
}) {
if (!destinationLane.rateLimiterConfig?.[inOutbound === LaneFilter.Inbound ? "in" : "out"]?.isEnabled) {
+ if (showUnavailableText) {
+ return (
+
+ )
+ }
return N/A
}
const { rateSecond, maxThroughput } = displayRate(
diff --git a/src/components/CCIP/VerifierGrid/LazyVerifierGrid.tsx b/src/components/CCIP/VerifierGrid/LazyVerifierGrid.tsx
new file mode 100644
index 00000000000..7dd31d36e19
--- /dev/null
+++ b/src/components/CCIP/VerifierGrid/LazyVerifierGrid.tsx
@@ -0,0 +1,46 @@
+import { lazy, Suspense } from "react"
+import type { Environment } from "~/config/data/ccip/types.ts"
+
+const VerifierGrid = lazy(() => import("./VerifierGrid.tsx"))
+
+interface LazyVerifierGridProps {
+ verifiers: Array<{
+ id: string
+ name: string
+ logo: string
+ totalNetworks: number
+ }>
+ environment: Environment
+}
+
+export default function LazyVerifierGrid({ verifiers, environment }: LazyVerifierGridProps) {
+ return (
+
+ {Array.from({ length: 8 }, (_, i) => (
+
+ ))}
+
+ }
+ >
+
+
+ )
+}
diff --git a/src/components/CCIP/VerifierGrid/VerifierGrid.tsx b/src/components/CCIP/VerifierGrid/VerifierGrid.tsx
new file mode 100644
index 00000000000..133dbb95a97
--- /dev/null
+++ b/src/components/CCIP/VerifierGrid/VerifierGrid.tsx
@@ -0,0 +1,46 @@
+import { fallbackVerifierIconUrl } from "~/features/utils/index.ts"
+import Card from "../Cards/Card.tsx"
+import Grid from "../Landing/Grid.tsx"
+
+interface VerifierGridProps {
+ verifiers: {
+ id: string
+ name: string
+ logo: string
+ totalNetworks: number
+ }[]
+ environment: string
+}
+
+const BEFORE_SEE_MORE = 2 * 4 // Number of verifiers to show before the "See more" button, 2 rows x 4 items
+
+function VerifierGrid({ verifiers, environment }: VerifierGridProps) {
+ return (
+ {
+ const subtitle = `${verifier.totalNetworks} ${verifier.totalNetworks === 1 ? "network" : "networks"}`
+ const logoElement = (
+
+
+
+ )
+ return (
+
+ )
+ }}
+ />
+ )
+}
+
+export default VerifierGrid
diff --git a/src/components/CCIP/Verifiers/Verifiers.astro b/src/components/CCIP/Verifiers/Verifiers.astro
new file mode 100644
index 00000000000..dd3dc730de4
--- /dev/null
+++ b/src/components/CCIP/Verifiers/Verifiers.astro
@@ -0,0 +1,118 @@
+---
+import CcipDirectoryLayout from "~/layouts/CcipDirectoryLayout.astro"
+import { getEntry, render } from "astro:content"
+import {
+ getAllNetworks,
+ getAllVerifiers,
+ getSearchLanes,
+ Version,
+ Environment,
+ getAllSupportedTokens,
+ getChainsOfToken,
+} from "~/config/data/ccip"
+import Table from "~/components/CCIP/Tables/VerifiersTable"
+import { getAllUniqueVerifiers } from "~/config/data/ccip/data.ts"
+import { DOCS_BASE_URL } from "~/utils/structuredData"
+import ChainHero from "~/components/CCIP/ChainHero/ChainHero"
+import { getTokenIconUrl } from "~/features/utils"
+import "./Verifiers.css"
+
+interface Props {
+ environment: Environment
+}
+
+const { environment } = Astro.props as Props
+
+const entry = await getEntry("ccip", "index")
+if (!entry) {
+ throw new Error('Could not find "ccip/index" doc. Check src/content/ccip/index.mdx!')
+}
+
+const { headings } = await render(entry)
+
+const networks = getAllNetworks({ filter: environment })
+
+const allVerifiers = getAllVerifiers({
+ environment,
+ version: Version.V1_2_0,
+})
+
+const uniqueVerifiers = getAllUniqueVerifiers({
+ environment,
+ version: Version.V1_2_0,
+})
+
+const searchLanes = getSearchLanes({ environment })
+
+const supportedTokens = getAllSupportedTokens({
+ environment,
+ version: Version.V1_2_0,
+})
+const tokens = Object.keys(supportedTokens).sort((a, b) => a.localeCompare(b, undefined, { sensitivity: "base" }))
+const allTokens = tokens.map((token) => {
+ const logo = getTokenIconUrl(token) || ""
+ return {
+ id: token,
+ logo,
+ totalNetworks: getChainsOfToken({ token, filter: environment }).length,
+ }
+})
+
+// Generate dynamic metadata for verifiers page
+const environmentText = environment === Environment.Mainnet ? "Mainnet" : "Testnet"
+const verifiersMetadata = {
+ title: `CCIP Verifiers - ${environmentText} Networks`,
+ description: `View all CCIP verifiers across ${environmentText} networks. Explore ${allVerifiers.length} verifiers, their addresses, types, and supported networks for cross-chain verification.`,
+ image: "/assets/product-logos/ccip-logo.svg",
+ excerpt: `CCIP verifiers ${environmentText.toLowerCase()} networks addresses types committee api cross-chain verification blockchain interoperability`,
+}
+
+// Generate structured data for verifiers page
+const currentPath = new URL(Astro.request.url).pathname
+const canonicalForJsonLd = `${DOCS_BASE_URL}${currentPath}`
+---
+
+
+
+
+
+
diff --git a/src/components/CCIP/Verifiers/Verifiers.css b/src/components/CCIP/Verifiers/Verifiers.css
new file mode 100644
index 00000000000..eda464e886c
--- /dev/null
+++ b/src/components/CCIP/Verifiers/Verifiers.css
@@ -0,0 +1,43 @@
+.layout {
+ margin: 0 auto;
+ padding: var(--space-6x);
+}
+
+.layout h2 {
+ color: var(--gray-900);
+ font-size: 22px;
+ line-height: var(--space-10x);
+ padding-bottom: var(--space-4x);
+ border-bottom: 1px solid var(--gray-200);
+ margin-bottom: var(--space-6x);
+}
+
+.layout h2 span {
+ color: var(--gray-400);
+ font-weight: 600;
+ letter-spacing: 0.5px;
+}
+
+.networks__grid {
+ display: grid;
+ grid-template-columns: 1fr;
+ gap: var(--space-8x);
+}
+
+.tokens__grid {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: var(--space-8x);
+}
+
+@media (min-width: 50em) {
+ .layout {
+ max-width: 1500px;
+ }
+}
+
+@media (min-width: 992px) {
+ .layout {
+ padding: var(--space-10x) var(--space-8x);
+ }
+}
diff --git a/src/components/Cards/Card.astro b/src/components/Cards/Card.astro
new file mode 100644
index 00000000000..c1331668d75
--- /dev/null
+++ b/src/components/Cards/Card.astro
@@ -0,0 +1,17 @@
+---
+import CardLink from "./CardLink.astro"
+import styles from "./cards.module.css"
+import { ICard } from "./types"
+
+type Props = ICard
+
+const { title, description, links } = Astro.props
+---
+
+
+
{title}
+
{description}
+
+ {links && links.map((l) => )}
+
+
diff --git a/src/components/Cards/CardLink.astro b/src/components/Cards/CardLink.astro
new file mode 100644
index 00000000000..032a29adc02
--- /dev/null
+++ b/src/components/Cards/CardLink.astro
@@ -0,0 +1,27 @@
+---
+import styles from "./cards.module.css"
+import { ILink } from "./types"
+
+import tokenIcon from "../../assets/icons/token-icon.svg"
+import remixIcon from "../../assets/icons/remix-logo.svg"
+
+interface Props {
+ link: ILink
+}
+
+const { link } = Astro.props
+
+const iconMap = {
+ token: tokenIcon,
+ remix: remixIcon,
+}
+
+const iconSrc = iconMap[link.icon]
+---
+
+
+
+
+ {link.label}
+
+
diff --git a/src/components/Cards/CardsWrapper.astro b/src/components/Cards/CardsWrapper.astro
new file mode 100644
index 00000000000..cb91045a25d
--- /dev/null
+++ b/src/components/Cards/CardsWrapper.astro
@@ -0,0 +1,15 @@
+---
+import Card from "./Card.astro"
+import styles from "./cards.module.css"
+import { ICard } from "./types.ts"
+
+interface Props {
+ links: ICard[]
+}
+
+const { links } = Astro.props
+---
+
+
+ {links.map((link) => )}
+
diff --git a/src/components/Cards/cards.module.css b/src/components/Cards/cards.module.css
new file mode 100644
index 00000000000..db4e076ab55
--- /dev/null
+++ b/src/components/Cards/cards.module.css
@@ -0,0 +1,66 @@
+.cardsWrapper {
+ display: grid;
+ grid-template-columns: repeat(3, 1fr);
+ border-left: 1px solid var(--border);
+ border-top: 1px solid var(--border);
+}
+
+.cardsWrapper h6 {
+ font-size: 18px;
+ margin-bottom: var(--space-4x);
+}
+
+:where(.cardsWrapper p) {
+ font-size: 14px;
+ line-height: 24px; /* 171.429% */
+}
+
+.card {
+ padding: var(--space-5x) var(--space-6x);
+ background: #fff;
+ border-right: 1px solid var(--border);
+ border-bottom: 1px solid var(--border);
+}
+
+.card:hover {
+ background: var(--gray-100);
+}
+
+.links {
+ display: flex;
+ flex-direction: column;
+ margin-top: var(--space-6x);
+ gap: var(--space-4x);
+}
+
+.link {
+ color: var(--Color-Primary, #0e1119);
+ display: flex;
+ gap: var(--space-2x);
+ align-items: center;
+ cursor: default;
+}
+
+.link:hover span {
+ opacity: 0.7;
+}
+
+.cardTitle {
+ font-weight: 525;
+ margin-bottom: var(--space-4x);
+ font-size: 18px;
+ color: var(--foreground);
+}
+
+@media screen and (max-width: 768px) {
+ .cardsWrapper {
+ grid-template-columns: repeat(2, 1fr) !important;
+ }
+}
+
+@media screen and (max-width: 600px) {
+ .cardsWrapper {
+ grid-template-columns: repeat(1, 1fr) !important;
+ margin-top: 0;
+ }
+}
diff --git a/src/components/Cards/types.ts b/src/components/Cards/types.ts
new file mode 100644
index 00000000000..20007518bc0
--- /dev/null
+++ b/src/components/Cards/types.ts
@@ -0,0 +1,12 @@
+export type IconType = "token" | "remix"
+
+export interface ILink {
+ icon: IconType
+ href: string
+ label: string
+}
+export interface ICard {
+ title: string
+ description: string
+ links?: ILink[]
+}
diff --git a/src/components/ChangelogSnippet/ChangelogCard.astro b/src/components/ChangelogSnippet/ChangelogCard.astro
new file mode 100644
index 00000000000..a22d05ad2bd
--- /dev/null
+++ b/src/components/ChangelogSnippet/ChangelogCard.astro
@@ -0,0 +1,313 @@
+---
+import { SvgTaillessArrowDownSmall, Typography } from "@chainlink/blocks"
+import styles from "./ChangelogCard.module.css"
+import type { ChangelogItem } from "./types"
+
+interface Props {
+ item: ChangelogItem
+}
+
+const { item } = Astro.props
+
+// Format the date
+const formatDate = (dateString: string) => {
+ const date = new Date(dateString)
+ return date.toLocaleDateString("en-US", {
+ year: "numeric",
+ month: "short",
+ day: "numeric",
+ })
+}
+
+const formattedDate = formatDate(item["date-of-release"])
+---
+
+
+
+
+
+
+
+ {item.name}
+
+
+
+ {item["text-description"] &&
}
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/ChangelogSnippet/ChangelogCard.module.css b/src/components/ChangelogSnippet/ChangelogCard.module.css
new file mode 100644
index 00000000000..7e3dda0edeb
--- /dev/null
+++ b/src/components/ChangelogSnippet/ChangelogCard.module.css
@@ -0,0 +1,150 @@
+/* Card Wrapper */
+.cardWrapper {
+ max-height: 400px;
+ overflow: hidden;
+ transition: max-height 0.5s ease;
+ position: relative;
+ border: 1px solid var(--border);
+}
+
+/* Card Container */
+.card {
+ display: flex;
+ gap: 82px;
+ padding: var(--space-6x);
+}
+
+.cardWrapper.expanded .card {
+ -webkit-mask-image: none;
+ mask-image: none;
+}
+
+.cardWrapper:hover {
+ background-color: var(--muted);
+
+ & .contentFooter {
+ background: linear-gradient(to top, var(--muted) 50%, transparent);
+ }
+}
+
+/* Header Section */
+.header {
+ display: flex;
+ justify-content: space-between;
+ align-items: flex-start;
+ gap: var(--space-4x);
+ margin-bottom: var(--space-3x);
+}
+
+.metaSection {
+ display: flex;
+ flex-direction: column;
+ gap: var(--space-1x);
+ flex: 1;
+}
+
+/* Description Section */
+.description {
+ display: flex;
+ flex-direction: column;
+ gap: var(--space-3x);
+ line-height: 1.6;
+ margin-top: var(--space-3x);
+}
+
+.description p {
+ margin: 0;
+ color: var(--foreground);
+}
+
+.description a {
+ color: var(--color-blue-600);
+ text-decoration: none;
+}
+
+.description a:hover {
+ text-decoration: underline;
+}
+
+.header {
+ display: flex;
+ width: 150px;
+}
+
+.content {
+ display: flex;
+ flex-direction: column;
+ flex: 1;
+}
+
+/* Description Content */
+.descriptionContent {
+ flex: 1;
+}
+
+/* Content Footer */
+.contentFooter {
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ z-index: 10;
+ height: calc(var(--space-6x) + 68px);
+ display: flex;
+ align-items: end;
+ background: linear-gradient(to top, white 50%, transparent);
+ opacity: 0;
+ pointer-events: none;
+ transition: opacity 0.2s ease-in-out;
+}
+
+/* Expand Button */
+.expandButton {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ padding: 0;
+ background: none;
+ border: none;
+ color: var(--foreground);
+ font-size: 14px;
+ font-weight: 600;
+ transition: color 0.2s ease;
+ cursor: default;
+ margin-left: 256px;
+ margin-bottom: var(--space-6x);
+}
+
+.expandButton svg {
+ transition: transform 0.3s ease;
+}
+
+@media (max-width: 768px) {
+ .card {
+ padding: var(--space-4x);
+ flex-direction: column;
+ gap: var(--space-4x);
+ }
+
+ .header {
+ gap: var(--space-3x);
+ width: 100%;
+ }
+
+ .metaSection {
+ gap: var(--space-1x);
+ }
+
+ .expandButton {
+ margin-left: 0;
+ }
+
+ .cardWrapper.expanded .card {
+ -webkit-mask-image: none;
+ mask-image: none;
+ }
+
+ .contentFooter {
+ padding-left: var(--space-4x);
+ }
+}
diff --git a/src/components/ChangelogSnippet/ChangelogSnippet.astro b/src/components/ChangelogSnippet/ChangelogSnippet.astro
new file mode 100644
index 00000000000..aa2930cb346
--- /dev/null
+++ b/src/components/ChangelogSnippet/ChangelogSnippet.astro
@@ -0,0 +1,65 @@
+---
+import { SvgArrowRight2, Typography } from "@chainlink/blocks"
+import { SearchClient, searchClient } from "@algolia/client-search"
+import ChangelogCard from "./ChangelogCard.astro"
+import { AlgoliaQuery, type ChangelogItem } from "./types"
+import styles from "./ChangelogSnippet.module.css"
+import { getSecret } from "astro:env/server"
+
+interface Props {
+ query: AlgoliaQuery
+}
+
+const { query } = Astro.props
+
+const appId = getSecret("ALGOLIA_APP_ID")
+const apiKey = getSecret("PUBLIC_ALGOLIA_SEARCH_PUBLIC_API_KEY")
+
+let client: SearchClient
+let latestLog: ChangelogItem | undefined = undefined
+
+// Initialize client if appId and apiKey are available to avoid needing to update
+// the github actions with the new keys (satisfies linkcheck-internal)
+if (appId && apiKey) {
+ client = searchClient(appId, apiKey)
+
+ const req = await client.search({
+ requests: [
+ {
+ indexName: "Changelog",
+ restrictSearchableAttributes: ["topic"],
+ query,
+ hitsPerPage: 1,
+ },
+ ],
+ })
+
+ const firstResult = req.results[0]
+ const results = "hits" in firstResult ? (firstResult.hits as ChangelogItem[]) : []
+
+ // logs are returned sorted by created_at DESC
+ latestLog = results[0]
+}
+---
+
+{
+ latestLog && (
+
+ )
+}
diff --git a/src/components/ChangelogSnippet/ChangelogSnippet.module.css b/src/components/ChangelogSnippet/ChangelogSnippet.module.css
new file mode 100644
index 00000000000..d852a20cba5
--- /dev/null
+++ b/src/components/ChangelogSnippet/ChangelogSnippet.module.css
@@ -0,0 +1,46 @@
+.container {
+ display: flex;
+ flex-direction: column;
+ gap: var(--space-6x);
+}
+
+.grid {
+ display: grid;
+ grid-template-columns: repeat(3, 1fr);
+ gap: var(--space-4x);
+}
+
+.sectionHeader {
+ display: flex;
+ gap: var(--space-4x);
+ align-items: end;
+}
+
+.arrow {
+ padding: 10px;
+ border: 1px solid var(--border);
+ height: fit-content;
+ cursor: default;
+ &:hover {
+ border: 1px solid var(--foreground);
+ }
+}
+
+@media (max-width: 1024px) {
+ .grid {
+ grid-template-columns: repeat(2, 1fr);
+ }
+}
+
+@media (max-width: 768px) {
+ .grid {
+ grid-template-columns: 1fr;
+ }
+}
+
+@media screen and (max-width: 480px) {
+ .sectionHeader {
+ justify-content: space-between;
+ width: 100%;
+ }
+}
diff --git a/src/components/ChangelogSnippet/README.md b/src/components/ChangelogSnippet/README.md
new file mode 100644
index 00000000000..bce2e2505ae
--- /dev/null
+++ b/src/components/ChangelogSnippet/README.md
@@ -0,0 +1,37 @@
+# ChangelogSnippet Component
+
+## What This Component Does
+
+The ChangelogSnippet component displays the most recent changelog entry for a specific product or topic. It searches through changelog entries and shows the latest update in a card format with an expandable description.
+
+## How to Use It
+
+Import the component into your MDX file and provide a search query:
+
+```astro
+import ChangelogSnippet from "@components/ChangelogSnippet/ChangelogSnippet.astro"
+
+
+```
+
+## Props
+
+| Prop | Type | Required | Description |
+| ------- | ------ | -------- | ------------------------------------------------------------------------------------------- |
+| `query` | string | Yes | The search term used to find relevant changelog entries (e.g., "ccip", "vrf", "automation") |
+
+## Complete Example
+
+Here's a full example of using the component in your documentation page:
+
+```astro
+---
+import ChangelogSnippet from "@components/ChangelogSnippet/ChangelogSnippet.astro"
+---
+
+# CCIP Documentation Learn about Cross-Chain Interoperability Protocol.
+
+
+```
+
+This will display the latest CCIP-related changelog entry with a link to view the full changelog.
diff --git a/src/components/ChangelogSnippet/types.ts b/src/components/ChangelogSnippet/types.ts
new file mode 100644
index 00000000000..870c3afd23b
--- /dev/null
+++ b/src/components/ChangelogSnippet/types.ts
@@ -0,0 +1,31 @@
+export type AlgoliaQuery =
+ | "ccip"
+ | "data-streams"
+ | "smart-data"
+ | "nodes"
+ | "data-feeds"
+ | "functions"
+ | "automation"
+ | "vrf"
+ | "general"
+
+export interface ChangelogItem {
+ createdOn: string
+ "date-of-release": string
+ hash: string
+ id: string
+ lastPublished: string
+ lastUpdated: string
+ name: string
+ networks: string
+ slug: string
+ "text-description": string
+ topic: string
+ type: string
+ objectID: string
+ _highlightResult?: {
+ "date-of-release": Record
+ name: Record
+ "text-description": Record
+ }
+}
diff --git a/src/components/CodeSample/CodeSample.astro b/src/components/CodeSample/CodeSample.astro
index 73cef4f4cb2..8ffa36e46b8 100644
--- a/src/components/CodeSample/CodeSample.astro
+++ b/src/components/CodeSample/CodeSample.astro
@@ -10,8 +10,9 @@ export type Props = {
showButtonOnly?: boolean
optimize?: boolean
runs?: number
+ showButtons?: boolean
}
-const { src, lang, showButtonOnly, optimize, runs } = Astro.props as Props
+const { src, lang, showButtonOnly, optimize, runs, showButtons = true } = Astro.props as Props
const data = (await fs.readFile(path.join(process.cwd(), "public", src), "utf-8")).toString()
@@ -31,7 +32,7 @@ const remixUrl = `https://remix.ethereum.org/#url=https://docs.chain.link/${clea
{!showButtonOnly && }
{
- isSample && (
+ isSample && showButtons && (
Open in Remix
diff --git a/src/components/CodeSample/CodeSampleReact.tsx b/src/components/CodeSample/CodeSampleReact.tsx
index 4b17738649b..687e13ade30 100644
--- a/src/components/CodeSample/CodeSampleReact.tsx
+++ b/src/components/CodeSample/CodeSampleReact.tsx
@@ -13,7 +13,6 @@ export const CodeSampleReact: React.FC = ({ src, showButto
const isSolidityFile = src.match(/\.sol/)
const isSample = isSolidityFile && (src.indexOf("samples/") === 0 || src.indexOf("/samples/") === 0)
-
if (!isSample || !showButtonOnly || !remixUrl) return null
return (
diff --git a/src/components/CommunityEvents/CommunityEvents.astro b/src/components/CommunityEvents/CommunityEvents.astro
new file mode 100644
index 00000000000..2d31b6a0945
--- /dev/null
+++ b/src/components/CommunityEvents/CommunityEvents.astro
@@ -0,0 +1,110 @@
+---
+import { SvgArrowRight2, Typography } from "@chainlink/blocks"
+import EventCard from "./EventCard.astro"
+import ImageGallery from "./ImageGallery.astro"
+import type { GalleryImage } from "./types"
+import { fetchEventsFromRSS } from "./fetchEvents"
+import styles from "./CommunityEvents.module.css"
+
+// Community event gallery images
+const galleryImages: GalleryImage[] = [
+ // Top row - scrolls left
+ {
+ id: "1",
+ imageUrl:
+ "https://cdn.prod.website-files.com/64cc2c23d8dbd707cdb556d8/677d1da974d919ae98a3bd59_home-community-5.webp",
+ alt: "Chainlink community event",
+ },
+ {
+ id: "2",
+ imageUrl:
+ "https://cdn.prod.website-files.com/64cc2c23d8dbd707cdb556d8/677d1da974d919ae98a3bd55_home-community-2.webp",
+ alt: "Chainlink community event",
+ },
+ {
+ id: "3",
+ imageUrl:
+ "https://cdn.prod.website-files.com/64cc2c23d8dbd707cdb556d8/677d1da974d919ae98a3bd30_home-community-4.webp",
+ alt: "Chainlink community event",
+ },
+ {
+ id: "4",
+ imageUrl:
+ "https://cdn.prod.website-files.com/64cc2c23d8dbd707cdb556d8/677d1da974d919ae98a3bd46_home-community-11.webp",
+ alt: "Chainlink community event",
+ },
+ {
+ id: "5",
+ imageUrl:
+ "https://cdn.prod.website-files.com/64cc2c23d8dbd707cdb556d8/677d1da974d919ae98a3bd51_home-community-3.webp",
+ alt: "Chainlink community event",
+ },
+ {
+ id: "6",
+ imageUrl:
+ "https://cdn.prod.website-files.com/64cc2c23d8dbd707cdb556d8/677d1da974d919ae98a3bd42_home-community-10.webp",
+ alt: "Chainlink community event",
+ },
+ // Bottom row - scrolls right
+ {
+ id: "7",
+ imageUrl:
+ "https://cdn.prod.website-files.com/64cc2c23d8dbd707cdb556d8/677d1da974d919ae98a3bd24_community-photo-12.webp",
+ alt: "Chainlink community event",
+ },
+ {
+ id: "8",
+ imageUrl:
+ "https://cdn.prod.website-files.com/64cc2c23d8dbd707cdb556d8/677d1da974d919ae98a3bd2b_community-photo-10.webp",
+ alt: "Chainlink community event",
+ },
+ {
+ id: "9",
+ imageUrl:
+ "https://cdn.prod.website-files.com/64cc2c23d8dbd707cdb556d8/677d1da974d919ae98a3bd4c_community-photo-24.webp",
+ alt: "Chainlink community event",
+ },
+ {
+ id: "10",
+ imageUrl:
+ "https://cdn.prod.website-files.com/64cc2c23d8dbd707cdb556d8/677d1da974d919ae98a3bd3d_community-photo-22.webp",
+ alt: "Chainlink community event",
+ },
+ {
+ id: "11",
+ imageUrl:
+ "https://cdn.prod.website-files.com/64cc2c23d8dbd707cdb556d8/677d1da974d919ae98a3bd36_community-photo-30.webp",
+ alt: "Chainlink community event",
+ },
+]
+
+const events = await fetchEventsFromRSS()
+---
+
+
+
+
+
+
+ {events.map((event) => )}
+
+
+
+
+
+
+
+
diff --git a/src/components/CommunityEvents/CommunityEvents.module.css b/src/components/CommunityEvents/CommunityEvents.module.css
new file mode 100644
index 00000000000..562ac07105c
--- /dev/null
+++ b/src/components/CommunityEvents/CommunityEvents.module.css
@@ -0,0 +1,87 @@
+.wrapper {
+ margin: 86px 0;
+}
+.component {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ grid-template-rows: auto;
+ grid-auto-columns: 1fr;
+ align-items: center;
+ gap: 33px;
+ width: 100%;
+}
+
+.contentLeft {
+ justify-self: end;
+ width: 100%;
+ max-width: calc(var(--fullwidth-max-width) / 2);
+ padding-left: var(--space-10x);
+}
+
+.contentRight {
+ display: flex;
+ align-items: center;
+ overflow: hidden;
+}
+
+.sectionHeader {
+ display: flex;
+ gap: var(--space-4x);
+ align-items: end;
+ max-width: var(--fullwidth-max-width);
+ margin-bottom: var(--space-8x);
+ margin-left: auto;
+ margin-right: auto;
+ padding: 0 var(--space-10x);
+}
+
+.arrow {
+ padding: 10px;
+ border: 1px solid var(--border);
+ height: fit-content;
+ cursor: pointer;
+ transition: border-color 0.2s ease;
+}
+
+.arrow:hover {
+ border: 1px solid var(--foreground);
+}
+
+.eventList {
+ display: flex;
+ flex-direction: column;
+ gap: var(--space-6x);
+}
+
+/* Tablet */
+@media (max-width: 1024px) {
+ .component {
+ display: flex;
+ flex-direction: column-reverse;
+ }
+
+ .contentRight {
+ margin-left: 0;
+ width: 100%;
+ }
+
+ .contentLeft {
+ max-width: 100%;
+ }
+}
+
+/* Mobile */
+@media (max-width: 768px) {
+ .sectionHeader {
+ margin-bottom: var(--space-6x);
+ margin-left: unset;
+ margin-right: unset;
+ & > h2 {
+ font-size: 28px;
+ }
+ }
+
+ .wrapper {
+ margin: 36px 0;
+ }
+}
diff --git a/src/components/CommunityEvents/EventCard.astro b/src/components/CommunityEvents/EventCard.astro
new file mode 100644
index 00000000000..4bf52bef5a0
--- /dev/null
+++ b/src/components/CommunityEvents/EventCard.astro
@@ -0,0 +1,32 @@
+---
+import { SvgArrowRight2, Typography } from "@chainlink/blocks"
+import type { CommunityEvent } from "./types"
+import styles from "./EventCard.module.css"
+
+interface Props {
+ event: CommunityEvent
+}
+
+const { event } = Astro.props
+---
+
+
+
+ {event.month}
+ {event.day}
+
+
+
+
+
+
+
{event.location}
+
+
+
+ {event.title}
+
+
+
+
+
diff --git a/src/components/CommunityEvents/EventCard.module.css b/src/components/CommunityEvents/EventCard.module.css
new file mode 100644
index 00000000000..4613acc0971
--- /dev/null
+++ b/src/components/CommunityEvents/EventCard.module.css
@@ -0,0 +1,80 @@
+.eventCardLink {
+ display: flex;
+ align-items: center;
+ gap: var(--space-4x);
+ border-radius: 0.5rem;
+ text-decoration: none;
+ transition: all 0.3s ease;
+ background-color: var(--background);
+}
+
+.eventCardLink:hover .eventCardH {
+ color: var(--brand) !important;
+}
+
+.eventCardLink:hover .linkArr {
+ opacity: 1 !important;
+}
+
+.eventDate {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ padding: var(--space-2x) var(--space-5x);
+ flex-shrink: 0;
+ border: 1px solid var(--border);
+ background-color: var(--muted);
+}
+
+.eventCardDesc {
+ display: flex;
+ flex-direction: column;
+ gap: var(--space-2x);
+ flex: 1;
+ min-width: 0;
+}
+
+.eventCardCountry {
+ display: flex;
+ align-items: center;
+ gap: var(--space-2x);
+}
+
+.eventCardFlag {
+ width: 16px;
+ max-width: 16px;
+ height: 16px;
+ border-radius: 100%;
+ overflow: hidden;
+ flex-shrink: 0;
+ position: relative;
+}
+
+.coverImg {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+ display: block;
+}
+
+.eventCardCountryName {
+ text-transform: uppercase;
+ color: var(--gray-600);
+}
+
+.eventCardHWrap {
+ display: flex;
+ align-items: baseline;
+ gap: var(--space-3x);
+}
+
+.linkArr {
+ opacity: 0;
+}
+
+@media (max-width: 768px) {
+ .eventCardLink {
+ gap: var(--space-3x);
+ }
+}
diff --git a/src/components/CommunityEvents/ImageGallery.astro b/src/components/CommunityEvents/ImageGallery.astro
new file mode 100644
index 00000000000..20c0f26e5ee
--- /dev/null
+++ b/src/components/CommunityEvents/ImageGallery.astro
@@ -0,0 +1,42 @@
+---
+import type { GalleryImage } from "./types"
+import styles from "./ImageGallery.module.css"
+
+interface Props {
+ images: GalleryImage[]
+}
+
+const { images } = Astro.props
+
+// Split images into two rows for the gallery
+const topRowImages = images.slice(0, Math.ceil(images.length / 2))
+const bottomRowImages = images.slice(Math.ceil(images.length / 2))
+
+// Duplicate images for seamless infinite scroll
+const topRowDuplicated = [...topRowImages, ...topRowImages]
+const bottomRowDuplicated = [...bottomRowImages, ...bottomRowImages]
+---
+
+
+
+
+ {
+ topRowDuplicated.map((image) => (
+
+
+
+ ))
+ }
+
+
+
+
+ {
+ bottomRowDuplicated.map((image) => (
+
+
+
+ ))
+ }
+
+
diff --git a/src/components/CommunityEvents/ImageGallery.module.css b/src/components/CommunityEvents/ImageGallery.module.css
new file mode 100644
index 00000000000..edc1af53337
--- /dev/null
+++ b/src/components/CommunityEvents/ImageGallery.module.css
@@ -0,0 +1,70 @@
+.gallery {
+ width: 100%;
+ display: flex;
+ flex-direction: column;
+ gap: var(--space-5x);
+ overflow: hidden;
+}
+
+.row {
+ display: flex;
+ gap: var(--space-5x);
+ animation: scrollLeft 30s linear infinite;
+ flex-shrink: 0;
+}
+
+.rowReverse {
+ animation: scrollRight 30s linear infinite;
+}
+
+.imageWrapper {
+ width: 16rem;
+ height: 12rem;
+ flex-shrink: 0;
+ border-radius: 0.5rem;
+ overflow: hidden;
+ position: relative;
+}
+
+.image {
+ object-fit: cover;
+ border-radius: 0.5rem;
+ width: 100%;
+ height: 100%;
+ position: absolute;
+ inset: 0;
+}
+
+@keyframes scrollLeft {
+ 0% {
+ transform: translate3d(0%, 0px, 0px);
+ }
+ 100% {
+ transform: translate3d(-50%, 0px, 0px);
+ }
+}
+
+@keyframes scrollRight {
+ 0% {
+ transform: translate3d(-50%, 0px, 0px);
+ }
+ 100% {
+ transform: translate3d(0%, 0px, 0px);
+ }
+}
+
+/* Pause animation on hover */
+.gallery:hover .row {
+ animation-play-state: paused;
+}
+
+@media (max-width: 1024px) {
+ .imageWrapper {
+ width: 12rem;
+ height: 9rem;
+ }
+
+ .gallery {
+ padding: 0 var(--space-10x);
+ }
+}
diff --git a/src/components/CommunityEvents/fetchEvents.ts b/src/components/CommunityEvents/fetchEvents.ts
new file mode 100644
index 00000000000..09ee45fbbef
--- /dev/null
+++ b/src/components/CommunityEvents/fetchEvents.ts
@@ -0,0 +1,53 @@
+import type { CommunityEvent } from "./types.ts"
+
+// Fetch events from Webflow RSS feed
+export const fetchEventsFromRSS = async (): Promise => {
+ try {
+ const response = await fetch("https://chain.link/events-coll/rss.xml")
+ const xml = await response.text()
+
+ // Parse RSS XML manually (lightweight approach without xml2js dependency)
+ const items = xml.match(/- [\s\S]*?<\/item>/g) || []
+ const now = new Date()
+ now.setHours(0, 0, 0, 0) // Set to start of today to include today's events
+
+ const events = items
+ .map((item, index) => {
+ const title = item.match(/
(.*?)<\/title>/)?.[1] || ""
+ const pubDate = item.match(/(.*?)<\/pubDate>/)?.[1] || ""
+ const description = item.match(/(.*?)<\/description>/)?.[1] || ""
+ const mediaContent = item.match(/ s.trim())
+ const location = descParts[2] || "Virtual"
+ const eventUrl = descParts[3] || ""
+
+ // Parse date
+ const dateObj = new Date(pubDate)
+ const month = dateObj.toLocaleDateString("en-US", { month: "short" })
+ const day = dateObj.getDate().toString()
+
+ return {
+ id: index.toString(),
+ title: title.replace(/&/g, "&"),
+ date: dateObj.toISOString(),
+ month,
+ day,
+ location,
+ country: location,
+ flagUrl: mediaContent,
+ eventUrl,
+ backgroundColor: "rgb(12, 22, 44)",
+ }
+ })
+ .filter((event) => new Date(event.date) >= now) // Filter out past events
+ .sort((a, b) => new Date(a.date).getTime() - new Date(b.date).getTime()) // Sort ascending (closest first)
+ .slice(0, 3) // Only take the first 3 events
+
+ return events
+ } catch (error) {
+ console.error("Error fetching events:", error)
+ return []
+ }
+}
diff --git a/src/components/CommunityEvents/types.ts b/src/components/CommunityEvents/types.ts
new file mode 100644
index 00000000000..ab6910a200d
--- /dev/null
+++ b/src/components/CommunityEvents/types.ts
@@ -0,0 +1,18 @@
+export interface CommunityEvent {
+ id: string
+ title: string
+ date: string // ISO date string
+ month: string
+ day: string
+ location: string
+ country: string
+ flagUrl: string
+ eventUrl: string
+ backgroundColor?: string
+}
+
+export interface GalleryImage {
+ id: string
+ imageUrl: string
+ alt: string
+}
diff --git a/src/components/Demos.astro b/src/components/Demos.astro
new file mode 100644
index 00000000000..0cf482cfe2e
--- /dev/null
+++ b/src/components/Demos.astro
@@ -0,0 +1,90 @@
+---
+import { Tag, Typography } from "@chainlink/blocks"
+import styles from "./Demos.module.css"
+
+export interface Demo {
+ image: string
+ title: string
+ description: string
+ tags: string[]
+ href: string
+}
+
+const demos: Demo[] = [
+ {
+ image: "/images/demos/Demos thumbnails 1.png",
+ title: "Custom Data Feed",
+ description:
+ "See how you can bring your financial data onchain in a variety of different ways by creating a Net Asset Value feed, Proof of Reserve feed, or other custom data feed.",
+ tags: ["CRE", "DATA FEEDS"],
+ href: "/",
+ },
+ {
+ image: "/images/demos/Demos thumbnails 2.png",
+ title: "Delivery vs. Payment (DvP)",
+ description:
+ "Learn how to sell a variety of assets via a Delivery vs. Payment transaction using the Chainlink Runtime Environment (CRE).",
+ tags: ["CRE"],
+ href: "/",
+ },
+ {
+ image: "/images/demos/Demos thumbnails 3.png",
+ title: "Digital Transfer Agent (DTA)",
+ description:
+ "Learn how to invest in a variety of funds via a Digital Transfer Agent (DTA) transaction using the Chainlink Runtime Environment (CRE).",
+ tags: ["CRE"],
+ href: "/",
+ },
+ {
+ image: "/images/demos/Demos thumbnails 4.png",
+ title: "Explore Chainlink",
+ description: "Explore how the Chainlink standard powers tokenization and onchain finance through",
+ tags: ["CRE", "CCIP", "DATA FEEDS"],
+ href: "/",
+ },
+]
+---
+
+
diff --git a/src/components/Demos.module.css b/src/components/Demos.module.css
new file mode 100644
index 00000000000..37371d59041
--- /dev/null
+++ b/src/components/Demos.module.css
@@ -0,0 +1,99 @@
+.demosSection {
+ width: 100%;
+ display: flex;
+ flex-direction: column;
+ gap: var(--space-6x);
+
+ & > h2 {
+ font-size: 28px;
+ }
+}
+
+.grid {
+ display: grid;
+ grid-template-columns: repeat(4, 1fr);
+ border: 1px solid var(--border);
+}
+
+.card {
+ display: flex;
+ flex-direction: column;
+ padding: var(--space-6x);
+ overflow: hidden;
+ transition: box-shadow 0.2s ease;
+ gap: var(--space-4x);
+
+ &:hover {
+ background-color: var(--muted);
+ }
+
+ &:hover .footerTag {
+ background-color: var(--background);
+ }
+
+ &:hover .footerArrow {
+ opacity: 1;
+ }
+}
+
+.card:not(:last-child) {
+ border-right: 1px solid var(--border);
+}
+
+.imageContainer {
+ width: 100%;
+ aspect-ratio: 16 / 9;
+ overflow: hidden;
+}
+
+.image {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+}
+
+.body {
+ margin-bottom: var(--space-4x);
+}
+.content {
+ display: flex;
+ flex-direction: column;
+ gap: var(--space-4x);
+ flex: 1;
+}
+
+.tags {
+ display: flex;
+ flex-wrap: wrap;
+ gap: var(--space-1x);
+}
+
+.footer {
+ display: flex;
+ justify-content: space-between;
+
+ margin-top: auto;
+ padding-top: var(--space-4x);
+}
+
+.footerArrow {
+ opacity: 0;
+ display: flex;
+ align-items: end;
+}
+@media screen and (max-width: 1024px) {
+ .grid {
+ grid-template-columns: repeat(2, 1fr);
+ }
+}
+
+@media screen and (max-width: 570px) {
+ .grid {
+ grid-template-columns: repeat(1, 1fr);
+ }
+
+ .card:not(:last-child) {
+ border-bottom: 1px solid var(--border);
+ border-right: none;
+ }
+}
diff --git a/src/components/DocsHeaderTitle/DocsHeaderTitle.astro b/src/components/DocsHeaderTitle/DocsHeaderTitle.astro
new file mode 100644
index 00000000000..81ec51634ed
--- /dev/null
+++ b/src/components/DocsHeaderTitle/DocsHeaderTitle.astro
@@ -0,0 +1,24 @@
+---
+import { getNavigationProps } from "../Header/getNavigationProps"
+import { isMatchedPath } from "../Header/Nav/isMatchedPath"
+import defaultLogo from "../../assets/product-logos/default-logo.svg"
+import styles from "./docsHeaderTitle.module.css"
+const { subProductsNav } = getNavigationProps()
+import { Typography } from "@chainlink/blocks"
+
+interface Props {
+ pathname: string
+}
+
+const { pathname } = Astro.props
+
+const subProductTrigger = subProductsNav?.find(({ href }) => isMatchedPath(pathname, href))
+
+const label = subProductTrigger?.label || "Resources"
+const icon = subProductTrigger?.label ? subProductTrigger.icon : defaultLogo.src
+---
+
+
diff --git a/src/components/DocsHeaderTitle/docsHeaderTitle.module.css b/src/components/DocsHeaderTitle/docsHeaderTitle.module.css
new file mode 100644
index 00000000000..f0f9443a1f0
--- /dev/null
+++ b/src/components/DocsHeaderTitle/docsHeaderTitle.module.css
@@ -0,0 +1,11 @@
+.logo {
+ width: var(--space-6x);
+ height: var(--space-6x);
+}
+
+.docsHeaderTitleWrapper {
+ display: flex;
+ align-items: center;
+ gap: var(--space-3x);
+ padding: var(--doc-padding) 0;
+}
diff --git a/src/components/DocsNavigation/DocsNavigationDesktop/DocsNavigationDesktop.tsx b/src/components/DocsNavigation/DocsNavigationDesktop/DocsNavigationDesktop.tsx
index f1a88b5395f..bf09832475c 100644
--- a/src/components/DocsNavigation/DocsNavigationDesktop/DocsNavigationDesktop.tsx
+++ b/src/components/DocsNavigation/DocsNavigationDesktop/DocsNavigationDesktop.tsx
@@ -1,6 +1,5 @@
import { clsx } from "~/lib/clsx/clsx.ts"
import { useNavBar } from "../../Header/useNavBar/useNavBar.ts"
-import DocsPickerDesktop from "./DocsPickerDesktop.tsx"
import styles from "./docsNavigationDesktop.module.css"
import QuickLinksModal from "../../Header/Nav/QuickLinksModal.tsx"
import { useState } from "react"
@@ -29,10 +28,7 @@ function DocsNavigationDesktop({
})}
>
-
-
- {children}
-
+
{children}
{isCcipPage ? (
/* Custom links for CCIP Directory pages */
diff --git a/src/components/DocsNavigation/DocsNavigationDesktop/DocsPickerDesktop.tsx b/src/components/DocsNavigation/DocsNavigationDesktop/DocsPickerDesktop.tsx
deleted file mode 100644
index feb8d80bcfb..00000000000
--- a/src/components/DocsNavigation/DocsNavigationDesktop/DocsPickerDesktop.tsx
+++ /dev/null
@@ -1,63 +0,0 @@
-import { useState } from "react"
-import { isMatchedPath } from "../../Header/Nav/isMatchedPath.ts"
-import { getNavigationProps } from "../../Header/getNavigationProps.ts"
-import styles from "./docsPickerDesktop.module.css"
-import { clsx } from "../../Header/Nav/utils.ts"
-import defaultLogo from "../../../assets/product-logos/default-logo.svg"
-
-function DocsPickerDesktop({ pathname }: { pathname: string }) {
- const [productMenuOpen, setProductMenuOpen] = useState(false)
- const { subProductsNav } = getNavigationProps()
-
- const subProductTrigger = subProductsNav?.find(({ href }) => isMatchedPath(pathname, href))
-
- const label = subProductTrigger?.label || "Resources"
- const icon = subProductTrigger?.label ? subProductTrigger.icon : defaultLogo.src
-
- return (
-
setProductMenuOpen(true)}
- onMouseLeave={() => setProductMenuOpen(false)}
- >
-
-
{label}
-
-
-
- {productMenuOpen && (
-
-
- {subProductsNav
- .filter((item) => !item.hideFromDropdown && item.col === 1)
- .map((item) => (
-
-
-
- {item.label}
-
-
- ))}
-
-
- {subProductsNav
- .filter((item) => !item.hideFromDropdown && item.col === 2)
- .map((item) => (
-
-
-
- {item.label}
-
-
- ))}
-
-
- )}
-
- )
-}
-
-export default DocsPickerDesktop
diff --git a/src/components/Footer/Footer.astro b/src/components/Footer/Footer.astro
index 7f8a2078d1a..fee1f52732f 100644
--- a/src/components/Footer/Footer.astro
+++ b/src/components/Footer/Footer.astro
@@ -302,6 +302,12 @@
display: flex;
align-items: center;
}
+
+ .footer-col > h3 {
+ margin-bottom: var(--space-4x);
+ font-weight: 500;
+ }
+
.footer-logo-text-hide {
position: absolute;
left: 0;
diff --git a/src/components/Footer/NewsletterCTA.css b/src/components/Footer/NewsletterCTA.css
index bf25fd36df4..eac894074d1 100644
--- a/src/components/Footer/NewsletterCTA.css
+++ b/src/components/Footer/NewsletterCTA.css
@@ -19,6 +19,8 @@
.cta-subscribe-h1 {
text-align: center;
+ font-size: 2rem;
+ font-weight: 600;
}
.newsletter-cta :is(h2) {
@@ -56,6 +58,7 @@
}
.newsletter-cta .cta-subscribe-input::placeholder {
font-style: italic;
+ color: var(--muted-foreground);
}
#subscribe-button {
@@ -100,3 +103,9 @@
margin-bottom: var(--space-0x);
}
}
+
+@media screen and (min-width: 768px) {
+ .cta-subscribe-h1 {
+ font-size: 2.5rem;
+ }
+}
diff --git a/src/components/HeadCommon.astro b/src/components/HeadCommon.astro
index f2199bba192..96285979c75 100644
--- a/src/components/HeadCommon.astro
+++ b/src/components/HeadCommon.astro
@@ -4,6 +4,7 @@ import "../styles/index.css"
import "../styles/migrated.css"
import "../styles/prism-darcula.css"
import "@chainlink/design-system/global-styles.css"
+import "@chainlink/blocks/src/theme/globals.css"
export interface Props {
title: string
diff --git a/src/components/Header/Nav/ProductNavigation/Desktop/MegaMenu.tsx b/src/components/Header/Nav/ProductNavigation/Desktop/MegaMenu.tsx
index b13f9e55827..a8a65f8f984 100644
--- a/src/components/Header/Nav/ProductNavigation/Desktop/MegaMenu.tsx
+++ b/src/components/Header/Nav/ProductNavigation/Desktop/MegaMenu.tsx
@@ -1,305 +1,244 @@
-import { evmProducts } from "~/features/landing/data/index.ts"
import styles from "./megaMenu.module.css"
-import resourcesLogo from "../../../../../assets/product-logos/data-resources-logo.svg"
-import { Fragment } from "react/jsx-runtime"
-import { useEffect } from "react"
+import ccipLogo from "../../../../../assets/product-logos/ccip-logo.svg"
+import dataFeedsLogo from "../../../../../assets/product-logos/data-feeds-logo.svg"
+import dataStreamsLogo from "../../../../../assets/product-logos/data-streams-logo.svg"
+import dataLinkLogo from "../../../../../assets/product-logos/datalink-logo.svg"
+import functionsLogo from "../../../../../assets/product-logos/functions-logo.svg"
+import automationLogo from "../../../../../assets/product-logos/automation-logo.svg"
+import vrfLogo from "../../../../../assets/product-logos/vrf-logo.svg"
+import dtaLogo from "../../../../../assets/product-logos/dta-logo.svg"
+import generalGlobeLogo from "../../../../../assets/product-logos/general-globe-logo.svg"
+import nodesLogo from "../../../../../assets/product-logos/nodes-logo.svg"
+import chainlinkLocalLogo from "../../../../../assets/product-logos/chainlink-local-2-logo.svg"
+import creLogo from "../../../../../assets/product-logos/cre-logo.svg"
+import { Typography } from "@chainlink/blocks"
+import { clsx } from "../../utils.ts"
-interface MegaMenuProps {
- cancel: () => void
- id?: string
-}
-
-interface BottomLink {
- label: string
- href: string
-}
-
-interface Link {
- label: string
- href?: string
+const BlueSquare = () => {
+ return (
+
+ )
}
-interface MenuItem {
- title?: string
- image?: { src: string }
- description?: string
- learnMoreLink?: string
- docsLandingLink?: string
- links: Link[]
+interface GroupItem {
+ title: string
+ description: string
+ icon: ImageMetadata
+ link: string
}
-interface SubSection {
- title: string
- items: MenuItem[]
- bottomLinks?: BottomLink[]
+const GroupItem = ({ data }: { data: GroupItem }) => {
+ return (
+
+
+
+
+ {data.title}
+
+
+ {data.description}
+
+
+
+ )
}
-interface MegaMenuSection {
- title: string
- isMultiSection?: boolean
- sections?: SubSection[]
- items?: MenuItem[]
- bottomLinks?: BottomLink[]
+const GroupTitle = ({ children }: { children: React.ReactNode }) => {
+ return (
+
+ {children}
+
+ )
}
-export const megaMenuSections: MegaMenuSection[] = [
- {
- title: "Orchestration & Cross-Chain",
- isMultiSection: true,
- sections: [
- {
- title: "Orchestration",
- items: [
- {
- ...(evmProducts.find((product) => product.title === "CRE") || {}),
- links: [
- {
- label: "Docs",
- href: (evmProducts.find((product) => product.title === "CRE") || {})?.docsLandingLink,
- },
- ],
- },
- ],
- },
+export const megaMenuSections = {
+ interoperability: {
+ title: "Interoperability",
+ items: [
{
- title: "Cross-Chain",
- items: [
- {
- ...(evmProducts.find((product) => product.title === "CCIP") || {}),
- links: [
- {
- label: "Docs",
- href: (evmProducts.find((product) => product.title === "CCIP") || {})?.docsLandingLink,
- },
- {
- label: "Learn",
- href: (evmProducts.find((product) => product.title === "CCIP") || {})?.learnMoreLink,
- },
- ],
- },
- ],
- bottomLinks: [
- {
- label: "View all resources",
- href: "https://dev.chain.link/resources",
- },
- {
- label: "Learn about Chainlink",
- href: "https://dev.chain.link/products/general",
- },
- ],
+ icon: ccipLogo,
+ title: "Cross-Chain Communication",
+ description: "Move data and value across any blockchain",
+ link: "/ccip",
},
],
},
- {
+ data: {
title: "Data",
items: [
{
- ...evmProducts.find((product) => product.title === "Data Feeds"),
- title: "Data Feeds",
- links: [
- {
- label: "Docs",
- href: (evmProducts.find((product) => product.title === "Data Feeds") || {})?.docsLandingLink,
- },
- {
- label: "Learn",
- href: (evmProducts.find((product) => product.title === "Data Feeds") || {})?.learnMoreLink,
- },
- ],
+ icon: dataStreamsLogo,
+ title: "Data Streams",
+ description: "Access high-frequency market data for next-gen DeFi",
+ link: "/data-streams",
},
-
{
- ...evmProducts.find((product) => product.title === "Data Streams"),
- title: "Data Streams",
- links: [
- {
- label: "Docs",
- href: (evmProducts.find((product) => product.title === "Data Streams") || {})?.docsLandingLink,
- },
- {
- label: "Learn",
- href: (evmProducts.find((product) => product.title === "Data Streams") || {})?.learnMoreLink,
- },
- ],
+ icon: dataFeedsLogo,
+ title: "Market and Data Feeds",
+ description: "Utilize ultra-secure onchain data for smart contracts",
+ link: "/data-feeds",
},
-
{
- title: "Data resources",
- image: resourcesLogo,
- description: "Global standard for building secure cross-chain applications.",
- learnMoreLink: "data-feeds",
- links: [
- {
- label: "Learn",
- href: "https://dev.chain.link/products/data",
- },
- ],
+ icon: dataLinkLogo,
+ title: "DataLink",
+ description: "Publish and commercialize institutional data across...",
+ link: "/datalink",
},
],
},
- {
+ assetManagement: {
+ title: "Asset Management",
+ items: [
+ {
+ icon: dtaLogo,
+ title: "Digital Transfer Agent (DTA) Technical Standard",
+ description: "Unlock streamlined tokenized fund operations",
+ link: "/dta-technical-standard",
+ },
+ ],
+ },
+ compute: {
title: "Compute",
items: [
{
- ...evmProducts.find((product) => product.title === "Automation"),
- links: [
- {
- label: "Docs",
- href: (evmProducts.find((product) => product.title === "Automation") || {})?.docsLandingLink,
- },
- {
- label: "Learn",
- href: (evmProducts.find((product) => product.title === "Automation") || {})?.learnMoreLink,
- },
- ],
+ icon: functionsLogo,
+ title: "Functions",
+ description: "Connect smart contracts to any API",
+ link: "/chainlink-functions",
},
{
- ...evmProducts.find((product) => product.title === "Functions"),
- links: [
- {
- label: "Docs",
- href: (evmProducts.find((product) => product.title === "Functions") || {})?.docsLandingLink,
- },
- {
- label: "Learn",
- href: (evmProducts.find((product) => product.title === "Functions") || {})?.learnMoreLink,
- },
- ],
+ icon: automationLogo,
+ title: "Automation",
+ description: "Automate smart contracts via decentralized triggers",
+ link: "/chainlink-automation",
},
{
- ...evmProducts.find((product) => product.title === "VRF"),
- links: [
- {
- label: "Docs",
- href: (evmProducts.find((product) => product.title === "VRF") || {})?.docsLandingLink,
- },
- {
- label: "Learn",
- href: (evmProducts.find((product) => product.title === "VRF") || {})?.learnMoreLink,
- },
- ],
+ icon: vrfLogo,
+ title: "VRF",
+ description: "Ensure fair outcomes in games, NFTs, and more",
+ link: "/vrf",
},
],
},
-]
-
-function MegaMenu({ cancel, id }: MegaMenuProps) {
- useEffect(() => {
- const onESC = (ev: KeyboardEvent) => {
- if (ev.key === "Escape") {
- cancel()
- }
- }
- window.addEventListener("keyup", onESC, false)
- return () => {
- window.removeEventListener("keyup", onESC, false)
- }
- }, [])
+ orchestration: {
+ title: "Orchestration",
+ items: [
+ {
+ icon: creLogo,
+ title: "Chainlink Runtime Environment (CRE)",
+ description: "The global orchestration layer",
+ link: "/cre",
+ },
+ ],
+ },
+ other: {
+ title: "More",
+ items: [
+ {
+ icon: generalGlobeLogo,
+ title: "General",
+ description: "Foundational Chainlink knowledge",
+ link: "/getting-started/conceptual-overview",
+ },
+ {
+ icon: nodesLogo,
+ title: "Nodes",
+ description: "Be part of the Chainlink Network",
+ link: "/",
+ },
+ {
+ icon: chainlinkLocalLogo,
+ title: "Chainlink local",
+ description: "Run services locally before transitioning to a testnet",
+ link: "/chainlink-local",
+ },
+ ],
+ },
+}
+function MegaMenu({ cancel, isMobile }: { cancel?: () => void; isMobile?: boolean }) {
return (
-
-
-
- {megaMenuSections.map((section) => (
-
- {section.isMultiSection && section.sections ? (
- <>
- {section.sections.map((subSection) => (
-
- {subSection.title}
- {subSection.items.map((item, index) => (
-
-
- {item?.image?.src &&
}
-
{item.title}
-
-
-
{item.description}
- {item.links.map((link, linkIndex) => (
-
-
- {link.label}
-
- {linkIndex < item.links.length - 1 && }
-
- ))}
-
-
- ))}
- {subSection.bottomLinks && (
-
- {subSection.bottomLinks.map((link, linkIndex) => (
-
- ))}
-
- )}
-
- ))}
- >
- ) : (
- <>
-
{section.title}
- {section.items?.map((item, index) => (
-
-
- {item?.image?.src &&
}
-
{item.title}
-
-
-
{item.description}
- {item.links.map((link, linkIndex) => (
-
-
- {link.label}
-
- {linkIndex < item.links.length - 1 && }
-
- ))}
-
-
- ))}
- {"bottomLinks" in section && section.bottomLinks && (
-
- {section.bottomLinks.map((link, linkIndex) => (
-
- ))}
-
- )}
- >
- )}
-
- ))}
+
+
+
+
+
+ {megaMenuSections.orchestration.title}
+
+
+ {megaMenuSections.orchestration.items.map((link) => (
+
+ ))}
+
-
-
Featured
-
-
-
-
+
+
+
+ {megaMenuSections.interoperability.title}
+
+
+ {megaMenuSections.interoperability.items.map((link) => (
+
+ ))}
+
+
+
+
+
+ {megaMenuSections.assetManagement.title}
+
+
+ {megaMenuSections.assetManagement.items.map((link) => (
+
+ ))}
+
+
+
-
Hardhat CLI for Data Streams
-
-
Try out Chainlink Automation
-
+
+
+
+
+ {megaMenuSections.data.title}
+
+
+ {megaMenuSections.data.items.map((link) => (
+
+ ))}
+
+
+
+
+
+ {megaMenuSections.compute.title}
+
+
+ {megaMenuSections.compute.items.map((link) => (
+
+ ))}
+
+
+
+
+
+ {megaMenuSections.other.title}
+
+
+ {megaMenuSections.other.items.map((link) => (
+
+ ))}
+
diff --git a/src/components/Header/Nav/ProductNavigation/Desktop/MegaMenuContainer.tsx b/src/components/Header/Nav/ProductNavigation/Desktop/MegaMenuContainer.tsx
new file mode 100644
index 00000000000..17a6a2a25ce
--- /dev/null
+++ b/src/components/Header/Nav/ProductNavigation/Desktop/MegaMenuContainer.tsx
@@ -0,0 +1,27 @@
+import { useEffect } from "react"
+import styles from "./megaMenu.module.css"
+
+interface MegaMenuProps {
+ cancel: () => void
+ id?: string
+ children?: React.ReactNode
+}
+
+export default function MegaMenuContainer({ cancel, id, children }: MegaMenuProps) {
+ useEffect(() => {
+ const onESC = (ev: KeyboardEvent) => {
+ if (ev.key === "Escape") {
+ cancel()
+ }
+ }
+ window.addEventListener("keyup", onESC, false)
+ return () => {
+ window.removeEventListener("keyup", onESC, false)
+ }
+ }, [])
+ return (
+
+ {children}
+
+ )
+}
diff --git a/src/components/Header/Nav/ProductNavigation/Desktop/ProductNavigation.tsx b/src/components/Header/Nav/ProductNavigation/Desktop/ProductNavigation.tsx
index c6e0768cb9f..ada39e93f95 100644
--- a/src/components/Header/Nav/ProductNavigation/Desktop/ProductNavigation.tsx
+++ b/src/components/Header/Nav/ProductNavigation/Desktop/ProductNavigation.tsx
@@ -6,6 +6,7 @@ import { extendRadixComponent } from "../extendRadixComponent.ts"
import styles from "./productNavigation.module.css"
import { CaretIcon } from "../CaretIcon.tsx"
import MegaMenu from "./MegaMenu.tsx"
+import MegaMenuContainer from "./MegaMenuContainer.tsx"
type Props = {
setNavMenuOpen: (navMenuOpen: boolean) => void
@@ -42,27 +43,20 @@ export const ProductNavigation = ({ setNavMenuOpen, showMegaMenu, isMegamenuOpen
<>
- -
+
-
- Resources
+ Docs
- -
-
- Docs
-
-
-
Demos
@@ -79,12 +73,16 @@ export const ProductNavigation = ({ setNavMenuOpen, showMegaMenu, isMegamenuOpen
-
-
+
Get Certified
- {isMegamenuOpen && }
+ {isMegamenuOpen && (
+
+ )}
>
)
diff --git a/src/components/Header/Nav/ProductNavigation/Desktop/megaMenu.module.css b/src/components/Header/Nav/ProductNavigation/Desktop/megaMenu.module.css
index 83ba42a3509..6b3b9066541 100644
--- a/src/components/Header/Nav/ProductNavigation/Desktop/megaMenu.module.css
+++ b/src/components/Header/Nav/ProductNavigation/Desktop/megaMenu.module.css
@@ -9,15 +9,8 @@
justify-content: center;
}
-.wrapper {
- max-width: 1360px;
- width: 100%;
- background-color: white;
- height: fit-content;
- border-radius: 0.5rem;
- display: grid;
- grid-template-columns: 3fr 1fr;
- overflow: hidden;
+/* applies shadow to dropdown version of mega-menu */
+.megaMenuContainer > .wrapper {
box-shadow:
4.6px 9.3px 54px 1px rgba(152, 160, 185, 0.04),
2.1px 4.3px 32px -0.7px rgba(152, 160, 185, 0.31),
@@ -25,108 +18,128 @@
0.3px 0.5px 0.8px 0px rgba(152, 160, 185, 0.12);
}
-.wrapper h2 {
- padding-bottom: var(--space-4x);
- color: var(--gray-500);
- text-transform: uppercase;
- border-bottom: 1px solid var(--gray-200);
- margin-bottom: var(--space-8x);
-}
+.wrapper {
+ max-width: 1500px;
+ width: 100%;
+ background-color: white;
+ height: fit-content;
+ overflow: hidden;
+ display: flex;
+ flex-direction: column;
-.wrapper h3 {
- font-family: var(--font-family-text);
- color: var(--gray-900);
+ border: 1px solid var(--border);
}
-.wrapper p {
- color: var(--gray-500);
- margin-top: var(--space-2x);
- margin-bottom: var(--space-3x);
- line-height: var(--space-6x);
+.row {
+ display: grid;
+ grid-template-columns: repeat(3, 1fr);
+ border-bottom: 1px solid var(--border);
}
-.resourcesMenuContentMain {
- padding-top: var(--space-16x);
- padding-left: var(--space-16x);
- padding-bottom: var(--space-16x);
- padding-right: var(--space-8x);
- display: grid;
- grid-template-columns: 1fr 1fr 1fr;
- gap: var(--space-16x);
+.row:last-child {
+ border-bottom: none;
}
-.resourcesMenuContentRow {
+.wrapper header {
display: flex;
- flex-direction: column;
+ align-items: center;
+ gap: var(--space-3x);
+ padding: var(--space-4x) var(--space-6x);
}
-.verticalDivider {
- border-left: 1px solid var(--gray-300);
- margin: 0 var(--space-3x);
+.wrapper p {
+ margin-bottom: 0;
}
-.links {
- margin-bottom: var(--space-10x);
+.section {
+ display: flex;
+ flex-direction: column;
+ border-right: 1px solid var(--border);
}
-.links a {
- font-weight: var(--font-weight-medium);
- color: var(--color-text-link);
+.section:last-child {
+ border-right: none;
}
-.resourcesMenuContentFeatured {
- padding-top: var(--space-16x);
- padding-left: var(--space-8x);
- padding-bottom: var(--space-16x);
- padding-right: var(--space-16x);
- background-color: var(--gray-100);
+.section header {
+ border-bottom: 1px solid var(--border);
}
-.megaMenuLink {
+.groupItem {
display: flex;
align-items: center;
- gap: var(--space-2x);
-}
-
-.megaMenuLink h3 {
- margin-bottom: 0;
+ padding: var(--space-6x) var(--space-8x);
+ gap: var(--space-4x);
+ text-decoration: none;
+ transition: background-color 0.2s;
}
-.megaMenuLink img {
- width: var(--space-5x);
- height: var(--space-5x);
+.groupItem:hover {
+ background-color: var(--muted);
}
-.featuredImage {
- width: 100%;
+.groupItemIcon {
+ width: 24px;
+ height: 24px;
+ flex-shrink: 0;
}
-.divider {
- border-bottom: 1px solid var(--gray-200);
- margin: var(--space-8x) auto;
-}
-
-.bottomLinks {
- margin-top: auto;
+.itemList {
display: flex;
flex-direction: column;
- gap: var(--space-3x);
}
-.bottomLinks div {
- display: flex;
- align-items: center;
- gap: var(--space-2x);
- line-height: var(--space-6x);
+.groupItemDescription {
+ display: -webkit-box;
+ -webkit-line-clamp: 1;
+ line-clamp: 1;
+ -webkit-box-orient: vertical;
+ overflow: hidden;
}
-.bottomLinks a {
- color: var(--gray-900);
+.groupItemTitle {
+ display: -webkit-box;
+ -webkit-line-clamp: 1;
+ line-clamp: 1;
+ -webkit-box-orient: vertical;
+ overflow: hidden;
+ font-size: 18px;
+ font-weight: 500;
}
-/* TODO: change with a var when available in the chainlink repo */
-.bottomLink a:hover {
- color: #0847f7;
+.wrapper.mobile {
+ border: none;
+ overflow: unset;
+
+ & .row {
+ grid-template-columns: 1fr;
+ border-bottom: none;
+ }
+
+ & .section header {
+ border-bottom: 1px solid var(--border);
+ border-top: 1px solid var(--border);
+ }
+
+ & .section {
+ border-right: none;
+ }
+
+ & .groupItemTitle {
+ display: block;
+ -webkit-line-clamp: unset;
+ line-clamp: unset;
+ -webkit-box-orient: unset;
+ overflow: visible;
+ }
+
+ & .groupItemDescription {
+ display: block;
+ -webkit-line-clamp: unset;
+ line-clamp: unset;
+ -webkit-box-orient: unset;
+ overflow: visible;
+ }
}
@media screen and (min-width: 768px) {
diff --git a/src/components/Header/Nav/ProductNavigation/Desktop/productNavigation.module.css b/src/components/Header/Nav/ProductNavigation/Desktop/productNavigation.module.css
index 4057b7ac853..048809c260c 100644
--- a/src/components/Header/Nav/ProductNavigation/Desktop/productNavigation.module.css
+++ b/src/components/Header/Nav/ProductNavigation/Desktop/productNavigation.module.css
@@ -57,19 +57,6 @@
opacity: 1;
}
-.megaMenu::after {
- content: "";
- position: absolute;
- bottom: -35px;
- right: 35%;
- transform: translateX(-50%) rotate(45deg);
- width: 20px;
- height: 20px;
- z-index: 100;
- background-color: white;
- padding: var(--space-2x);
-}
-
@media screen and (min-width: 992px) {
.root {
display: flex;
diff --git a/src/components/Header/Nav/ProductNavigation/Mobile/MegaMenu.tsx b/src/components/Header/Nav/ProductNavigation/Mobile/MegaMenu.tsx
deleted file mode 100644
index bbab4ffc7ce..00000000000
--- a/src/components/Header/Nav/ProductNavigation/Mobile/MegaMenu.tsx
+++ /dev/null
@@ -1,94 +0,0 @@
-import styles from "./megaMenu.module.css"
-import { Fragment } from "react/jsx-runtime"
-import { megaMenuSections } from "../Desktop/MegaMenu.tsx"
-import { useState } from "react"
-
-function MegaMenu() {
- return (
-
-
- {megaMenuSections.map((section) => (
-
-
{section.title}
- {section.items?.map((item, index) => (
-
- ))}
-
- ))}
-
-
-
-
-
Featured
-
-
-
-
Blockchain 101
-
-
-
- )
-}
-
-function MegaMenuItem({
- image,
- title,
- description,
- links,
-}: {
- image?: string
- title?: string
- description?: string
- links: { label: string; href?: string }[]
-}) {
- const [open, setOpen] = useState(false)
- return (
- <>
-
setOpen((state) => !state)}>
-
-
-
{title}
-
- {open ? "-" : "+"}
-
- {open && (
-
-
{description}
- {links.map((link, index) => (
-
-
- {link.label}
-
- {index < links.length - 1 && }
-
- ))}
-
- )}
- >
- )
-}
-
-export default MegaMenu
diff --git a/src/components/Header/Nav/ProductNavigation/Mobile/ProductNavigation.tsx b/src/components/Header/Nav/ProductNavigation/Mobile/ProductNavigation.tsx
index dc0f0371d88..dc4df1d6eaf 100644
--- a/src/components/Header/Nav/ProductNavigation/Mobile/ProductNavigation.tsx
+++ b/src/components/Header/Nav/ProductNavigation/Mobile/ProductNavigation.tsx
@@ -6,7 +6,7 @@ import styles from "./productNavigation.module.css"
import { MenuIcon } from "./MenuIcon.tsx"
import { BackArrowIcon } from "./BackArrowIcon.tsx"
import { CaretRightIcon } from "./CaretRightIcon.tsx"
-import MegaMenu from "./MegaMenu.tsx"
+import MegaMenu from "../Desktop/MegaMenu.tsx"
const Trigger = extendRadixComponent(Dialog.Trigger)
const Close = extendRadixComponent(Dialog.Close)
@@ -71,14 +71,12 @@ export function ProductNavigation() {
className={styles.productContentLink}
onClick={() => setProductsSlidePosition("submenu")}
data-testid="sub-product-navigation-trigger-mobile"
- aria-label="Open Resources submenu"
+ aria-label="Open Docs submenu"
>
- Resources
+ Docs
-
- Docs
-
+
Demos
@@ -88,7 +86,7 @@ export function ProductNavigation() {
Changelog
-
+
Get Certified
@@ -103,11 +101,11 @@ export function ProductNavigation() {
>
-
Resources
+
Docs
{/* Spacer */}
-
+
diff --git a/src/components/Header/Nav/ProductNavigation/Mobile/megaMenu.module.css b/src/components/Header/Nav/ProductNavigation/Mobile/megaMenu.module.css
deleted file mode 100644
index cf8382f3d30..00000000000
--- a/src/components/Header/Nav/ProductNavigation/Mobile/megaMenu.module.css
+++ /dev/null
@@ -1,142 +0,0 @@
-.wrapper {
- width: 100%;
- border-radius: 0.5rem;
- display: flex;
- flex-direction: column;
- max-height: calc(100vh - 68px);
-}
-
-.wrapper h2 {
- padding-bottom: var(--space-3x);
- color: var(--gray-500);
- text-transform: uppercase;
-
- border-bottom: 1px solid var(--gray-200);
-}
-
-.wrapper h3 {
- font-family: var(--font-family-text);
- color: var(--gray-900);
-}
-
-.wrapper p {
- color: var(--gray-500);
- margin-top: var(--space-2x);
- margin-bottom: var(--space-3x);
- line-height: var(--space-6x);
-}
-
-.resourcesMenuContentMain {
- padding: var(--space-6x) var(--space-8x) var(--space-4x) var(--space-8x);
- display: flex;
- flex-direction: column;
- gap: var(--space-6x);
-}
-
-.resourcesMenuContentRow {
- display: flex;
- flex-direction: column;
-}
-
-.verticalDivider {
- border-left: 1px solid var(--gray-300);
- margin: 0 var(--space-3x);
-}
-
-.links {
- margin-bottom: var(--space-6x);
- margin-left: var(--space-8x);
-}
-
-.links a {
- font-weight: var(--font-weight-medium);
- color: var(--color-text-link);
-}
-
-.resourcesMenuContentFeatured {
- padding-top: var(--space-16x);
- padding-left: var(--space-8x);
- padding-bottom: var(--space-16x);
- padding-right: var(--space-16x);
- background-color: var(--gray-100);
-}
-
-.megaMenuButton {
- display: flex;
- justify-content: space-between;
- align-items: center;
- padding: var(--space-4x) var(--space-1x);
- cursor: pointer;
-}
-
-.megaMenuButton span {
- font-size: var(--space-6x);
- font-weight: var(--font-weight-medium);
- color: var(--gray-500);
-}
-
-.megaMenuLink {
- display: flex;
- align-items: center;
- gap: var(--space-2x);
-}
-
-.megaMenuLink h3 {
- margin-bottom: 0;
-}
-
-.megaMenuLink img {
- width: var(--space-5x);
- height: var(--space-5x);
-}
-
-.featuredImage {
- width: 100%;
-}
-
-.divider {
- border-bottom: 1px solid var(--gray-200);
- margin: var(--space-8x) auto;
-}
-
-.bottomLinks {
- padding: var(--space-6x) 0;
- display: flex;
- flex-direction: column;
- gap: var(--space-8x);
- border-top: 1px solid var(--gray-200);
-}
-
-.bottomLinks div {
- display: flex;
- align-items: center;
- gap: var(--space-2x);
- line-height: var(--space-6x);
-}
-
-.bottomLinks a {
- color: var(--gray-900);
-}
-
-/* TODO: change with a var when available in the chainlink repo */
-.bottomLink a:hover {
- color: #0847f7;
-}
-
-@media screen and (min-width: 768px) {
- .megaMenuContainer {
- display: flex;
- }
-}
-
-@media screen and (min-width: 1280px) {
- .wrapper::before {
- left: 31%;
- }
-}
-
-@media screen and (min-width: 1565px) {
- .wrapper::before {
- left: 35%;
- }
-}
diff --git a/src/components/Header/Nav/ProductNavigation/Mobile/productNavigation.module.css b/src/components/Header/Nav/ProductNavigation/Mobile/productNavigation.module.css
index 5994b36a9e4..b3bb2b4c22c 100644
--- a/src/components/Header/Nav/ProductNavigation/Mobile/productNavigation.module.css
+++ b/src/components/Header/Nav/ProductNavigation/Mobile/productNavigation.module.css
@@ -34,6 +34,7 @@
width: 200vw;
display: flex;
transition: transform 0.3s;
+ height: 100%;
}
.main {
@@ -71,11 +72,11 @@
overflow: scroll;
list-style: none;
width: 100vw;
- padding-bottom: 56px;
}
.subProductContent {
display: flex;
flex-direction: column;
+ height: 100%;
}
.subProductContentTitle {
diff --git a/src/components/Header/Nav/navBar.module.css b/src/components/Header/Nav/navBar.module.css
index 7b8a629ffad..643ac110ed9 100644
--- a/src/components/Header/Nav/navBar.module.css
+++ b/src/components/Header/Nav/navBar.module.css
@@ -1,11 +1,11 @@
-/*
+/*
* Navigation bar styles
- *
+ *
* The navigation uses a fixed header with blur effect and contains:
* 1. Logo section (left)
* 2. Menu section (center)
* 3. Right section with actions
- *
+ *
* Responsive breakpoints:
* - Mobile: < 992px
* - Desktop: >= 992px
@@ -96,7 +96,6 @@
display: flex;
justify-content: center;
align-items: center;
- z-index: 10;
}
.modalContentWrapper {
diff --git a/src/components/Header/NavBar.tsx b/src/components/Header/NavBar.tsx
index 404af835727..108ab4c6cd7 100644
--- a/src/components/Header/NavBar.tsx
+++ b/src/components/Header/NavBar.tsx
@@ -35,13 +35,9 @@ export const NavBar = ({
/ - if the page has been scrolled down and the header is hidden
/ - if the page is a inner doc page or part of the "pathWithoutDocNav" or not
*/
- const innerDocNavHeight = 56
- let height = (navRef.current as HTMLElement).clientHeight
- let baseHeightNoNav = 0
- if (doubleNavbar()) {
- height += innerDocNavHeight
- baseHeightNoNav += innerDocNavHeight
- }
+ const height = (navRef.current as HTMLElement).clientHeight
+ const baseHeightNoNav = 0
+
const elements = document.body.querySelectorAll("[data-sticky]")
elements.forEach((e: HTMLElement) => {
if (!e.classList.contains(styles.animateTop)) {
diff --git a/src/components/JourneyCards/JourneyCards.astro b/src/components/JourneyCards/JourneyCards.astro
new file mode 100644
index 00000000000..39e85bdf1b5
--- /dev/null
+++ b/src/components/JourneyCards/JourneyCards.astro
@@ -0,0 +1,258 @@
+---
+import { Tag, Typography } from "@chainlink/blocks"
+import { JourneyTabGrid } from "./JourneyTabGrid"
+
+const columns = [
+ {
+ title: "Learn & Explore",
+ items: [
+ {
+ title: "Explore Cross-Chain Interoperability with CCIP",
+ description: "Learn cross-chain concepts, workflows, and real-world use cases.",
+ badge: "ccip",
+ href: "/",
+ },
+ {
+ title: "Understand How Data Feeds Power dApps",
+ description: "See how oracle data feeds deliver price feeds and reference data.",
+ badge: "data feeds",
+ href: "/",
+ },
+ {
+ title: "Learn How Data Streams Deliver Real-Time Data",
+ description: "Understand how low-latency streams support time-sensitive applications.",
+ badge: "data streams",
+ href: "/",
+ },
+ {
+ title: "Discover Off-Chain Compute with Functions",
+ description: "Learn how Functions connect smart contracts to APIs and custom logic.",
+ badge: "functions",
+ href: "/",
+ },
+ ],
+ },
+ {
+ title: "Build & Integrate",
+ items: [
+ {
+ title: "Build Cross-Chain Apps with CCIP Tutorials",
+ description: "Follow step-by-step guides with language switching (EVM, Rust, Move, etc.).",
+ badge: "ccip",
+ href: "/",
+ },
+ {
+ title: "Integrate Data Feeds into Smart Contracts",
+ description: "Plug feeds into your apps with examples and addresses.",
+ badge: "data feeds",
+ href: "/",
+ },
+ {
+ title: "Implement Real-Time Use Cases with Data Streams",
+ description: "Use low-latency data in trading, gaming, and other live applications.",
+ badge: "data streams",
+ href: "/",
+ },
+ {
+ title: "Connect Contracts to APIs with Functions",
+ description: "Add external data and custom logic to your dApps.",
+ badge: "functions",
+ href: "/",
+ },
+ ],
+ },
+ {
+ title: "Operate & Scale",
+ items: [
+ {
+ title: "Monitor CCIP Transactions in Real Time",
+ description: "Track the progress and status of cross-chain transactions.",
+ badge: "ccip",
+ href: "/",
+ },
+ {
+ title: "Stay Up to Date with Data Feeds",
+ description: "Rely on changelogs and schema updates for accuracy.",
+ badge: "data feeds",
+ href: "/",
+ },
+ {
+ title: "Deliver Reliable Low-Latency Data with Streams",
+ description: "Operate Data Streams at scale for critical, time-sensitive use cases.",
+ badge: "data streams",
+ href: "/",
+ },
+ {
+ title: "Scale and Optimize Functions",
+ description: "Debug, manage workloads, and grow your applications.",
+ badge: "functions",
+ href: "/",
+ },
+ ],
+ },
+]
+
+// Transform columns to tabs format for JourneyTabGrid
+const tabs = columns.map((column) => ({
+ name: column.title,
+ items: column.items.map((item) => ({
+ title: item.title,
+ description: item.description,
+ link: item.href,
+ badge: item.badge,
+ })),
+}))
+---
+
+
+
+ Start your Chainlink journey
+
+ {
+ columns.map((column) => (
+
+ ))
+ }
+
+
+
+
+
+
diff --git a/src/components/JourneyCards/JourneyTabGrid.module.css b/src/components/JourneyCards/JourneyTabGrid.module.css
new file mode 100644
index 00000000000..39bc9c5012e
--- /dev/null
+++ b/src/components/JourneyCards/JourneyTabGrid.module.css
@@ -0,0 +1,124 @@
+/* Tab styling - copied from TabGrid */
+.gridHeader {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: var(--space-8x);
+ flex-wrap: wrap;
+ gap: var(--space-8x);
+}
+
+.tabsTrigger {
+ height: 32px;
+ padding: var(--space-1x) var(--space-2x);
+ justify-content: center;
+ align-items: center;
+ border-radius: var(--space-2x);
+ background-color: var(--pill);
+ border: 1px solid var(--pill-border);
+}
+
+.tabsTrigger:hover {
+ background-color: var(--pill-hover);
+}
+
+.tabsTrigger[data-state="active"] {
+ background-color: var(--pill-active);
+ border-color: var(--pill-active);
+ border-bottom: 1px solid var(--pill-active);
+
+ & h3 {
+ color: var(--pill-active-foreground);
+ }
+}
+
+.tabTitle {
+ color: var(--pill-foreground);
+ font-weight: 400;
+}
+
+.tabsList {
+ display: flex;
+ gap: var(--space-2x);
+ border-bottom: 0;
+ flex-wrap: wrap;
+ justify-content: start !important;
+}
+
+.journeyGrid {
+ display: grid;
+ grid-template-columns: 1fr;
+ border-left: 1px solid var(--border);
+ border-top: 1px solid var(--border);
+}
+
+.journeyCard {
+ display: flex;
+ flex-direction: column;
+ gap: var(--space-6x);
+ padding: var(--space-6x);
+ border-right: 1px solid var(--border);
+ border-bottom: 1px solid var(--border);
+}
+
+.journeyCard:hover {
+ background-color: var(--muted);
+
+ .footerTag {
+ background-color: var(--background);
+ }
+
+ .footerIcon {
+ opacity: 1;
+ }
+}
+
+.cardContent {
+ display: flex;
+ flex-direction: column;
+ gap: var(--space-2x);
+}
+
+.journeyFooter {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ margin-top: auto;
+ flex: 1;
+ width: 100%;
+}
+
+.footerIcon {
+ height: 12px;
+ width: 12px;
+ opacity: 0;
+}
+
+.footerTag {
+ text-transform: uppercase;
+}
+
+@media (max-width: 768px) {
+ .journeyGrid {
+ grid-template-columns: repeat(2, 1fr);
+ }
+ .gridHeader > h2 {
+ font-size: 28px;
+ }
+}
+
+@media screen and (max-width: 425px) {
+ .journeyGrid {
+ grid-template-columns: 1fr;
+ }
+ .gridHeader {
+ margin-bottom: var(--space-6x);
+ }
+}
+
+@media screen and (max-width: 390px) {
+ .gridHeader {
+ flex-direction: column;
+ align-items: start;
+ }
+}
diff --git a/src/components/JourneyCards/JourneyTabGrid.tsx b/src/components/JourneyCards/JourneyTabGrid.tsx
new file mode 100644
index 00000000000..ab44a3b0fba
--- /dev/null
+++ b/src/components/JourneyCards/JourneyTabGrid.tsx
@@ -0,0 +1,71 @@
+import styles from "./JourneyTabGrid.module.css"
+import { Tabs, TabsContent, TabsList, TabsTrigger, Typography, Tag } from "@chainlink/blocks"
+
+export interface JourneyItem {
+ title: string
+ description: string
+ link: string
+ badge?: string
+}
+
+export interface JourneyTab {
+ name: string
+ items: JourneyItem[]
+}
+
+interface JourneyTabGridProps {
+ tabs: JourneyTab[]
+ header: string
+}
+
+export const JourneyTabGrid = ({ tabs, header }: JourneyTabGridProps) => {
+ return (
+
+
+
+ {header}
+
+
+ {tabs.map((tab) => (
+
+ {tab.name}
+
+ ))}
+
+
+
+ {tabs.map((tab) => (
+
+
+
+ ))}
+
+ )
+}
diff --git a/src/components/LandingHero/LandingHero.astro b/src/components/LandingHero/LandingHero.astro
new file mode 100644
index 00000000000..4303beed5ea
--- /dev/null
+++ b/src/components/LandingHero/LandingHero.astro
@@ -0,0 +1,21 @@
+---
+import { Typography } from "@chainlink/blocks"
+import MegaMenu from "../Header/Nav/ProductNavigation/Desktop/MegaMenu"
+import styles from "./landingHero.module.css"
+---
+
+
+
+ Explore docs & resources
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/LandingHero/landingHero.module.css b/src/components/LandingHero/landingHero.module.css
new file mode 100644
index 00000000000..c7a64507745
--- /dev/null
+++ b/src/components/LandingHero/landingHero.module.css
@@ -0,0 +1,69 @@
+.content {
+ padding: var(--space-16x);
+ max-width: 1440px;
+ width: 100%;
+ margin: 0 auto;
+ position: absolute;
+ inset: 0;
+ z-index: 5;
+}
+
+.backgrounds {
+ display: flex;
+ height: 100%;
+}
+
+.title {
+ font-weight: 400;
+ margin-bottom: var(--space-8x);
+}
+
+.wrapper {
+ background-color: var(--muted);
+ position: relative;
+ inset: 0;
+ height: 746px;
+}
+
+.heroImage {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+}
+
+.heroDotted {
+ width: 100%;
+ object-fit: cover;
+}
+.heroLeft {
+ display: flex;
+ align-items: end;
+}
+
+.heroRight,
+.heroLeft {
+ width: 50%;
+ height: 100%;
+}
+
+@media screen and (max-width: 991px) {
+ .wrapper {
+ background-color: transparent;
+ height: auto;
+ padding: 36px var(--space-10x);
+ }
+ .backgrounds,
+ .content .menu {
+ display: none;
+ }
+
+ .content {
+ position: unset;
+ padding: 0;
+ }
+
+ .title {
+ font-size: 40px;
+ margin-bottom: 0;
+ }
+}
diff --git a/src/components/LayoutHero/LayoutHero.astro b/src/components/LayoutHero/LayoutHero.astro
new file mode 100644
index 00000000000..ee95ce616f9
--- /dev/null
+++ b/src/components/LayoutHero/LayoutHero.astro
@@ -0,0 +1,45 @@
+---
+import { buttonVariants, Typography } from "@chainlink/blocks"
+import styles from "./LayoutHero.module.css"
+
+interface Props {
+ title: string
+ description: string
+ buttons: Array<{
+ label: string
+ link: string
+ }>
+ image: string
+}
+
+const { title, description, buttons = [], image } = Astro.props as Props
+---
+
+
+
+
+
{title}
+
{description}
+
+
+
+
+
+
+
+
+
diff --git a/src/components/LayoutHero/LayoutHero.module.css b/src/components/LayoutHero/LayoutHero.module.css
new file mode 100644
index 00000000000..08edb61ed40
--- /dev/null
+++ b/src/components/LayoutHero/LayoutHero.module.css
@@ -0,0 +1,99 @@
+.layoutHero {
+ display: flex;
+ flex-direction: column;
+ gap: var(--space-8x);
+ margin: 0 auto;
+ background-color: var(--gray-100);
+ position: relative;
+ width: 100%;
+ height: 345px;
+ border-left: 1px solid var(--border);
+ border-right: 1px solid var(--border);
+ border-bottom: 1px solid var(--border);
+}
+
+.heroContent {
+ display: flex;
+ flex-direction: column;
+ padding-left: 55px;
+ width: 100%;
+ height: 100%;
+ justify-content: center;
+ max-width: 540px;
+}
+
+.heroContentWrapper {
+ display: flex;
+ position: relative;
+ z-index: 2;
+ width: 100%;
+ height: 100%;
+}
+
+.heroBackgroundImg {
+ position: absolute;
+ right: 0;
+ z-index: 1;
+}
+.heroTitle {
+ font-size: 3rem;
+ line-height: 50px;
+ color: var(--gray-950);
+ margin-bottom: var(--space-3x);
+ letter-spacing: -0.48px;
+ font-weight: 400;
+}
+
+.heroButtons {
+ display: flex;
+
+ gap: var(--space-4x);
+ margin-top: var(--space-8x);
+}
+
+.heroImage {
+ display: flex;
+ position: absolute;
+ bottom: 35px;
+ right: 0;
+}
+
+.heroImage img {
+ max-width: 100%;
+ height: auto;
+}
+
+@media screen and (max-width: 425px) {
+ .layoutHero {
+ height: auto;
+ padding: var(--space-8x) 0;
+ }
+}
+
+/* lesser values cause overlapping of elements */
+@media screen and (max-width: 1400px) {
+ .layoutHero {
+ border: none;
+ background-color: transparent;
+ }
+ .heroImage,
+ .heroBackgroundImg {
+ display: none;
+ }
+
+ .heroContent {
+ padding-left: 0;
+ }
+
+ .heroButtons {
+ margin-top: var(--space-6x);
+ }
+
+ .heroButtons a {
+ width: fit-content;
+ }
+
+ .heroTitle {
+ font-size: 40px;
+ }
+}
diff --git a/src/components/LayoutHero/README.md b/src/components/LayoutHero/README.md
new file mode 100644
index 00000000000..fcc0c16e4d0
--- /dev/null
+++ b/src/components/LayoutHero/README.md
@@ -0,0 +1,84 @@
+# LayoutHero Component
+
+## What is it?
+
+The LayoutHero component is a reusable hero section that displays a title, description, call-to-action buttons, and an optional image. It's perfect for landing pages or the top of important pages where you want to grab attention and guide users to take action.
+
+## How to Use It
+
+### Basic Usage
+
+To use the LayoutHero component in your page, you'll need to import it and provide some information:
+
+```astro
+---
+import { LayoutHero } from "@components"
+---
+
+
+```
+
+### What Each Part Does
+
+**title** (Required)
+
+- This is the main heading that appears at the top
+- Make it clear and attention-grabbing
+- Example: "Welcome to Chainlink Docs"
+
+**description** (Required)
+
+- A short paragraph explaining what this page or section is about
+- Keep it concise but informative
+- Example: "Learn how to connect your smart contracts to real-world data"
+
+**buttons** (Required)
+
+- An array of buttons that link to other pages
+- Each button needs two things:
+ - `label`: The text shown on the button
+ - `link`: Where the button takes you when clicked
+- The first button will be blue (primary action)
+- The second button will be white (secondary action)
+- You can have 0, 1, or 2 buttons
+
+**image** (Required)
+
+- The path to an image file you want to display
+- The image appears on the right side on larger screens
+- Below the text on mobile devices
+- Example: "/images/my-hero-image.png"
+
+## Examples
+
+### With Only One Button
+
+```astro
+
+```
+
+### With Image and Two Buttons
+
+```astro
+
+```
diff --git a/src/components/LeftSidebar/LeftSidebar.astro b/src/components/LeftSidebar/LeftSidebar.astro
index 3066a4c384a..960265a8aac 100644
--- a/src/components/LeftSidebar/LeftSidebar.astro
+++ b/src/components/LeftSidebar/LeftSidebar.astro
@@ -6,9 +6,9 @@ import RecursiveSidebar from "./RecursiveSidebar.astro"
import { LanguageSwitcherDropdown } from "~/components/LanguageSwitcherDropdown"
import { ChainTypeSelector } from "~/components/ChainSelector"
import { isChainAwareSection } from "~/config/chainTypes"
-import { filterContentByChainType } from "~/utils/chainType"
-import type { ChainType } from "~/config/types"
import styles from "./leftSidebar.module.css"
+import DocsHeaderTitle from "../DocsHeaderTitle/DocsHeaderTitle.astro"
+import * as CONFIG from "../../config"
type SectionEntryWithParent = SectionEntry & { parentSection?: string }
@@ -103,6 +103,39 @@ const sidebarSections = getSidebarSections(section)
))
}
+
+
+
+ {
+ CONFIG.COMMUNITY_INVITE_URL && (
+
+ )
+ }
+
diff --git a/src/components/LeftSidebar/leftSidebar.module.css b/src/components/LeftSidebar/leftSidebar.module.css
index 1b0f96dcd06..8f0b448ed8f 100644
--- a/src/components/LeftSidebar/leftSidebar.module.css
+++ b/src/components/LeftSidebar/leftSidebar.module.css
@@ -56,8 +56,7 @@
.navGroupTitle {
margin-bottom: var(--space-2x);
margin-top: var(--space-1x);
- color: var(--gray-900);
- font-weight: 600;
+ color: var(--muted-foreground);
line-height: 24px;
font-size: 15px;
display: flex;
@@ -66,10 +65,9 @@
cursor: pointer;
list-style: none;
position: relative;
- padding-left: var(--space-6x);
}
-.navGroupTitle::before {
+.navGroupTitle::after {
content: "";
width: 6px;
height: 6px;
@@ -80,21 +78,16 @@
transition: transform 0.15s ease;
position: absolute;
top: calc(50% - 4px);
- left: var(--space-2x);
+ right: var(--space-2x);
}
-details[open] > .navGroupTitle::before {
+details[open] > .navGroupTitle::after {
transform: rotate(45deg);
top: calc(50% - 5px);
}
-details:hover .navGroupTitle::before {
- border-color: var(--color-text-link);
-}
-
.navGroupEntries {
margin-bottom: 0;
- padding-left: var(--space-6x);
}
details {
diff --git a/src/components/LeftSidebar/recursiveSidebar.module.css b/src/components/LeftSidebar/recursiveSidebar.module.css
index 31a33633647..ca7720c2278 100644
--- a/src/components/LeftSidebar/recursiveSidebar.module.css
+++ b/src/components/LeftSidebar/recursiveSidebar.module.css
@@ -10,11 +10,13 @@
gap: var(--space-2x);
line-height: 1.4;
font-size: 14px;
- color: var(--gray-500, #858a95);
+ color: var(--muted-foreground);
padding: var(--space-2x) var(--space-6x) var(--space-2x) var(--space-4x);
transition: color 100ms ease-in;
- border-radius: 4px;
- margin-right: var(--space-2x);
+ border-left: 1px solid var(--border);
+
+ padding-right: var(--space-2x);
+ margin-bottom: 0;
position: relative;
}
@@ -39,7 +41,7 @@ details summary.navLink.nested a {
details summary.navLink:has(a.active),
details summary.navLink:has(a[aria-current="page"]),
details summary.navLink.active {
- color: var(--color-text-link);
+ color: var(--foreground);
}
.navLink:hover,
@@ -47,15 +49,19 @@ details summary.navLink.active {
details summary.navLink:hover,
details summary.navLink:focus {
text-decoration: none;
+ background-color: var(--muted);
+
+ color: var(--muted-foreground);
}
.navLink[aria-current="page"],
details summary.navLink:has(a[aria-current="page"]),
details summary.navLink.active,
details summary.navLink:has(a.active) {
- font-weight: 600;
- background-color: rgba(28, 100, 242, 0.08);
- color: var(--color-text-link);
+ color: var(--foreground);
+ border-left: 2px solid var(--brand);
+ font-weight: 500;
+ background-color: var(--muted);
}
.navLink.nested {
@@ -75,14 +81,15 @@ details summary.navLink a {
margin: 0;
}
-details summary.navLink:hover a {
- color: var(--color-text-link);
+details summary.navLink:hover {
+ background-color: var(--muted);
+ color: var(--muted-foreground);
}
details summary.navLink a.active,
details summary.navLink a[aria-current="page"] {
- font-weight: 600;
- color: var(--color-text-link);
+ font-weight: 500;
+ color: var(--foreground);
}
.navGroupEntries {
@@ -109,9 +116,6 @@ details summary.navLink a[aria-current="page"] {
.navGroupEntries.nested {
margin-left: 0;
- margin-top: var(--space-1x);
- padding-left: var(--space-4x);
- margin-bottom: var(--space-1x);
position: relative;
}
@@ -125,6 +129,10 @@ details summary.navLink a[aria-current="page"] {
background-color: var(--gray-200);
}
+.navGroupEntries.nested .navLink {
+ padding-left: 28px;
+}
+
details summary::-webkit-details-marker {
display: none;
}
@@ -139,7 +147,7 @@ details > summary.navLink {
padding-left: var(--space-4x);
}
-details > summary.navLink::before {
+details > summary.navLink::after {
content: "";
width: 6px;
height: 6px;
@@ -150,14 +158,18 @@ details > summary.navLink::before {
transition: transform 0.15s ease;
position: absolute;
top: calc(50% - 4px);
- left: 0;
+ right: var(--space-2x);
}
-details[open] > summary.navLink::before {
+details[open] > summary.navLink::after {
transform: rotate(45deg);
top: calc(50% - 5px);
}
-details:hover > summary.navLink::before {
- border-color: var(--color-text-link);
+.container ul {
+ overflow-y: auto;
+ padding: var(--space-4x);
+ line-height: 1.5;
+ list-style-type: none;
+ word-break: break-word;
}
diff --git a/src/components/MediaSection/MediaSection.astro b/src/components/MediaSection/MediaSection.astro
new file mode 100644
index 00000000000..6189f9326e7
--- /dev/null
+++ b/src/components/MediaSection/MediaSection.astro
@@ -0,0 +1,46 @@
+---
+import { Typography } from "@chainlink/blocks"
+import styles from "./MediaSection.module.css"
+
+interface Props {
+ heading: string
+ description: string
+ image?: string
+ video?: string
+}
+
+const { heading, description, image, video } = Astro.props
+---
+
+
+
+ {heading}
+
+ {description}
+
+
+
+ {
+ image && (
+
+ )
+ }
+
+ {
+ !image && video && (
+
+
+
+ Your browser does not support the video tag.
+
+
+ )
+ }
+
diff --git a/src/components/MediaSection/MediaSection.module.css b/src/components/MediaSection/MediaSection.module.css
new file mode 100644
index 00000000000..f7c5673f5a8
--- /dev/null
+++ b/src/components/MediaSection/MediaSection.module.css
@@ -0,0 +1,25 @@
+.section {
+ display: flex;
+ flex-direction: column;
+ gap: var(--space-8x);
+}
+
+.textContent {
+ display: flex;
+ flex-direction: column;
+ gap: var(--space-6x);
+}
+
+.mediaWrapper {
+ width: 100%;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+
+.media {
+ width: 100%;
+ max-width: 100%;
+ height: auto;
+ border-radius: var(--space-2x);
+}
diff --git a/src/components/MediaSection/README.md b/src/components/MediaSection/README.md
new file mode 100644
index 00000000000..c03ad7205c6
--- /dev/null
+++ b/src/components/MediaSection/README.md
@@ -0,0 +1,44 @@
+# MediaSection Component
+
+## What it does
+
+The MediaSection component displays a section with a heading, description, and optionally an image or video. It's perfect for explaining concepts with visual aids, like showing architecture diagrams or tutorial videos.
+
+## How to use it
+
+Import the component and add it to your page with the content you want to display:
+
+```astro
+import MediaSection from "~/components/MediaSection/MediaSection.astro"
+
+
+```
+
+## Props explained
+
+- **heading** (required) - The title of your section
+- **description** (required) - A paragraph explaining the section content
+- **image** (optional) - Path to an image file you want to display
+- **video** (optional) - Path to a video file you want to display
+
+**Note:** You can provide either an image OR a video, not both. If you include both, only the image will show.
+
+## Example
+
+```astro
+
+```
+
+This will display:
+
+1. A heading that says "High-level architecture"
+2. The description text below it
+3. The architecture diagram image at the bottom
diff --git a/src/components/OverviewWrapper.astro b/src/components/OverviewWrapper.astro
new file mode 100644
index 00000000000..e3eaef0fa90
--- /dev/null
+++ b/src/components/OverviewWrapper.astro
@@ -0,0 +1,20 @@
+
+
+
diff --git a/src/components/PageContent/PageContent.astro b/src/components/PageContent/PageContent.astro
index 5e5689abf6b..e29180351b4 100644
--- a/src/components/PageContent/PageContent.astro
+++ b/src/components/PageContent/PageContent.astro
@@ -1,190 +1,224 @@
---
import { MarkdownHeading } from "astro"
-import BackButton from "./BackButton.astro"
export type Props = {
titleHeading: MarkdownHeading
+ disableDefaultStyles?: boolean
+ hideTitle?: boolean
}
-const { titleHeading } = Astro.props
+const { titleHeading, disableDefaultStyles, hideTitle } = Astro.props
---
-
- {titleHeading.text}
+
+ {titleHeading.text}
+
diff --git a/src/components/PageContent/WhatsNext.astro b/src/components/PageContent/WhatsNext.astro
index 43bd4634c79..0c1cf779674 100644
--- a/src/components/PageContent/WhatsNext.astro
+++ b/src/components/PageContent/WhatsNext.astro
@@ -1,10 +1,12 @@
---
+import { Typography } from "@chainlink/blocks"
+
export type Props = { content: Record }
const { content = {} } = Astro.props as Props
---
- What's next
+ What's next
{
Object.keys(content).map((key) => (
@@ -23,6 +25,8 @@ const { content = {} } = Astro.props as Props
h2 {
margin: 0;
+ font-weight: bold;
+ font-size: 2rem;
}
ul {
@@ -42,6 +46,7 @@ const { content = {} } = Astro.props as Props
li a {
display: inline-block;
padding: var(--space-4x);
+ color: var(--color-text-link);
width: 100%;
}
diff --git a/src/components/QuickLinkCard/QuickLinkCard.astro b/src/components/QuickLinkCard/QuickLinkCard.astro
new file mode 100644
index 00000000000..e4e13bc9e71
--- /dev/null
+++ b/src/components/QuickLinkCard/QuickLinkCard.astro
@@ -0,0 +1,44 @@
+---
+import { Typography } from "@chainlink/blocks"
+import styles from "./QuickLinkCard.module.css"
+
+interface Link {
+ icon: any
+ label: string
+ link: string
+}
+
+interface Props {
+ links: Link[]
+}
+
+const { links } = Astro.props
+---
+
+
diff --git a/src/components/QuickLinkCard/QuickLinkCard.module.css b/src/components/QuickLinkCard/QuickLinkCard.module.css
new file mode 100644
index 00000000000..f514f3a06a0
--- /dev/null
+++ b/src/components/QuickLinkCard/QuickLinkCard.module.css
@@ -0,0 +1,66 @@
+.srOnly {
+ position: absolute;
+ width: 1px;
+ height: 1px;
+ padding: 0;
+ margin: -1px;
+ overflow: hidden;
+ clip: rect(0, 0, 0, 0);
+ white-space: nowrap;
+ border-width: 0;
+}
+
+.content {
+ display: flex;
+}
+
+.sidebar {
+ width: 32px;
+ flex-shrink: 0;
+ background: url("/images/info-sidebar-img.png") lightgray 50% / cover no-repeat;
+ position: relative;
+ filter: saturate(0.6);
+}
+
+.main {
+ flex: 1;
+ min-width: 0;
+}
+
+.linksGrid {
+ display: grid;
+ grid-template-columns: 1fr;
+ gap: var(--space-6x);
+ padding: var(--space-4x) 0 calc(var(--space-4x) - 2px) var(--space-6x);
+
+ border-top: 1px solid var(--border);
+ border-bottom: 1px solid var(--border);
+ border-right: 1px solid var(--border);
+}
+
+.linkItem {
+ display: flex;
+ align-items: center;
+ gap: var(--space-2x);
+}
+
+.label {
+ font-size: 1rem;
+ font-weight: 500;
+}
+
+@media (min-width: 640px) {
+ .linksGrid {
+ grid-template-columns: repeat(2, 1fr);
+ }
+}
+
+@media (min-width: 1024px) {
+ .sidebar {
+ display: block;
+ }
+
+ .linksGrid {
+ grid-template-columns: repeat(3, 1fr);
+ }
+}
diff --git a/src/components/QuickLinkCard/README.md b/src/components/QuickLinkCard/README.md
new file mode 100644
index 00000000000..84ecff72986
--- /dev/null
+++ b/src/components/QuickLinkCard/README.md
@@ -0,0 +1,214 @@
+# QuickLinkCard Component
+
+A responsive component that displays a grid of quick links with icons, perfect for creating a "Tools & Utilities" section or similar resource lists.
+
+## What This Component Does
+
+The QuickLinkCard component creates a visually appealing section that:
+
+- Shows a decorative sidebar image on larger screens
+- Arranges your links in a responsive grid (1 column on mobile, 2 on tablet, 3 on desktop)
+- Each link has an icon and a label
+- Icons are displayed in brand color (blue)
+
+## How to Use It
+
+### Basic Usage
+
+1. Import the component and icon components in your Astro page:
+
+```astro
+---
+import QuickLinkCard from "~/components/QuickLinkCard/QuickLinkCard.astro"
+import { SvgEyeOptic, SvgStartup, SvgBulletList } from "@chainlink/blocks"
+---
+```
+
+2. Add the component with your links:
+
+```astro
+
+```
+
+## Understanding the Props
+
+The component accepts one prop called `links`, which is a list (array) of link objects. Each link object has three parts:
+
+### `icon` (required)
+
+- **What it is:** An icon component that appears next to the link
+- **Format:** A component from `@chainlink/blocks` or any other icon component
+- **Example:** `SvgEyeOptic`, `SvgStartup`, `SvgBulletList`
+- **Tip:** Use icons from the `@chainlink/blocks` package for consistency with the rest of the site
+
+### `label` (required)
+
+- **What it is:** The text that appears next to the icon
+- **Format:** Plain text
+- **Example:** `'View Network Configs'`
+- **Tip:** Keep it short and descriptive (2-4 words works best)
+
+### `link` (required)
+
+- **What it is:** Where the link goes when clicked
+- **Format:** A URL path
+- **Example:** `'/network-configs'` or `'https://example.com'`
+- **Tip:** Use relative paths (starting with `/`) for internal pages
+
+## Complete Example
+
+Here's a full example showing 6 links:
+
+```astro
+---
+import QuickLinkCard from "~/components/QuickLinkCard/QuickLinkCard.astro"
+import {
+ SvgEyeOptic,
+ SvgTransactionRepeatRecurring,
+ SvgWaveSignal,
+ SvgStartup,
+ SvgCrossChain,
+ SvgBulletList,
+} from "@chainlink/blocks"
+
+// Define your links here
+const quickLinks = [
+ {
+ icon: SvgEyeOptic,
+ label: "View Network Configs",
+ link: "https://docs.chain.link/ccip/directory/mainnet",
+ },
+ {
+ icon: SvgTransactionRepeatRecurring,
+ label: "Check Transaction Status",
+ link: "https://ccip.chain.link/",
+ },
+ {
+ icon: SvgWaveSignal,
+ label: "View Lane Status",
+ link: "https://ccip.chain.link/status",
+ },
+ {
+ icon: SvgStartup,
+ label: "Get Testnet Tokens",
+ link: "https://tokenmanager.chain.link/",
+ },
+ {
+ icon: SvgCrossChain,
+ label: "Convert Chainlink tokens",
+ link: "https://www.transporter.io/",
+ },
+ {
+ icon: SvgBulletList,
+ label: "View the Changelog",
+ link: "https://dev.chain.link/changelog?product=CCIP",
+ },
+]
+---
+
+
+```
+
+## Customizing the Look
+
+### Icon Color
+
+The icon color is set in the component itself. To change it:
+
+1. Open: `src/components/QuickLinkCard/QuickLinkCard.astro`
+2. Find line with ` `
+3. Change `"brand"` to another color from `@chainlink/blocks` (e.g., `"blue-600"`, `"green-500"`, etc.)
+
+### Spacing and Layout
+
+If you want to change spacing or other visual aspects:
+
+1. Open the file: `src/components/QuickLinkCard/QuickLinkCard.module.css`
+2. Look for the section you want to change:
+ - `.linkItem` - changes how each link looks
+ - `.linksGrid` - changes spacing and layout of the grid
+ - `.sidebar` - changes the sidebar image size
+
+### Example Customizations
+
+**Make the grid spacing tighter:**
+
+```css
+.linksGrid {
+ gap: var(--space-4x); /* Change from var(--space-6x) */
+}
+```
+
+**Change the sidebar image size:**
+
+```css
+.sidebar img {
+ width: 48px; /* Change from 32px */
+}
+```
+
+## Responsive Behavior
+
+The component automatically adapts to different screen sizes:
+
+- **Mobile (small screens):** Links stack in 1 column, sidebar image is hidden
+- **Tablet (medium screens):** Links display in 2 columns, sidebar image is hidden
+- **Desktop (large screens):** Links display in 3 columns, sidebar image appears on the left
+
+## Available Icons
+
+The `@chainlink/blocks` package provides many icons. Here are some commonly used ones:
+
+- `SvgEyeOptic` - Eye/view icon
+- `SvgTransactionRepeatRecurring` - Transaction icon
+- `SvgWaveSignal` - Signal/status icon
+- `SvgStartup` - Rocket/startup icon
+- `SvgCrossChain` - Cross-chain/transfer icon
+- `SvgBulletList` - List icon
+- And many more...
+
+Explore the `@chainlink/blocks` package to see all available icons.
+
+## Tips for Best Results
+
+1. **Icon Tips:**
+ - Use icons from `@chainlink/blocks` for consistency
+ - Keep all icons simple and recognizable
+ - Match the icon to the action (eye for "view", rocket for "get started", etc.)
+
+2. **Label Tips:**
+ - Keep labels short (2-4 words)
+ - Use action words like "View", "Check", "Get", "Convert"
+ - Be clear about what happens when the link is clicked
+
+3. **Link Tips:**
+ - Test all your links to make sure they work
+ - Use relative paths for internal pages (starts with `/`)
+ - Use full URLs for external sites (starts with `http://` or `https://`)
+
+## Need Help?
+
+If something isn't working:
+
+1. Check that all three parts (icon, label, link) are included for each link
+2. Make sure you've imported the icon components from `@chainlink/blocks`
+3. Verify that your links are correct paths
+4. Check the browser console for any error messages
diff --git a/src/components/Resource/README.md b/src/components/Resource/README.md
new file mode 100644
index 00000000000..097d6befad1
--- /dev/null
+++ b/src/components/Resource/README.md
@@ -0,0 +1,106 @@
+# ResourceGrid
+
+## What it does
+
+This component displays a grid of resource cards. Each card can represent either an article or a video, with an optional image, title, description, and link. Article cards show a "Read the full article" footer with an arrow.
+
+## How to use it
+
+1. Import the component in your Astro layout or page:
+
+```astro
+import ResourceGrid from "~/components/Resource/ResourceGrid.astro" import type {ResourceItem} from "~/components/Resource/ResourceGrid.astro"
+```
+
+2. (Optional) If you want to use imported images, import them:
+
+```astro
+import myImage from "~/assets/images/my-image.png"
+```
+
+3. Create an array of resources with the information for each resource card
+
+4. Add the component to your page and pass in the resources:
+
+```astro
+
+```
+
+## Example
+
+Here's a complete example showing how to use the component:
+
+```astro
+---
+import ResourceGrid from "~/components/Resource/ResourceGrid.astro"
+import type { ResourceItem } from "~/components/Resource/ResourceGrid.astro"
+import tokenPoolImage from "~/assets/images/token-pool.png"
+
+const resources: ResourceItem[] = [
+ {
+ image: tokenPoolImage,
+ imageAlt: "Token Pool illustration",
+ label: "Token Pool Types",
+ description:
+ "Explore the various token pool types supported by the Cross-Chain Token (CCT) standard with Chainlink Labs.",
+ link: "/resources/token-pool-types",
+ type: "article",
+ },
+ {
+ label: "Getting Started with CCIP",
+ description:
+ "Learn how to build cross-chain applications using Chainlink CCIP in this comprehensive video tutorial.",
+ link: "https://youtube.com/watch?v=example",
+ type: "video",
+ },
+ {
+ image: "/images/cross-chain-messaging.png",
+ imageAlt: "Cross-chain messaging diagram",
+ label: "Understanding Cross-Chain Messaging",
+ description: "A deep dive into how cross-chain messaging works and how to implement it in your smart contracts.",
+ link: "/resources/cross-chain-messaging",
+ type: "article",
+ },
+]
+---
+
+
+```
+
+## What you need to provide
+
+Each item in your `resources` array needs these fields:
+
+| Field | Required? | What it is | Example |
+| --------------- | --------- | -------------------------------------------------------------------------- | ---------------------------------------------------------------- |
+| **label** | Yes | The title of the resource | `"Token Pool Types"` |
+| **link** | Yes | Where the card should link to (can be internal or external) | `"/resources/token-pool-types"` or `"https://youtube.com/..."` |
+| **description** | Yes | A description explaining what the resource covers | `"Explore the various token pool types..."` |
+| **type** | Yes | The type of resource - either `"article"` or `"video"` | `"article"` |
+| **image** | No | Either an imported image or a path string | `myImage` (imported) or `"/images/token-pool.png"` (string path) |
+| **imageAlt** | No | Description of the image for accessibility (required if image is provided) | `"Token Pool illustration"` |
+
+## Where to put images
+
+Images are optional for resource cards. You have two options:
+
+### Option 1: Import images (recommended for images in your project)
+
+1. Place your image file in the `src/assets/images/` directory
+2. Import it at the top of your file:
+ ```astro
+ import myImage from "~/assets/images/my-image.png"
+ ```
+3. Use the imported variable in your resource object
+
+### Option 2: Use a path string (for public directory or external images)
+
+1. Place your image file in the `/public/images/` directory
+2. Reference it with the full path starting with `/images/`
+
+Both approaches work! Use imported images for better optimization, or use path strings for simplicity.
+
+## Resource types
+
+- **article**: Displays "Read the full article" footer with an arrow icon
+- **video**: No special footer (just the card with title and description). For video resources, the `image` prop can be a YouTube video thumbnail URL, and the `link` prop can be the YouTube video URL
diff --git a/src/components/Resource/ResourceCard.astro b/src/components/Resource/ResourceCard.astro
new file mode 100644
index 00000000000..775abded644
--- /dev/null
+++ b/src/components/Resource/ResourceCard.astro
@@ -0,0 +1,47 @@
+---
+import { Typography, SvgArrowRight2, SvgButtonPlay } from "@chainlink/blocks"
+import styles from "./ResourceCard.module.css"
+import { ResourceItem } from "./ResourceGrid.astro"
+
+type Props = ResourceItem
+
+const { image, imageAlt, label, link, description, type } = Astro.props
+
+const imageSrc = typeof image === "string" ? image : image?.src
+
+const isVideo = type === "video"
+---
+
+
+ {
+ imageSrc && (
+
+
+
+
+
+
+
+
+ )
+ }
+
+ {label}
+
+ {description}
+
+
+ {
+ type === "article" && (
+
+ )
+ }
+
diff --git a/src/components/Resource/ResourceCard.module.css b/src/components/Resource/ResourceCard.module.css
new file mode 100644
index 00000000000..af9c4cc67ad
--- /dev/null
+++ b/src/components/Resource/ResourceCard.module.css
@@ -0,0 +1,104 @@
+.card {
+ display: flex;
+ flex-direction: column;
+ background: var(--color-background);
+ padding: var(--space-6x);
+ gap: var(--space-4x);
+ border-right: 1px solid var(--border);
+ border-bottom: 1px solid var(--border);
+ text-decoration: none;
+ transition: background-color 0.2s;
+ min-height: 329px;
+ cursor: default;
+}
+
+.card:nth-child(-n + 3) {
+ border-top: 1px solid var(--border);
+}
+
+.card:hover {
+ background-color: var(--muted);
+}
+
+.overlay {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+
+.playButtonWrapper {
+ background-color: var(--brand);
+ width: 45px;
+ height: 45px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ & svg {
+ color: var(--white);
+ fill: var(--white);
+ }
+}
+
+.imageWrapper {
+ width: 100%;
+ aspect-ratio: 16 / 9;
+ overflow: hidden;
+ border-radius: var(--space-2x);
+ position: relative;
+}
+
+.image {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+}
+
+.content {
+ display: flex;
+ flex-direction: column;
+ flex: 1;
+}
+
+.cardLabel {
+ font-size: 16px;
+ font-weight: 525;
+ color: var(--foreground);
+ margin-bottom: var(--space-2x);
+}
+
+.cardFooter {
+ display: flex;
+ align-items: center;
+ width: 100%;
+ gap: var(--space-2x);
+ margin-top: var(--space-4x);
+}
+
+.footerText {
+ font-size: 14px;
+ color: var(--color-text-secondary);
+}
+@media screen and (max-width: 1024px) {
+ .card:nth-child(-n + 3) {
+ border-top: none;
+ }
+
+ .card:nth-child(-n + 2) {
+ border-top: 1px solid var(--border);
+ }
+}
+
+@media screen and (max-width: 768px) {
+ .card:nth-child(n) {
+ border-top: none;
+ }
+
+ .card:nth-child(1) {
+ border-top: 1px solid var(--border);
+ }
+}
diff --git a/src/components/Resource/ResourceGrid.astro b/src/components/Resource/ResourceGrid.astro
new file mode 100644
index 00000000000..1ec37d2aac1
--- /dev/null
+++ b/src/components/Resource/ResourceGrid.astro
@@ -0,0 +1,24 @@
+---
+import type { ImageMetadata } from "astro"
+import ResourceCard from "./ResourceCard.astro"
+import styles from "./ResourceGrid.module.css"
+
+export interface ResourceItem {
+ image?: string | ImageMetadata
+ imageAlt?: string
+ label: string
+ link: string
+ description: string
+ type: "article" | "video"
+}
+
+interface Props {
+ resources: ResourceItem[]
+}
+
+const { resources } = Astro.props
+---
+
+
+ {resources.map((resource) => )}
+
diff --git a/src/components/Resource/ResourceGrid.module.css b/src/components/Resource/ResourceGrid.module.css
new file mode 100644
index 00000000000..02cb548eeb9
--- /dev/null
+++ b/src/components/Resource/ResourceGrid.module.css
@@ -0,0 +1,17 @@
+.grid {
+ display: grid;
+ grid-template-columns: repeat(3, 1fr);
+ border-left: 1px solid var(--border);
+}
+
+@media (max-width: 1024px) {
+ .grid {
+ grid-template-columns: repeat(2, 1fr);
+ }
+}
+
+@media (max-width: 768px) {
+ .grid {
+ grid-template-columns: 1fr;
+ }
+}
diff --git a/src/components/Resource/ResourceSection.astro b/src/components/Resource/ResourceSection.astro
new file mode 100644
index 00000000000..148f2b2213d
--- /dev/null
+++ b/src/components/Resource/ResourceSection.astro
@@ -0,0 +1,23 @@
+---
+import { Typography } from "@chainlink/blocks"
+import ResourceGrid from "./ResourceGrid.astro"
+import type { ResourceItem } from "./ResourceGrid.astro"
+import styles from "./ResourceSection.module.css"
+
+interface Props {
+ title: string
+ resources: ResourceItem[]
+}
+
+const { title, resources } = Astro.props
+---
+
+
diff --git a/src/components/Resource/ResourceSection.module.css b/src/components/Resource/ResourceSection.module.css
new file mode 100644
index 00000000000..434df633c45
--- /dev/null
+++ b/src/components/Resource/ResourceSection.module.css
@@ -0,0 +1,11 @@
+.section {
+ display: flex;
+ flex-direction: column;
+ gap: var(--space-8x);
+}
+
+@media screen and (max-width: 425px) {
+ .section {
+ gap: var(--space-6x);
+ }
+}
diff --git a/src/components/RightSidebar/MoreMenu.astro b/src/components/RightSidebar/MoreMenu.astro
index 75e14d7fc79..3ea4d3d931f 100644
--- a/src/components/RightSidebar/MoreMenu.astro
+++ b/src/components/RightSidebar/MoreMenu.astro
@@ -63,48 +63,6 @@ const supportedLanguages = cfg?.languages || []
)
}
-
- {
- CONFIG.COMMUNITY_INVITE_URL && (
-
- )
- }
diff --git a/src/components/ToolsUtilitiesGrid/README.md b/src/components/ToolsUtilitiesGrid/README.md
new file mode 100644
index 00000000000..550b5ae7de0
--- /dev/null
+++ b/src/components/ToolsUtilitiesGrid/README.md
@@ -0,0 +1,82 @@
+# ToolsUtilitiesGrid
+
+## What it does
+
+This component displays a grid of clickable cards that showcase tools and utilities. Each card includes an icon, title, description, and link. It's perfect for creating a visual directory of resources, tools, or utilities that users can browse and click through to.
+
+## How to use it
+
+1. Import the component in your Astro layout or page:
+
+```astro
+import ToolsUtilitiesGrid from "~/components/ToolsUtilitiesGrid/ToolsUtilitiesGrid.astro"
+```
+
+2. Create an array of links with the information for each tool/utility you want to display
+
+3. Add the component to your page and pass in the links:
+
+```astro
+
+```
+
+## Example
+
+Here's a complete example showing how to use the component:
+
+```astro
+---
+import ToolsUtilitiesGrid from "~/components/ToolsUtilitiesGrid/ToolsUtilitiesGrid.astro"
+
+const toolsAndUtilities = [
+ {
+ image: "/images/ccip-logo.svg",
+ imageAlt: "CCIP API icon",
+ label: "CCIP API",
+ link: "/ccip/api",
+ description: "An API for message retrieval and lane latency information.",
+ },
+ {
+ image: "/images/js-logo.svg",
+ imageAlt: "JavaScript SDK icon",
+ label: "Javascript SDK",
+ link: "https://github.com/smartcontractkit/ccip-javascript-sdk",
+ description: "Integrate CCIP functionality directly into your web applications for EVM-compatible chains.",
+ },
+ {
+ image: "/images/hardhat-logo.svg",
+ imageAlt: "Hardhat icon",
+ label: "Hardhat Starter Kit",
+ link: "https://github.com/smartcontractkit/hardhat-starter-kit",
+ description:
+ "Ready-to-go boilerplate for basic CCIP use cases that help you get started building quickly with Hardhat.",
+ },
+]
+---
+
+
+```
+
+## What you need to provide
+
+Each item in your `links` array needs these fields:
+
+| Field | What it is | Example |
+| --------------- | ----------------------------------------------------------- | -------------------------------------------------------------- |
+| **image** | The full path to the icon/logo image | `"/images/ccip-logo.svg"` |
+| **imageAlt** | Description of the image for accessibility | `"CCIP API icon"` |
+| **label** | The title/name of the tool or utility | `"CCIP API"` |
+| **link** | Where the card should link to (can be internal or external) | `"/ccip/api"` or `"https://github.com/..."` |
+| **description** | A short description explaining what the tool does | `"An API for message retrieval and lane latency information."` |
+
+## Where to put images
+
+Place your icon/logo images in the `/public/images/` directory, and reference them with the full path starting with `/images/`.
+
+For example, if you use `image: "/images/my-tool-logo.svg"`, the actual file should be at:
+
+```
+/public/images/my-tool-logo.svg
+```
+
+You can also use images from other locations by providing the full path (e.g., `"/assets/logos/my-logo.png"`).
diff --git a/src/components/ToolsUtilitiesGrid/ToolItem.astro b/src/components/ToolsUtilitiesGrid/ToolItem.astro
new file mode 100644
index 00000000000..eb5b7f590c7
--- /dev/null
+++ b/src/components/ToolsUtilitiesGrid/ToolItem.astro
@@ -0,0 +1,28 @@
+---
+import { Typography } from "@chainlink/blocks"
+import styles from "./toolsUtilities.module.css"
+import { Link } from "./types"
+
+type Props = Link
+
+const { description, image, imageAlt, label, link } = Astro.props
+---
+
+
+
+
+
+
+ {label}
+ {description}
+
+
+
+
+
diff --git a/src/components/ToolsUtilitiesGrid/ToolsUtilitiesGrid.astro b/src/components/ToolsUtilitiesGrid/ToolsUtilitiesGrid.astro
new file mode 100644
index 00000000000..fa875b286c8
--- /dev/null
+++ b/src/components/ToolsUtilitiesGrid/ToolsUtilitiesGrid.astro
@@ -0,0 +1,26 @@
+---
+import styles from "./toolsUtilities.module.css"
+
+import { Link } from "./types"
+import ToolItem from "./ToolItem.astro"
+import { Typography } from "@chainlink/blocks"
+
+interface Props {
+ links: Link[]
+}
+
+const { links } = Astro.props
+---
+
+
+ Tools & Utilities
+
+
+ {links.map((link) => )}
+
+
diff --git a/src/components/ToolsUtilitiesGrid/toolsUtilities.module.css b/src/components/ToolsUtilitiesGrid/toolsUtilities.module.css
new file mode 100644
index 00000000000..c1e36191486
--- /dev/null
+++ b/src/components/ToolsUtilitiesGrid/toolsUtilities.module.css
@@ -0,0 +1,60 @@
+.container {
+ display: grid;
+ grid-template-columns: repeat(3, 1fr);
+ margin-top: var(--space-8x);
+}
+
+.card {
+ padding: var(--space-6x);
+ display: flex;
+ gap: var(--space-4x);
+ align-items: start;
+}
+
+.card:hover {
+ background: var(--muted);
+ & .arrow {
+ opacity: 1;
+ }
+}
+
+.imageContainer {
+ min-width: 48px;
+ height: 48px;
+ background: var(--background-alt);
+ border: 1px solid var(--border);
+ border-radius: var(--space-1x);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.content {
+ display: flex;
+
+ & > img {
+ align-self: end;
+ }
+}
+
+.arrow {
+ opacity: 0;
+}
+
+@media screen and (max-width: 1135px) {
+ .container {
+ grid-template-columns: repeat(2, 1fr);
+ }
+}
+
+@media screen and (max-width: 525px) {
+ .container {
+ grid-template-columns: repeat(1, 1fr);
+ }
+}
+
+@media screen and (max-width: 425px) {
+ .container {
+ margin-top: var(--space-6x);
+ }
+}
diff --git a/src/components/ToolsUtilitiesGrid/types.ts b/src/components/ToolsUtilitiesGrid/types.ts
new file mode 100644
index 00000000000..2c645744a9f
--- /dev/null
+++ b/src/components/ToolsUtilitiesGrid/types.ts
@@ -0,0 +1,7 @@
+export interface Link {
+ image: string
+ imageAlt: string
+ label: string
+ link: string
+ description: string
+}
diff --git a/src/components/TryItOut/README.md b/src/components/TryItOut/README.md
new file mode 100644
index 00000000000..50a8e94c97a
--- /dev/null
+++ b/src/components/TryItOut/README.md
@@ -0,0 +1,92 @@
+# TryItOut Component
+
+A component that displays an interactive accordion of features alongside a dynamically changing code sample preview. The code sample updates based on which accordion item is currently expanded.
+
+## Usage
+
+```astro
+
+```
+
+## Props
+
+### `accordionTabs` (required)
+
+A list of expandable sections that describe different features. Each tab needs:
+
+- **title**: The heading text for the accordion item
+- **text**: The description that appears when the accordion is expanded
+- **codeSampleSrc**: The file path to the code sample for this specific tab (should point to a file in the `/samples/` folder)
+
+**Example:**
+
+```js
+;[
+ {
+ title: "Transfer Tokens",
+ text: "Move tokens between different blockchains easily.",
+ codeSampleSrc: "/samples/CCIP/TokenTransfer.sol",
+ },
+ {
+ title: "Fetch Data",
+ text: "Get real-time information from external sources.",
+ codeSampleSrc: "/samples/DataFeeds/PriceFeed.sol",
+ },
+]
+```
+
+### `ctas` (optional)
+
+An array of call-to-action buttons to display in the footer. If not provided, defaults to "Create CRE account" and "Get the SDK" buttons.
+
+Each CTA object needs:
+
+- **text**: The button text
+- **href**: The button link URL
+- **variant** (optional): Either "primary" or "secondary" (defaults to "primary")
+
+**Example:**
+
+```js
+;[
+ { text: "Get Started", href: "/getting-started", variant: "primary" },
+ { text: "View Docs", href: "/documentation", variant: "secondary" },
+]
+```
+
+## How It Works
+
+The component uses [Astro's nano stores](https://docs.astro.build/en/core-concepts/sharing-state/) to track which accordion item is currently expanded. When you click on a different accordion item, the code sample automatically updates to show the code associated with that item.
+
+### Technical Implementation
+
+**Why we pre-render all code samples:**
+
+All code samples are rendered at build time using the `` Astro component and included in the HTML. While this means all code samples are present in the DOM, they are toggled via visibility rather than dynamically loaded. This approach is necessary because:
+
+1. **Astro components are build-time only** - The `` component uses Astro's Prism integration which only runs during the build process, not at runtime
+2. **Proper syntax highlighting** - Pre-rendering ensures all code has proper syntax highlighting applied via Prism
+3. **Performance** - No runtime file reading or syntax highlighting processing; instant switching between code samples
+4. **Simplicity** - Avoids complex API endpoints or client-side file fetching
+
+**Accessibility considerations:**
+
+Inactive code samples are hidden from both visual users and assistive technology:
+
+- `display: none` hides them visually
+- `aria-hidden="true"` ensures screen readers ignore hidden code blocks
+- Only the active code sample has `aria-hidden="false"`, making it visible to screen readers
+
+When the active accordion changes, the visibility and `aria-hidden` attributes are updated via JavaScript to show the new code sample and hide all others.
diff --git a/src/components/TryItOut/TryItOut.astro b/src/components/TryItOut/TryItOut.astro
new file mode 100644
index 00000000000..c015f66c5bf
--- /dev/null
+++ b/src/components/TryItOut/TryItOut.astro
@@ -0,0 +1,106 @@
+---
+import { buttonVariants, Typography } from "@chainlink/blocks"
+import styles from "./styles.module.css"
+import CodeSample from "../CodeSample/CodeSample.astro"
+import { TryItOutAccordion } from "./TryItOutAccordion"
+import { clsx } from "~/lib/clsx/clsx"
+
+interface CTA {
+ text: string
+ href: string
+ variant?: "primary" | "secondary"
+}
+
+interface Props {
+ accordionTabs: Array<{ title: string; text: string; codeSampleSrc: string }>
+ ctas: CTA[]
+}
+
+const { accordionTabs, ctas } = Astro.props
+---
+
+
+
+ Try it out
+
+
+
+
+
+
+
+
+
+ {
+ accordionTabs.map((tab, index) => (
+
+
+
+ ))
+ }
+
+
+
+
+
+
+
+
diff --git a/src/components/TryItOut/TryItOutAccordion.tsx b/src/components/TryItOut/TryItOutAccordion.tsx
new file mode 100644
index 00000000000..7328daa63ab
--- /dev/null
+++ b/src/components/TryItOut/TryItOutAccordion.tsx
@@ -0,0 +1,37 @@
+import { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Typography } from "@chainlink/blocks"
+import { activeAccordionIndex } from "~/stores/tryItOutStore.ts"
+import styles from "./styles.module.css"
+
+interface AccordionTab {
+ title: string
+ text: string
+ codeSampleSrc: string
+}
+
+interface TryItOutAccordionProps {
+ tabs: AccordionTab[]
+}
+
+export const TryItOutAccordion = ({ tabs }: TryItOutAccordionProps) => {
+ const handleValueChange = (value: string) => {
+ if (value) {
+ activeAccordionIndex.set(parseInt(value, 10))
+ }
+ }
+
+ return (
+
+ {tabs.map((tab, idx) => (
+
+
+ {tab.title}{" "}
+
+ 0{idx + 1}
+
+
+ {tab.text}
+
+ ))}
+
+ )
+}
diff --git a/src/components/TryItOut/styles.module.css b/src/components/TryItOut/styles.module.css
new file mode 100644
index 00000000000..9aed11c8332
--- /dev/null
+++ b/src/components/TryItOut/styles.module.css
@@ -0,0 +1,124 @@
+.container {
+ background-color: var(--tertiary-foreground);
+ padding: var(--space-10x) var(--space-16x);
+ margin: 86px 0;
+}
+
+.title {
+ margin-bottom: var(--space-8x);
+ color: var(--background);
+}
+
+.secondaryBtn {
+ color: var(--muted-on-surface);
+}
+
+.contentFooter {
+ display: flex;
+ gap: var(--space-6x);
+ margin-top: 55px;
+}
+
+.content {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ justify-content: space-between;
+ gap: var(--space-24x);
+}
+
+.accordionItem {
+ border-bottom: none;
+ border-top: 1px solid var(--segment-button-foreground);
+ display: flex;
+ flex-direction: column;
+
+ * {
+ transition: all 0.2s linear;
+ }
+}
+
+.contentLeft {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+}
+
+.text {
+ color: var(--muted-more-foreground);
+}
+
+.indicator {
+ color: var(--segment-button-foreground);
+}
+
+.accordionTrigger {
+ color: var(--muted-more-foreground);
+ padding: var(--space-4x) 0;
+ border: none;
+ outline: none;
+ & p {
+ color: var(--muted-more-foreground);
+ }
+
+ & svg {
+ display: none;
+ }
+
+ & span {
+ word-wrap: normal;
+ }
+}
+
+.image {
+ width: 100%;
+ max-height: 412px;
+ overflow-y: auto;
+ border-bottom: 1.5px solid var(--stepper-counter-pending-foreground);
+ border-radius: 6.317px;
+}
+
+.accordionItem[data-state="open"] {
+ border-top: 2px solid var(--link);
+
+ & .accordionTrigger {
+ color: var(--background);
+ }
+ & .indicator {
+ color: var(--link);
+ }
+}
+
+.body {
+ max-width: var(--fullwidth-max-width);
+ width: 100%;
+ margin: 0 auto;
+}
+
+.contentFooterMobile {
+ display: none;
+ gap: var(--space-6x);
+}
+
+@media screen and (max-width: 425px) {
+ .contentFooterMobile {
+ flex-direction: column;
+ }
+}
+
+@media screen and (max-width: 768px) {
+ .content {
+ grid-template-columns: 1fr;
+ gap: var(--space-8x);
+ }
+
+ .title {
+ font-size: 28px;
+ }
+ .contentFooter {
+ display: none;
+ }
+
+ .contentFooterMobile {
+ display: flex;
+ }
+}
diff --git a/src/config/sidebar.ts b/src/config/sidebar.ts
index c70e3d9195a..1c12da7186f 100644
--- a/src/config/sidebar.ts
+++ b/src/config/sidebar.ts
@@ -1731,6 +1731,7 @@ export const SIDEBAR: Partial> = {
},
],
[SIDEBAR_SECTIONS.CCIP]: CCIP_SIDEBAR_CONTENT,
+
[SIDEBAR_SECTIONS.CHAINLINK_LOCAL]: [
{
section: "Chainlink Local",
diff --git a/src/content.config.ts b/src/content.config.ts
index 10fa1b090e7..bb9b9e18c17 100644
--- a/src/content.config.ts
+++ b/src/content.config.ts
@@ -60,6 +60,8 @@ const baseFrontmatter = z
whatsnext: z.record(z.string(), z.string()).optional(),
isMdx: z.boolean().optional(),
isIndex: z.boolean().optional(),
+ disableDefaultStyles: z.boolean().optional(),
+ hideTitle: z.boolean().optional(),
metadata,
datafeedtype: z.string().optional(),
fileExtension: z.string().optional(),
diff --git a/src/content/ccip/index.mdx b/src/content/ccip/index.mdx
index 796470376fc..8cd03f72240 100644
--- a/src/content/ccip/index.mdx
+++ b/src/content/ccip/index.mdx
@@ -8,27 +8,283 @@ metadata:
datePublished: "2023-08-03"
lastModified: "2025-05-19"
isIndex: true
-whatsnext:
- "Complete the Getting Started guide to learn the basics": "/ccip/getting-started"
- "CCIP Directory": "/ccip/directory"
- "Learn how to transfer tokens": "/ccip/tutorials/evm/transfer-tokens-from-contract"
- "Learn more about CCIP architecture": "/ccip/concepts/architecture"
+disableDefaultStyles: true
+hideTitle: true
---
-import { ClickToZoom, Aside } from "@components"
-import CcipCommon from "@features/ccip/CcipCommon.astro"
-
-
-
-Blockchain interoperability protocols are important for the Web3 ecosystem and traditional systems that need to interact with different blockchains. These protocols are the foundation for building blockchain abstraction layers, allowing traditional backends and dApps to interact with any blockchain network through a single middleware solution. Without a blockchain interoperability protocol, Web2 systems and dApps would need to build separate in-house implementations for each cross-chain interaction that they want to use, which is a time-consuming, resource-intensive, and complex process.
-
-Blockchain interoperability protocols provide the following capabilities:
-
-- You can transfer assets and information across multiple blockchains.
-- Application developers can leverage the strengths and benefits of different chains.
-- Collaboration between developers from diverse blockchain ecosystems enables the building of cross-chain applications to serve more users and provide additional features or products for them.
-
-The _Chainlink Cross-Chain Interoperability Protocol (CCIP)_ provides these capabilities and enables a variety of [use cases](#common-use-cases).
+import LayoutHero from "@components/LayoutHero/LayoutHero.astro"
+import { TabGrid } from "@components/TabGrid/TabGrid.tsx"
+import ResourceSection from "@components/Resource/ResourceSection.astro"
+import QuickLinkCard from "@components/QuickLinkCard/QuickLinkCard.astro"
+import ToolsUtilitiesGrid from "@components/ToolsUtilitiesGrid/ToolsUtilitiesGrid.astro"
+import MediaSection from "@components/MediaSection/MediaSection.astro"
+import CardsWrapper from "@components/Cards/CardsWrapper.astro"
+import OverviewWrapper from "@components/OverviewWrapper.astro"
+import ChangelogSnippet from "@components/ChangelogSnippet/ChangelogSnippet.astro"
+import {
+ SvgEyeOptic,
+ SvgTransactionRepeatRecurring,
+ SvgWaveSignal,
+ SvgStartup,
+ SvgCrossChain,
+ SvgBulletList,
+} from "@chainlink/blocks"
+import { ClickToZoom } from "@components"
+
+export const toolsAndUtilities = [
+ {
+ image: "/images/ccip-logo.svg",
+ imageAlt: "CCIP API icon",
+ label: "CCIP API",
+ link: "/ccip/api-reference",
+ description: "An API for message retrieval and lane latency information.",
+ },
+ {
+ image: "/images/js-logo.svg",
+ imageAlt: "JavaScript SDK icon",
+ label: "Javascript SDK",
+ link: "https://github.com/smartcontractkit/ccip-javascript-sdk",
+ description: "Integrate CCIP functionality directly into your web applications for EVM-compatible chains.",
+ },
+ {
+ image: "/images/ts-logo.svg",
+ imageAlt: "CLI icon",
+ label: "CLI",
+ link: "https://github.com/smartcontractkit/ccip-tools-ts",
+ description: "TypeScript command-line interface and library designed for interacting with deployed CCIP contracts.",
+ },
+ {
+ image: "/images/hardhat-logo.svg",
+ imageAlt: "Hardhat icon",
+ label: "Hardhat Starter Kit",
+ link: "https://github.com/smartcontractkit/hardhat-starter-kit",
+ description:
+ "Ready-to-go boilerplate for basic CCIP use cases that help you get started building quickly with Hardhat.",
+ },
+ {
+ image: "/images/foundry-logo.svg",
+ imageAlt: "Foundry icon",
+ label: "Foundry Starter Kit",
+ link: "https://github.com/smartcontractkit/foundry-starter-kit",
+ description:
+ "Ready-to-go boilerplate for basic CCIP use cases that help you get started building quickly with Foundry.",
+ },
+ {
+ image: "/images/npm-logo.png",
+ imageAlt: "NPM icon",
+ label: "CCIP Contracts NPM",
+ link: "https://www.npmjs.com/package/@chainlink/contracts-ccip",
+ description:
+ "An npm package providing Solidity smart contract implementations to integrate CCIP into your EVM-based project.",
+ },
+ {
+ image: "/images/direct-stacking-logo.svg",
+ imageAlt: "Direct Staking icon",
+ label: "Direct Staking",
+ link: "https://github.com/Aphyla/chainlink-csr",
+ description:
+ "Stake native tokens on supported L2 networks and receive liquid staked tokens directly on the same chain.",
+ },
+]
+
+export const exampleResources = [
+ {
+ label: "Token Pool Types",
+ description:
+ "Explore the various token pool types supported by the Cross-Chain Token (CCT) standard with Chainlink Labs. Explore the various token pool types supported by the Cross-Chain Token (CCT) standard with Chainlink Labs...",
+ link: "/",
+ type: "article",
+ },
+ {
+ label: "Token Pool Types",
+ description:
+ "Explore the various token pool types supported by the Cross-Chain Token (CCT) standard with Chainlink Labs. Explore the various token pool types supported by the Cross-Chain Token (CCT) standard with Chainlink Labs...",
+ link: "/",
+ type: "article",
+ },
+ {
+ label: "Token Pool Types",
+ description:
+ "Explore the various token pool types supported by the Cross-Chain Token (CCT) standard with Chainlink Labs. Explore the various token pool types supported by the Cross-Chain Token (CCT) standard with Chainlink Labs...",
+ link: "/",
+ type: "article",
+ },
+]
+
+export const exampleTutorials = [
+ {
+ name: "EVM",
+ links: [
+ {
+ title: "Acquire Test Tokens",
+ description: "Get test tokens in minutes; build and test cross-chain apps with zero friction.",
+ link: "/ccip/test-tokens",
+ },
+ {
+ title: "Transfer Tokens",
+ description: "Unlock seamless token transfers from contracts; learn, code, and deploy.",
+ link: "/ccip/tutorials/evm/transfer-tokens-from-contract",
+ },
+ {
+ title: "Transfer Tokens with Data",
+ description: "Go beyond basic transfers with logic-infused token movements in your EVM contracts.",
+ link: "/ccip/tutorials/evm/programmable-token-transfers",
+ },
+ {
+ title: "Using the Token Manager",
+ description: "Effortlessly manage CCTs by tracking, importing and organizing tokens from your dashboard.",
+ link: "/ccip/tutorials/evm/token-manager",
+ },
+ {
+ title: "Using the JS SDK",
+ description: "Integrate CCIP in your frontend or backend effortlessly with JavaScript SDK.",
+ link: "/ccip/ccip-javascript-sdk",
+ },
+ {
+ title: "Check Message Status",
+ description: "Retrieve real-time status of your offchain transaction from EVM.",
+ link: "/ccip/tutorials/evm/offchain/get-status-offchain",
+ },
+ {
+ title: "Transfer Tokens Between EOAs",
+ description: "Send tokens offchain from an Externally Owned Account with clear steps.",
+ link: "/ccip/tutorials/evm/offchain/transfer-tokens-from-eoa",
+ },
+ {
+ title: "Using the CLI",
+ description: "Use offchain tools from CCIP to simplify your Ethereum workflows.",
+ link: "/ccip/tutorials/evm/offchain/ccip-tools",
+ },
+ {
+ title: "Deploy and Register a CCT",
+ description: "Use RemixIDE to launch and configure tokens for cross-chain transfers on CCIP.",
+ link: "/ccip/tutorials/evm/cross-chain-tokens/register-from-eoa-remix",
+ },
+ {
+ title: "Register CCT Burn & Mint EOA",
+ description: "Implement burn-mint cross-chain token logic with CCIP using Hardhat or Foundry.",
+ link: "/ccip/tutorials/evm/cross-chain-tokens/register-from-eoa-burn-mint-hardhat",
+ },
+ {
+ title: "Register CCT Lock & Mint EOA",
+ description: "Implement a lock-mint token registration workflow with CCIP and Hardhat or Foundry.",
+ link: "/ccip/tutorials/evm/cross-chain-tokens/register-from-eoa-lock-mint-hardhat",
+ },
+ {
+ title: "Set Token Pool Rate Limits",
+ description: "Update rate limiter settings for your cross-chain tokens using Hardhat or Foundry.",
+ link: "/ccip/tutorials/evm/cross-chain-tokens/update-rate-limiters-hardhat",
+ },
+ ],
+ },
+ {
+ name: "Solana",
+ links: [
+ {
+ title: "Getting Started with Solana",
+ description: "Learn the basics of building on Solana blockchain.",
+ link: "/ccip/tutorials/svm",
+ },
+ {
+ title: "Solana Token Transfers",
+ description: "Transfer tokens on the Solana blockchain.",
+ link: "/ccip/tutorials/svm/source/token-transfers",
+ },
+ ],
+ },
+ {
+ name: "Aptos",
+ links: [
+ {
+ title: "Getting Started with Aptos",
+ description: "Start building on the Aptos blockchain.",
+ link: "/ccip/tutorials/aptos",
+ },
+ ],
+ },
+]
+
+export const quickLinks = [
+ {
+ icon: SvgEyeOptic,
+ label: "View Network Configs",
+ link: "https://docs.chain.link/ccip/directory/mainnet",
+ },
+ {
+ icon: SvgTransactionRepeatRecurring,
+ label: "Check Transaction Status",
+ link: "https://ccip.chain.link/",
+ },
+ {
+ icon: SvgWaveSignal,
+ label: "View Lane Status",
+ link: "https://ccip.chain.link/status",
+ },
+ {
+ icon: SvgStartup,
+ label: "Get Testnet Tokens",
+ link: "https://tokenmanager.chain.link/",
+ },
+ {
+ icon: SvgCrossChain,
+ label: "Convert Chainlink tokens",
+ link: "https://www.transporter.io/",
+ },
+ {
+ icon: SvgBulletList,
+ label: "View the Changelog",
+ link: "https://dev.chain.link/changelog?product=CCIP",
+ },
+]
+
+export const cardLinks = [
+ {
+ title: "Deploy/enable a token across multiple chains",
+ description:
+ "Create a new Cross-Chain-Token or enable an established one that can be launched on 50+ chains, providing unparalleled interoperability and reach.",
+ links: [
+ {
+ icon: "token",
+ href: "https://example.com",
+ label: "View Token Manager",
+ },
+ {
+ icon: "remix",
+ href: "https://example.com",
+ label: "Open in Remix",
+ },
+ ],
+ },
+ {
+ title: "Bridge a token",
+ description:
+ "Securely transfer tokens - including ETH, USDC, LINK - and messages between different blockchain networks.",
+ links: [
+ {
+ icon: "token",
+ href: "https://example.com",
+ label: "View Token Manager",
+ },
+ {
+ icon: "remix",
+ href: "https://example.com",
+ label: "Open in Remix",
+ },
+ ],
+ },
+ {
+ title: "Send a token with data",
+ description:
+ "Build token transfers that do more than move value, letting you embed business logic directly into your cross-chain workflows.",
+ links: [
+ {
+ icon: "remix",
+ href: "https://example.com",
+ label: "Open in Remix",
+ },
+ ],
+ },
+]
## What is Chainlink CCIP?
@@ -50,52 +306,3 @@ CCIP's robust security framework is built upon several core components:
/>
To understand how Chainlink CCIP works, refer to the [architecture](/ccip/concepts/architecture/overview) section. If you are new to using Chainlink CCIP, read these guides before you deploy any contracts that use CCIP.
-
-## Chainlink CCIP core capabilities
-
-Chainlink CCIP supports three main capabilities:
-
-### Arbitrary Messaging
-
-The ability to send arbitrary data (encoded as bytes) to a receiving smart contract on a different blockchain. The developer is free to encode any data they wish to send.
-
-Typically, developers use arbitrary messaging to trigger an informed action on the receiving smart contract, such as rebalancing an index, minting a specific NFT, or calling an arbitrary function with the sent data as custom parameters. Developers can encode multiple instructions in a single message, enabling them to orchestrate complex, multi-step, multi-chain tasks.
-
-### Token Transfer
-
-The ability to transfer tokens to an account on a different blockchain. This capability enables the seamless movement of assets across chains.
-
-### Programmable Token Transfer
-
-The ability to simultaneously transfer tokens and arbitrary data (encoded as bytes) within a single transaction. This mechanism allows users to transfer tokens and send instructions on what to do with those tokens.
-
-For example, a user could transfer tokens to a lending protocol with instructions to leverage those tokens as collateral for a loan, borrowing another asset to be sent back to the user.
-
-### Receiving account types
-
-With CCIP, you send transactions with data (arbitrary messaging), tokens, or both data and tokens (programmable token transfer). The receiver of a CCIP transaction varies by blockchain family:
-
-| CCIP capability | What is sent | Receiving account types |
-| --------------------------- | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
-| Arbitrary Messaging | Data | EVM: Smart contracts only SVM: Programs only Aptos: Modules only |
-| Token Transfer | Tokens | EVM: Smart contracts and EOAs SVM: User wallets or program-controlled PDAs Aptos: User accounts or modules deployed to resource accounts |
-| Programmable Token Transfer | Data and tokens | EVM: Smart contracts only SVM: Data to programs, tokens to program-controlled PDAs Aptos: Modules deployed to resource accounts |
-
-**Note**: On EVM chains, EOAs cannot receive messages. On Solana (SVM), programs work with Program Derived Addresses (PDAs) to manage token reception.
-
-## Common use cases
-
-Chainlink CCIP enables a variety of use cases:
-
-- **Cross-chain lending:** Chainlink CCIP enables users to lend and borrow a wide range of crypto assets across multiple DeFi platforms running on independent chains.
-- **Low-cost transaction computation:** Chainlink CCIP can help offload the computation of transaction data on cost-optimized chains.
-- **Optimizing cross-chain yield:** Users can leverage Chainlink CCIP to move collateral to new DeFi protocols to maximize yield across chains.
-- **Creating new kinds of dApps:** Chainlink CCIP enables users to take advantage of network effects on certain chains while harnessing compute and storage capabilities of other chains.
-
-Read [What Are Cross-Chain Smart Contracts](https://chain.link/education-hub/cross-chain-smart-contracts) to learn about cross-chain smart contracts and examples of use cases they enable.
-
-## CCIP Directory
-
-See the [CCIP Directory](/ccip/directory) page for a list of supported networks, tokens, and contract addresses.
-
-To learn about tokens, token pools, and the token onboarding process, see the [CCIP Architecture](/ccip/concepts/cross-chain-token/evm/token-pools) page.
diff --git a/src/features/landing/sections/ProductTabs.astro b/src/features/landing/sections/ProductTabs.astro
deleted file mode 100644
index 5e7a9b97b8d..00000000000
--- a/src/features/landing/sections/ProductTabs.astro
+++ /dev/null
@@ -1,8 +0,0 @@
----
-import { Tabs } from "../components/Tabs"
-import productTabs from "./ProductTabs.module.css"
----
-
-
-
-
diff --git a/src/features/landing/sections/ProductTabs.module.css b/src/features/landing/sections/ProductTabs.module.css
deleted file mode 100644
index 8eed3c59bb1..00000000000
--- a/src/features/landing/sections/ProductTabs.module.css
+++ /dev/null
@@ -1,4 +0,0 @@
-.container {
- padding-top: var(--space-6x);
- padding-bottom: 60px;
-}
diff --git a/src/hooks/useLaneTokens.ts b/src/hooks/useLaneTokens.ts
new file mode 100644
index 00000000000..12fcdc3e808
--- /dev/null
+++ b/src/hooks/useLaneTokens.ts
@@ -0,0 +1,64 @@
+import { useMemo } from "react"
+import { Environment, LaneFilter, Version } from "~/config/data/ccip/types.ts"
+import { getTokenData } from "~/config/data/ccip/data.ts"
+import { getTokenIconUrl } from "~/features/utils/index.ts"
+import { realtimeDataService } from "~/lib/ccip/services/realtime-data-instance.ts"
+
+export interface ProcessedToken {
+ id: string
+ data: ReturnType
+ logo: string
+ rateLimits: {
+ standard: { capacity: string; rate: string; isEnabled: boolean } | null
+ ftf: { capacity: string; rate: string; isEnabled: boolean } | null
+ }
+ isPaused: boolean
+}
+
+interface UseLaneTokensParams {
+ tokens: string[] | undefined
+ environment: Environment
+ rateLimitsData: Record
+ inOutbound: LaneFilter
+ searchQuery: string
+}
+
+export function useLaneTokens({ tokens, environment, rateLimitsData, inOutbound, searchQuery }: UseLaneTokensParams) {
+ const processedTokens = useMemo(() => {
+ if (!tokens) return []
+
+ const direction = inOutbound === LaneFilter.Outbound ? "out" : "in"
+
+ return tokens
+ .filter((token) => token.toLowerCase().includes(searchQuery.toLowerCase()))
+ .map((token) => {
+ const data = getTokenData({
+ environment,
+ version: Version.V1_2_0,
+ tokenId: token || "",
+ })
+
+ // Skip tokens with no data
+ if (!Object.keys(data).length) return null
+
+ const logo = getTokenIconUrl(token)
+ const tokenRateLimits = rateLimitsData[token]
+ const allLimits = realtimeDataService.getAllRateLimitsForDirection(tokenRateLimits, direction)
+ const isPaused = allLimits.standard?.capacity === "0"
+
+ return {
+ id: token,
+ data,
+ logo,
+ rateLimits: allLimits,
+ isPaused,
+ }
+ })
+ .filter((token): token is ProcessedToken => token !== null)
+ }, [tokens, environment, rateLimitsData, inOutbound, searchQuery])
+
+ return {
+ tokens: processedTokens,
+ count: tokens?.length ?? 0,
+ }
+}
diff --git a/src/hooks/useMultiLaneRateLimits.ts b/src/hooks/useMultiLaneRateLimits.ts
new file mode 100644
index 00000000000..2f0274e810f
--- /dev/null
+++ b/src/hooks/useMultiLaneRateLimits.ts
@@ -0,0 +1,78 @@
+import { useState, useEffect } from "react"
+import type { TokenRateLimits, Environment } from "~/lib/ccip/types/index.ts"
+import { realtimeDataService } from "~/lib/ccip/services/realtime-data-instance.ts"
+
+interface LaneConfig {
+ source: string
+ destination: string
+}
+
+interface UseMultiLaneRateLimitsResult {
+ rateLimitsMap: Record>
+ isLoading: boolean
+ error: Error | null
+}
+
+/**
+ * Custom hook to fetch rate limits for multiple lanes
+ * Useful for components that need to display rate limits across multiple lanes
+ * @param lanes - Array of lane configurations with source and destination
+ * @param environment - Network environment (mainnet/testnet)
+ * @returns Map of rate limits keyed by lane (source-destination), loading state, and error state
+ */
+export function useMultiLaneRateLimits(lanes: LaneConfig[], environment: Environment): UseMultiLaneRateLimitsResult {
+ const [rateLimitsMap, setRateLimitsMap] = useState>>({})
+ const [isLoading, setIsLoading] = useState(true)
+ const [error, setError] = useState(null)
+
+ useEffect(() => {
+ let isMounted = true
+
+ const fetchAllRateLimits = async () => {
+ setIsLoading(true)
+ setError(null)
+
+ try {
+ const newRateLimits: Record> = {}
+
+ // Fetch all lanes in parallel
+ const promises = lanes.map(async ({ source, destination }) => {
+ const laneKey = `${source}-${destination}`
+ const response = await realtimeDataService.getLaneSupportedTokens(source, destination, environment)
+
+ if (response?.data) {
+ newRateLimits[laneKey] = response.data
+ }
+ })
+
+ await Promise.all(promises)
+
+ if (isMounted) {
+ setRateLimitsMap(newRateLimits)
+ }
+ } catch (err) {
+ if (isMounted) {
+ console.error("Error fetching multi-lane rate limits:", err)
+ setError(err instanceof Error ? err : new Error("Failed to fetch rate limits"))
+ setRateLimitsMap({})
+ }
+ } finally {
+ if (isMounted) {
+ setIsLoading(false)
+ }
+ }
+ }
+
+ if (lanes.length > 0) {
+ fetchAllRateLimits()
+ } else {
+ setIsLoading(false)
+ }
+
+ return () => {
+ isMounted = false
+ }
+ }, [lanes, environment])
+
+ return { rateLimitsMap, isLoading, error }
+}
diff --git a/src/hooks/useTokenFinality.ts b/src/hooks/useTokenFinality.ts
new file mode 100644
index 00000000000..5036a3848f0
--- /dev/null
+++ b/src/hooks/useTokenFinality.ts
@@ -0,0 +1,66 @@
+import { useState, useEffect } from "react"
+import type { TokenFinalityData, Environment, OutputKeyType } from "~/lib/ccip/types/index.ts"
+import { realtimeDataService } from "~/lib/ccip/services/realtime-data-instance.ts"
+
+interface UseTokenFinalityResult {
+ finalityData: Record
+ isLoading: boolean
+ error: Error | null
+}
+
+/**
+ * Custom hook to fetch token finality data across all chains
+ * @param tokenCanonicalSymbol - Token canonical symbol (e.g., "BETS", "LINK")
+ * @param environment - Network environment (mainnet/testnet)
+ * @param outputKey - Format to use for displaying chain keys (optional)
+ * @returns Finality data for all chains, loading state, and error state
+ */
+export function useTokenFinality(
+ tokenCanonicalSymbol: string,
+ environment: Environment,
+ outputKey?: OutputKeyType
+): UseTokenFinalityResult {
+ const [finalityData, setFinalityData] = useState>({})
+ const [isLoading, setIsLoading] = useState(true)
+ const [error, setError] = useState(null)
+
+ useEffect(() => {
+ let isMounted = true
+
+ const fetchFinalityData = async () => {
+ setIsLoading(true)
+ setError(null)
+
+ try {
+ const result = await realtimeDataService.getTokenFinality(tokenCanonicalSymbol, environment, outputKey)
+
+ if (isMounted) {
+ if (result?.data) {
+ setFinalityData(result.data)
+ } else {
+ console.warn("[useTokenFinality] No data received")
+ setFinalityData({})
+ }
+ }
+ } catch (err) {
+ if (isMounted) {
+ console.error("Failed to fetch token finality data:", err)
+ setError(err instanceof Error ? err : new Error("Failed to fetch token finality"))
+ setFinalityData({})
+ }
+ } finally {
+ if (isMounted) {
+ setIsLoading(false)
+ }
+ }
+ }
+
+ fetchFinalityData()
+
+ return () => {
+ isMounted = false
+ }
+ }, [tokenCanonicalSymbol, environment, outputKey])
+
+ return { finalityData, isLoading, error }
+}
diff --git a/src/hooks/useTokenRateLimits.ts b/src/hooks/useTokenRateLimits.ts
new file mode 100644
index 00000000000..cbfd8ce04df
--- /dev/null
+++ b/src/hooks/useTokenRateLimits.ts
@@ -0,0 +1,65 @@
+import { useState, useEffect } from "react"
+import type { TokenRateLimits, Environment } from "~/lib/ccip/types/index.ts"
+import { realtimeDataService } from "~/lib/ccip/services/realtime-data-instance.ts"
+
+interface UseTokenRateLimitsResult {
+ rateLimits: Record
+ isLoading: boolean
+ error: Error | null
+}
+
+/**
+ * Custom hook to fetch token rate limits for a specific lane
+ * @param source - Source chain internal ID
+ * @param destination - Destination chain internal ID
+ * @param environment - Network environment (mainnet/testnet)
+ * @returns Rate limits data, loading state, and error state
+ */
+export function useTokenRateLimits(
+ source: string,
+ destination: string,
+ environment: Environment
+): UseTokenRateLimitsResult {
+ const [rateLimits, setRateLimits] = useState>({})
+ const [isLoading, setIsLoading] = useState(true)
+ const [error, setError] = useState(null)
+
+ useEffect(() => {
+ let isMounted = true
+
+ const fetchRateLimits = async () => {
+ setIsLoading(true)
+ setError(null)
+
+ try {
+ const response = await realtimeDataService.getLaneSupportedTokens(source, destination, environment)
+
+ if (isMounted) {
+ if (response?.data) {
+ setRateLimits(response.data)
+ } else {
+ setRateLimits({})
+ }
+ }
+ } catch (err) {
+ if (isMounted) {
+ console.error("Error fetching rate limits:", err)
+ setError(err instanceof Error ? err : new Error("Failed to fetch rate limits"))
+ setRateLimits({})
+ }
+ } finally {
+ if (isMounted) {
+ setIsLoading(false)
+ }
+ }
+ }
+
+ fetchRateLimits()
+
+ return () => {
+ isMounted = false
+ }
+ }, [source, destination, environment])
+
+ return { rateLimits, isLoading, error }
+}
diff --git a/src/layouts/BaseLayout.astro b/src/layouts/BaseLayout.astro
index 73f06501528..2a8ae9cfa79 100644
--- a/src/layouts/BaseLayout.astro
+++ b/src/layouts/BaseLayout.astro
@@ -6,6 +6,8 @@ import Header from "~/components/Header/Header.astro"
import { NewsletterCTA } from "~/components/Footer/NewsletterCTA"
import Footer from "~/components/Footer/Footer.astro"
import { Metadata, QuickstartsFrontmatter } from "~/content.config.ts"
+import "@chainlink/blocks/src/theme/globals.css"
+
//
interface Props {
diff --git a/src/layouts/DocsLayout.astro b/src/layouts/DocsLayout.astro
index 29f092bdac0..b877a0763c9 100644
--- a/src/layouts/DocsLayout.astro
+++ b/src/layouts/DocsLayout.astro
@@ -8,9 +8,9 @@ import WhatsNext from "~/components/PageContent/WhatsNext.astro"
import type { MarkdownHeading } from "astro"
import StickyHeader from "~/components/StickyHeader/StickyHeader"
import BaseLayout from "./BaseLayout.astro"
-import DocsNavigation from "~/components/DocsNavigation"
import { VersionSelector } from "~/components/VersionSelector/index.js"
import { detectApiReference } from "@components/VersionSelector/utils/versions"
+import CardsWrapper from "~/components/Cards/CardsWrapper.astro"
import { LanguageSwitcherDropdown } from "~/components/LanguageSwitcherDropdown"
import { ChainTypeSelector } from "~/components/ChainSelector"
import { isChainAwareSection } from "~/config/chainTypes"
@@ -67,7 +67,6 @@ const howToSteps = initialHeadings
>
-
@@ -140,11 +139,6 @@ const howToSteps = initialHeadings
max-width: 1505px;
}
- #grid-left,
- #left-bg {
- background: #fafbfd;
- }
-
#grid-left,
#grid-right {
display: flex;
diff --git a/src/layouts/DocsV3Layout/DocsV3Layout.astro b/src/layouts/DocsV3Layout/DocsV3Layout.astro
new file mode 100644
index 00000000000..05aa3478a5e
--- /dev/null
+++ b/src/layouts/DocsV3Layout/DocsV3Layout.astro
@@ -0,0 +1,149 @@
+---
+import StickyHeader from "~/components/StickyHeader/StickyHeader"
+import BaseLayout from "../BaseLayout.astro"
+import { MarkdownHeading } from "astro"
+import { BaseFrontmatter } from "~/content.config"
+import * as CONFIG from "~/config"
+import LeftSidebar from "~/components/LeftSidebar/LeftSidebar.astro"
+import PageContent from "~/components/PageContent/PageContent.astro"
+
+interface Props {
+ frontmatter: BaseFrontmatter
+ headings?: MarkdownHeading[]
+}
+const { frontmatter, headings } = Astro.props
+
+const titleHeading: MarkdownHeading = {
+ text: frontmatter.title,
+ slug: "overview",
+ depth: 1,
+}
+
+const filteredHeadings = headings?.filter((h) => h.depth < 5)
+const initialHeadings = [titleHeading].concat(filteredHeadings ?? [])
+
+const formattedContentTitle = `${frontmatter.title} | ${CONFIG.SITE.title}`
+
+const currentPage = new URL(Astro.request.url).pathname
+
+const includeLinkToWalletScript = !!Astro.props.frontmatter.metadata?.linkToWallet
+---
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/layouts/DocsV3Layout/README.md b/src/layouts/DocsV3Layout/README.md
new file mode 100644
index 00000000000..6d316fbf9ef
--- /dev/null
+++ b/src/layouts/DocsV3Layout/README.md
@@ -0,0 +1,110 @@
+# DocsV3Layout Component Guide
+
+## What is DocsV3Layout?
+
+DocsV3Layout is the template that creates the standard layout for documentation pages on the Chainlink Docs website. Think of it as a "frame" that wraps around your content to give it a consistent look and feel.
+
+## What Does It Do?
+
+When you use this layout, it automatically creates:
+
+- **A left sidebar** with navigation links to help users find related pages
+- **A main content area** where your documentation content appears
+- **A header** that shows the page outline (on mobile devices)
+- **Responsive design** that adapts to different screen sizes (mobile, tablet, desktop)
+
+## How to Use It
+
+### Basic Setup
+
+To use this layout for a documentation page, you need to specify it at the top of your Markdown file:
+
+```
+---
+layout: ~/layouts/DocsV3Layout/DocsV3Layout.astro
+title: Your Page Title
+section: your-section-name
+---
+
+Your content goes here...
+```
+
+### Required Information
+
+You need to provide two key pieces of information:
+
+1. **Title** - The name of your documentation page
+ - Example: `title: Getting Started with Chainlink`
+
+2. **Section** - Which documentation section this page belongs to
+ - Example: `section: quickstarts`
+ - This helps organize pages in the left sidebar navigation
+
+### Optional Information
+
+You can also include:
+
+- **Metadata** - Special settings for the page, like SEO information
+- **Link to Wallet** - If your page needs blockchain wallet integration, add:
+ ```
+ metadata:
+ linkToWallet: true
+ ```
+
+## Example Usage
+
+Here's a complete example of how to set up a documentation page:
+
+```
+---
+layout: ~/layouts/DocsV3Layout/DocsV3Layout.astro
+title: How to Use Chainlink Data Feeds
+section: data-feeds
+---
+
+# How to Use Chainlink Data Feeds
+
+This guide will teach you how to use data feeds...
+
+## Step 1: Prerequisites
+
+Before you begin, make sure you have...
+
+## Step 2: Installation
+
+To install the required packages...
+```
+
+## What Happens Behind the Scenes
+
+When you use this layout:
+
+1. **Your title** becomes the main heading and appears in the page outline
+2. **Your headings** (anything starting with `#`, `##`, `###`) are automatically collected and used for navigation
+3. **The sidebar** is populated with links based on your section
+4. **The layout adapts** to the user's screen size automatically
+
+## Layout Structure
+
+The page is divided into three columns:
+
+```
+┌──────────────┬─────────────────────┬──────────────┐
+│ │ │ │
+│ Left │ Main Content │ Right │
+│ Sidebar │ (Your Docs) │ Sidebar │
+│ (Navigation) │ │ (Future) │
+│ │ │ │
+└──────────────┴─────────────────────┴──────────────┘
+```
+
+- **Left Sidebar**: Shows navigation for the current section
+- **Main Content**: Your documentation content
+- **Right Sidebar**: Reserved for future use (currently empty)
+
+## Tips for Best Results
+
+1. **Use clear headings** - Your headings create the page outline, so make them descriptive
+2. **Keep titles concise** - The title appears in multiple places, so shorter is better
+3. **Choose the right section** - Make sure your page is in the correct section so users can find it
+4. **Limit heading depth** - Only headings up to level 4 (`####`) are included in the navigation
diff --git a/src/layouts/TutorialLayout.astro b/src/layouts/TutorialLayout.astro
index 6c572bb9647..c968d9cf957 100644
--- a/src/layouts/TutorialLayout.astro
+++ b/src/layouts/TutorialLayout.astro
@@ -7,7 +7,6 @@ import WhatsNext from "~/components/PageContent/WhatsNext.astro"
import type { MarkdownHeading } from "astro"
import StickyHeader from "~/components/StickyHeader/StickyHeader"
import BaseLayout from "./BaseLayout.astro"
-import DocsNavigation from "~/components/DocsNavigation"
import { TutorialProgress } from "~/components/CCIP/TutorialProgress/TutorialProgress"
interface Props {
@@ -32,7 +31,6 @@ const formattedContentTitle = `${frontmatter.title} | ${SITE.title}`
-
diff --git a/src/lib/ccip/services/realtime-data-instance.ts b/src/lib/ccip/services/realtime-data-instance.ts
new file mode 100644
index 00000000000..b1ac8df61bd
--- /dev/null
+++ b/src/lib/ccip/services/realtime-data-instance.ts
@@ -0,0 +1,7 @@
+import { RealtimeDataService } from "./realtime-data.ts"
+
+/**
+ * Singleton instance of RealtimeDataService
+ * Use this shared instance across all components to avoid creating multiple instances
+ */
+export const realtimeDataService = new RealtimeDataService()
diff --git a/src/lib/ccip/services/realtime-data.ts b/src/lib/ccip/services/realtime-data.ts
new file mode 100644
index 00000000000..a0b7a84b470
--- /dev/null
+++ b/src/lib/ccip/services/realtime-data.ts
@@ -0,0 +1,259 @@
+import { Environment } from "~/lib/ccip/types/index.ts"
+import type {
+ TokenRateLimits,
+ RateLimiterEntry,
+ RateLimiterConfig,
+ TokenFinalityData,
+ OutputKeyType,
+} from "~/lib/ccip/types/index.ts"
+
+export const prerender = false
+
+/**
+ * Base URL for CCIP realtime API
+ * For client-side calls, use relative URLs to hit the local API endpoints
+ */
+const getApiBaseUrl = () => {
+ // In browser context, use relative URLs
+ if (typeof window !== "undefined") {
+ return ""
+ }
+ // In server context, use environment variable or default
+ return process.env.CCIP_REALTIME_API_BASE_URL || "https://api.ccip.chainlink.com"
+}
+
+/**
+ * Response structure for lane supported tokens endpoint
+ */
+export interface LaneSupportedTokensResponse {
+ metadata: {
+ environment: Environment
+ timestamp: string
+ requestId: string
+ sourceChain: string
+ destinationChain: string
+ tokenCount: number
+ }
+ data: Record
+}
+
+/**
+ * Response structure for token finality endpoint
+ */
+export interface TokenFinalityResponse {
+ metadata: {
+ environment: Environment
+ timestamp: string
+ requestId: string
+ tokenSymbol: string
+ chainCount: number
+ }
+ data: Record
+}
+
+/**
+ * Service class for handling CCIP realtime data operations
+ * Provides functionality to fetch live data from the CCIP API
+ */
+export class RealtimeDataService {
+ private readonly requestId: string
+
+ /**
+ * Creates a new instance of RealtimeDataService
+ */
+ constructor() {
+ // Generate UUID - handle both browser and server environments
+ if (typeof crypto !== "undefined" && crypto.randomUUID) {
+ this.requestId = crypto.randomUUID()
+ } else {
+ this.requestId = `${Date.now()}-${Math.random().toString(36).substring(2, 11)}`
+ }
+ }
+
+ /**
+ * Fetches supported tokens with rate limits for a specific lane
+ *
+ * @param sourceInternalId - Source chain internal ID
+ * @param destinationInternalId - Destination chain internal ID
+ * @param environment - Network environment (mainnet/testnet)
+ * @returns Supported tokens with rate limits
+ */
+ async getLaneSupportedTokens(
+ sourceInternalId: string,
+ destinationInternalId: string,
+ environment: Environment
+ ): Promise {
+ try {
+ const baseUrl = getApiBaseUrl()
+ const url = `${baseUrl}/api/ccip/v1/lanes/by-internal-id/${sourceInternalId}/${destinationInternalId}/supported-tokens?environment=${environment}`
+
+ const response = await fetch(url)
+
+ if (!response.ok) {
+ return null
+ }
+
+ const data = await response.json()
+ return data
+ } catch (error) {
+ console.error("Error fetching lane supported tokens:", error)
+ return null
+ }
+ }
+
+ /**
+ * Fetches token finality details across all chains
+ *
+ * @param tokenCanonicalSymbol - Token canonical symbol (e.g., "BETS", "LINK")
+ * @param environment - Network environment (mainnet/testnet)
+ * @param outputKey - Format to use for displaying chain keys (optional)
+ * @returns Token finality data for all chains
+ */
+ async getTokenFinality(
+ tokenCanonicalSymbol: string,
+ environment: Environment,
+ outputKey?: OutputKeyType
+ ): Promise {
+ try {
+ const baseUrl = getApiBaseUrl()
+ let url = `${baseUrl}/api/ccip/v1/tokens/${tokenCanonicalSymbol}/finality?environment=${environment}`
+
+ if (outputKey) {
+ url += `&output_key=${outputKey}`
+ }
+
+ const response = await fetch(url)
+
+ if (!response.ok) {
+ console.error("Failed to fetch token finality:", response.status)
+ return null
+ }
+
+ const data = await response.json()
+ return data
+ } catch (error) {
+ console.error("Error fetching token finality:", error)
+ return null
+ }
+ }
+
+ /**
+ * Checks if rate limiter data is unavailable (null)
+ *
+ * @param entry - Rate limiter entry to check
+ * @returns True if unavailable (null)
+ */
+ isRateLimiterUnavailable(entry: RateLimiterEntry): entry is null {
+ return entry === null
+ }
+
+ /**
+ * Checks if rate limiter is enabled
+ *
+ * @param config - Rate limiter configuration
+ * @returns True if enabled
+ */
+ isRateLimiterEnabled(config: RateLimiterConfig): boolean {
+ return config.isEnabled
+ }
+
+ /**
+ * Gets the request ID for this service instance
+ */
+ getRequestId(): string {
+ return this.requestId
+ }
+
+ /**
+ * Extracts FTF (custom) rate limit data for a specific token and direction
+ *
+ * @param tokenRateLimits - Token rate limits containing standard and custom entries
+ * @param direction - Direction ("in" for inbound, "out" for outbound)
+ * @returns FTF rate limiter config or null if unavailable
+ */
+ getFTFRateLimit(tokenRateLimits: TokenRateLimits, direction: "in" | "out"): RateLimiterConfig | null {
+ if (!tokenRateLimits.custom || this.isRateLimiterUnavailable(tokenRateLimits.custom)) {
+ return null
+ }
+
+ const customEntry = tokenRateLimits.custom
+ return customEntry[direction] || null
+ }
+
+ /**
+ * Gets FTF capacity for a specific token and direction
+ *
+ * @param tokenRateLimits - Token rate limits containing standard and custom entries
+ * @param direction - Direction ("in" for inbound, "out" for outbound)
+ * @returns FTF capacity value or null if unavailable
+ */
+ getFTFCapacity(tokenRateLimits: TokenRateLimits, direction: "in" | "out"): string | null {
+ const ftfLimit = this.getFTFRateLimit(tokenRateLimits, direction)
+ return ftfLimit?.capacity || null
+ }
+
+ /**
+ * Gets FTF refill rate for a specific token and direction
+ *
+ * @param tokenRateLimits - Token rate limits containing standard and custom entries
+ * @param direction - Direction ("in" for inbound, "out" for outbound)
+ * @returns FTF refill rate value or null if unavailable
+ */
+ getFTFRefillRate(tokenRateLimits: TokenRateLimits, direction: "in" | "out"): string | null {
+ const ftfLimit = this.getFTFRateLimit(tokenRateLimits, direction)
+ return ftfLimit?.rate || null
+ }
+
+ /**
+ * Checks if FTF rate limiting is enabled for a specific token and direction
+ *
+ * @param tokenRateLimits - Token rate limits containing standard and custom entries
+ * @param direction - Direction ("in" for inbound, "out" for outbound)
+ * @returns True if FTF is enabled, false otherwise
+ */
+ isFTFEnabled(tokenRateLimits: TokenRateLimits, direction: "in" | "out"): boolean {
+ const ftfLimit = this.getFTFRateLimit(tokenRateLimits, direction)
+ return ftfLimit?.isEnabled || false
+ }
+
+ /**
+ * Gets both standard and FTF rate limits for a specific token and direction
+ *
+ * @param tokenRateLimits - Token rate limits containing standard and custom entries (can be null/undefined)
+ * @param direction - Direction ("in" for inbound, "out" for outbound)
+ * @returns Object containing both standard and FTF rate limits
+ */
+ getAllRateLimitsForDirection(
+ tokenRateLimits: TokenRateLimits | null | undefined,
+ direction: "in" | "out"
+ ): {
+ standard: RateLimiterConfig | null
+ ftf: RateLimiterConfig | null
+ } {
+ if (!tokenRateLimits) {
+ return { standard: null, ftf: null }
+ }
+
+ const standardLimit =
+ tokenRateLimits.standard && !this.isRateLimiterUnavailable(tokenRateLimits.standard)
+ ? tokenRateLimits.standard[direction] || null
+ : null
+
+ const ftfLimit = this.getFTFRateLimit(tokenRateLimits, direction)
+
+ return {
+ standard: standardLimit,
+ ftf: ftfLimit,
+ }
+ }
+
+ /**
+ * Checks if a token has FTF rate limiting available
+ *
+ * @param tokenRateLimits - Token rate limits to check
+ * @returns True if FTF data is available (not null/unavailable)
+ */
+ hasFTFRateLimits(tokenRateLimits: TokenRateLimits): boolean {
+ return tokenRateLimits.custom !== null && !this.isRateLimiterUnavailable(tokenRateLimits.custom)
+ }
+}
diff --git a/src/lib/ccip/utils/rate-limit-formatter.ts b/src/lib/ccip/utils/rate-limit-formatter.ts
new file mode 100644
index 00000000000..d7431f39f31
--- /dev/null
+++ b/src/lib/ccip/utils/rate-limit-formatter.ts
@@ -0,0 +1,72 @@
+import type { RateLimiterConfig } from "~/lib/ccip/types/index.ts"
+
+/**
+ * Formats a rate limit value from wei to tokens
+ * @param value - Rate limit value in wei (as string)
+ * @returns Formatted string with proper number formatting
+ */
+export function formatRateLimit(value: string | null | undefined): string {
+ if (!value || value === "0") return "0"
+
+ try {
+ // Convert from wei to tokens (divide by 1e18)
+ const numValue = BigInt(value)
+ const formatted = Number(numValue) / 1e18
+ return formatted.toLocaleString(undefined, { maximumFractionDigits: 2 })
+ } catch (error) {
+ console.error("Error formatting rate limit:", error)
+ return "0"
+ }
+}
+
+/**
+ * Checks if a token is paused based on rate limit configuration
+ * A token is considered paused if the capacity is "0"
+ * @param rateLimit - Rate limiter configuration
+ * @returns True if token is paused
+ */
+export function isTokenPaused(rateLimit: RateLimiterConfig | null | undefined): boolean {
+ return rateLimit?.capacity === "0"
+}
+
+/**
+ * Gets display value for a rate limit
+ * @param rateLimit - Rate limiter configuration
+ * @param isLoading - Whether data is still loading
+ * @returns Display string for the rate limit
+ */
+export function getRateLimitDisplay(rateLimit: RateLimiterConfig | null | undefined, isLoading: boolean): string {
+ if (isLoading) return "Loading..."
+ if (!rateLimit) return "N/A"
+ if (!rateLimit.isEnabled) return "Disabled"
+ return formatRateLimit(rateLimit.capacity)
+}
+
+/**
+ * Gets display value for a rate limit capacity
+ * @param rateLimit - Rate limiter configuration
+ * @param isLoading - Whether data is still loading
+ * @returns Display string for capacity
+ */
+export function getRateLimitCapacityDisplay(
+ rateLimit: RateLimiterConfig | null | undefined,
+ isLoading: boolean
+): string {
+ if (isLoading) return "Loading..."
+ if (!rateLimit) return "Unavailable"
+ if (!rateLimit.isEnabled) return "Disabled"
+ return formatRateLimit(rateLimit.capacity)
+}
+
+/**
+ * Gets display value for a rate limit refill rate
+ * @param rateLimit - Rate limiter configuration
+ * @param isLoading - Whether data is still loading
+ * @returns Display string for refill rate
+ */
+export function getRateLimitRateDisplay(rateLimit: RateLimiterConfig | null | undefined, isLoading: boolean): string {
+ if (isLoading) return "Loading..."
+ if (!rateLimit) return "N/A"
+ if (!rateLimit.isEnabled) return "Disabled"
+ return formatRateLimit(rateLimit.rate)
+}
diff --git a/src/pages/ccip/directory/mainnet/verifiers/index.astro b/src/pages/ccip/directory/mainnet/verifiers/index.astro
new file mode 100644
index 00000000000..07aad33d482
--- /dev/null
+++ b/src/pages/ccip/directory/mainnet/verifiers/index.astro
@@ -0,0 +1,8 @@
+---
+import Verifiers from "~/components/CCIP/Verifiers/Verifiers.astro"
+import { Environment } from "~/config/data/ccip"
+
+export const prerender = true
+---
+
+
diff --git a/src/pages/ccip/directory/testnet/verifiers/index.astro b/src/pages/ccip/directory/testnet/verifiers/index.astro
new file mode 100644
index 00000000000..a6101109fd7
--- /dev/null
+++ b/src/pages/ccip/directory/testnet/verifiers/index.astro
@@ -0,0 +1,8 @@
+---
+import Verifiers from "~/components/CCIP/Verifiers/Verifiers.astro"
+import { Environment } from "~/config/data/ccip"
+
+export const prerender = true
+---
+
+
diff --git a/src/pages/ccip/index.astro b/src/pages/ccip/index.astro
index 816caada5a7..cc8738a8ca7 100644
--- a/src/pages/ccip/index.astro
+++ b/src/pages/ccip/index.astro
@@ -1,6 +1,6 @@
---
-import DocsLayout from "~/layouts/DocsLayout.astro"
import { getEntry, render } from "astro:content"
+import DocsV3Layout from "~/layouts/DocsV3Layout/DocsV3Layout.astro"
const entry = await getEntry("ccip", "index")
if (!entry) {
@@ -11,6 +11,6 @@ if (!entry) {
const { Content, headings } = await render(entry)
---
-
+
-
+
diff --git a/src/pages/certification.astro b/src/pages/certification.astro
new file mode 100644
index 00000000000..2753c60246a
--- /dev/null
+++ b/src/pages/certification.astro
@@ -0,0 +1,933 @@
+---
+import BaseLayout from "~/layouts/BaseLayout.astro"
+import { clsx } from "~/lib/clsx/clsx"
+import { typographyVariants } from "@chainlink/blocks"
+
+const formattedContentTitle = `Courses | Chainlink Certifications`
+---
+
+
+
+
+
+
+
+
+
+
+ Supercharge your career with blockchain developer courses
+
+
+ Get Chainlink certified on Cyfrin, with hands-on learning in Web3, blockchain, tokenization, and smart
+ contracts. Prove your skills and readiness to lead Chainlink-powered projects. Learn to build
+ secure dApps using Chainlink's core services—Data Feeds, VRF, Automation, and CCIP—through a
+ developer-focused certification course.
+
+
Start learning
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ The Learning Environment
+
+
+
+
+
+
+
+
+
+
+ Access free learning resources
+
+
+
+
+
+
+
+
+
+
Chainlink Developer Bootcamps
+
+ Chainlink gives blockchain developers an easy-to-use framework for writing onchain applications.
+ Join a bootcamp to learn how.
+
+
+
+
+
+
+
+
+
+
+
+
DevHub Videos
+
+ Start learning the basics of smart contracts with these step-by-step video tutorials made by
+ expert Chainlink Labs developers.
+
+
+
+
+
+
+
+
+
+
+
+
DevHub Resources
+
+ Understand Chainlink's mission and platform by exploring tutorials, docs, blogs, and more, and
+ learn how Chainlink services underpin the blockchain industry.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/pages/index.astro b/src/pages/index.astro
index 0c08784a072..3ea40693d4d 100644
--- a/src/pages/index.astro
+++ b/src/pages/index.astro
@@ -1,35 +1,77 @@
---
-import ProductTabs from "../features/landing/sections/ProductTabs.astro"
-import LandingLayout from "../layouts/LandingLayout.astro"
-import HeroCTA from "../features/landing/sections/HeroCTA.astro"
+import JourneyCards from "~/components/JourneyCards/JourneyCards.astro"
+import TechnicalStandards from "~/components/TechnicalStandards/TechnicalStandards.astro"
import BaseLayout from "~/layouts/BaseLayout.astro"
import * as CONFIG from "../config"
+import Demos from "~/components/Demos.astro"
+import { Typography } from "@chainlink/blocks"
+import LandingHero from "~/components/LandingHero/LandingHero.astro"
+import TryItOut from "~/components/TryItOut/TryItOut.astro"
+import CommunityEvents from "~/components/CommunityEvents/CommunityEvents.astro"
const formattedContentTitle = `${CONFIG.PAGE.titleFallback} | ${CONFIG.SITE.title}`
---
-
-
-
Chainlink Developer Docs
-
What are you building?
-
-
+
+
+
+
-
-
Recommended reading
-
We think you'd love to explore
-
-
General
-
Link Token Contracts
-
Getting Started with CCIP
-
CCIP Directory
-
Data Feed Addresses
-
SmartData Feed Addresses
-
Getting Started with Data Streams
-
Data Streams Addresses
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Recommended reading
+
We think you'd love to explore
+
@@ -134,6 +176,15 @@ const formattedContentTitle = `${CONFIG.PAGE.titleFallback} | ${CONFIG.SITE.titl
background-color: var(--blue-100);
}
+ .wrapper {
+ display: flex;
+ flex-direction: column;
+ max-width: var(--fullwidth-max-width);
+ padding: 0 var(--space-10x);
+ gap: 36px;
+ }
+
+ /*800px*/
@media (min-width: 50em) {
.hero {
max-width: var(--fullwidth-max-width);
@@ -159,11 +210,6 @@ const formattedContentTitle = `${CONFIG.PAGE.titleFallback} | ${CONFIG.SITE.titl
font-weight: 600;
}
- .recommended {
- margin: var(--space-16x) auto;
- max-width: var(--fullwidth-max-width);
- }
-
.heroContainer {
background: linear-gradient(180deg, #f1f5fe 0%, white 100%);
}
@@ -178,8 +224,14 @@ const formattedContentTitle = `${CONFIG.PAGE.titleFallback} | ${CONFIG.SITE.titl
line-height: var(--space-6x);
margin-bottom: var(--space-2x);
}
+
+ .wrapper {
+ gap: 82px;
+ }
}
- @media (min-width: 72em) {
+
+ /* 992px */
+ @media (min-width: 62em) {
.hero {
max-width: min(1200px, calc(100% - 2 * var(--space-16x)));
padding: 0;
@@ -189,5 +241,10 @@ const formattedContentTitle = `${CONFIG.PAGE.titleFallback} | ${CONFIG.SITE.titl
max-width: min(1200px, calc(100% - 2 * var(--space-16x)));
padding: 0;
}
+
+ .wrapper {
+ margin: 0 auto;
+ margin-top: 60px;
+ }
}
diff --git a/src/stores/tryItOutStore.ts b/src/stores/tryItOutStore.ts
new file mode 100644
index 00000000000..fe13f6662e9
--- /dev/null
+++ b/src/stores/tryItOutStore.ts
@@ -0,0 +1,3 @@
+import { atom } from "nanostores"
+
+export const activeAccordionIndex = atom(0)
diff --git a/src/styles/index.css b/src/styles/index.css
index 8593eab6ab5..805359ae635 100644
--- a/src/styles/index.css
+++ b/src/styles/index.css
@@ -1,6 +1,6 @@
-/*
+/*
* Global styles and CSS variables
- *
+ *
* This file contains:
* 1. CSS reset and base styles
* 2. Global CSS variables for theming
@@ -24,6 +24,9 @@
--user-font-scale: 1rem - 16px;
--max-width: calc(100%);
--fullwidth-max-width: calc(100% - 1rem);
+
+ /* Page background and border colors */
+ --Page-Background-Alt: #fafbfc;
}
/* Fonts provided via centralized design system/CDN; no local @font-face overrides here. */
diff --git a/src/styles/theme.css b/src/styles/theme.css
index 2f394ceb5d0..a922dafcf53 100644
--- a/src/styles/theme.css
+++ b/src/styles/theme.css
@@ -44,6 +44,10 @@
--color-gray-90: var(--color-base-gray), 90%;
--color-gray-95: var(--color-base-gray), 95%;
+ /* Tertiary color aliases (matches design system) */
+ --tertiary-border: #d1d6de;
+ --tertiary-foreground: #0e1119;
+
--color-blue: var(--color-base-blue), 61%;
--color-blue-dark: var(--color-base-blue-dark), 39%;
--color-green: var(--color-base-green), 42%;
diff --git a/src/workers/data-worker.ts b/src/workers/data-worker.ts
index ac75689d4ba..db3cf94b45f 100644
--- a/src/workers/data-worker.ts
+++ b/src/workers/data-worker.ts
@@ -33,6 +33,13 @@ interface SearchData {
}
lane: LaneConfig
}>
+ verifiers: Array<{
+ id: string
+ name: string
+ type: string
+ logo: string
+ totalNetworks: number
+ }>
}
interface WorkerMessage {
@@ -44,6 +51,7 @@ interface WorkerResponse {
networks: SearchData["chains"]
tokens: SearchData["tokens"]
lanes: SearchData["lanes"]
+ verifiers: SearchData["verifiers"]
}
self.onmessage = (event: MessageEvent
) => {
@@ -51,7 +59,7 @@ self.onmessage = (event: MessageEvent) => {
const { search, data } = event.data
if (!search || !data) {
- self.postMessage({ networks: [], tokens: [], lanes: [] } as WorkerResponse)
+ self.postMessage({ networks: [], tokens: [], lanes: [], verifiers: [] } as WorkerResponse)
return
}
@@ -74,7 +82,15 @@ self.onmessage = (event: MessageEvent) => {
return matchesNetwork && hasTokens
})
- self.postMessage({ networks, tokens, lanes } as WorkerResponse)
+ // Filter verifiers
+ const verifiers = data.verifiers.filter(
+ (verifier) =>
+ verifier.name.toLowerCase().includes(searchLower) ||
+ verifier.id.toLowerCase().includes(searchLower) ||
+ verifier.type.toLowerCase().includes(searchLower)
+ )
+
+ self.postMessage({ networks, tokens, lanes, verifiers } as WorkerResponse)
}
// Export types for use in main thread
diff --git a/tailwind.config.js b/tailwind.config.js
new file mode 100644
index 00000000000..3dc5b2f5d48
--- /dev/null
+++ b/tailwind.config.js
@@ -0,0 +1,4 @@
+import baseConfig from "@chainlink/blocks/src/theme/base"
+/** @type {import('tailwindcss').Config} */
+
+export default baseConfig
diff --git a/tsconfig.json b/tsconfig.json
index b5df96aeb68..b718b196200 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -4,6 +4,7 @@
"target": "ESNext",
"module": "NodeNext",
"moduleResolution": "nodenext",
+ "allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"esModuleInterop": true,