From b14581616d6e1a0bcfecf1bc3d0e478f43c735e2 Mon Sep 17 00:00:00 2001 From: Carlo Sala Date: Mon, 19 Aug 2024 20:01:45 +0200 Subject: [PATCH 1/7] delegate wip --- src/App.tsx | 3 ++- src/actions/delegate/DelegateAction.tsx | 27 +++++++++++++++++++++++++ src/actions/delegate/delegate.ts | 20 ++++++++++++++++++ src/actions/delegate/index.tsx | 10 +++++++++ src/actions/index.ts | 2 +- 5 files changed, 60 insertions(+), 2 deletions(-) create mode 100644 src/actions/delegate/DelegateAction.tsx create mode 100644 src/actions/delegate/delegate.ts create mode 100644 src/actions/delegate/index.tsx diff --git a/src/App.tsx b/src/App.tsx index 3b29071..bfa4c22 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,6 +1,6 @@ import { Suspense } from "react" import { Route, Routes } from "react-router-dom" -import { Send, Void } from "./actions" +import { Delegate, Send, Void } from "./actions" import { Header } from "./Header" function App() { @@ -11,6 +11,7 @@ function App() { } /> } /> + } /> diff --git a/src/actions/delegate/DelegateAction.tsx b/src/actions/delegate/DelegateAction.tsx new file mode 100644 index 0000000..f7e952f --- /dev/null +++ b/src/actions/delegate/DelegateAction.tsx @@ -0,0 +1,27 @@ +import { useStateObservable } from "@react-rxjs/core" +import { chain$, delegateAccount$ } from "./delegate" + +chain$.subscribe() +delegateAccount$.subscribe() + +export const DelegateAction = () => { + console.log("delegating") + const chainData = useStateObservable(chain$) + const delegateAccount = useStateObservable(delegateAccount$) + + return ( +
+

Delegate

+
+

H2 INFO

+
+ Chain:
{chainData ?? "NOT DEFINED"}
+
+
+ Delegate Account: +
{delegateAccount ?? "NOT DEFINED"}
+
+
+
+ ) +} diff --git a/src/actions/delegate/delegate.ts b/src/actions/delegate/delegate.ts new file mode 100644 index 0000000..7eaaf0e --- /dev/null +++ b/src/actions/delegate/delegate.ts @@ -0,0 +1,20 @@ +import { routeMatch$ } from "@/router" +import { map } from "rxjs" +import { state } from "@react-rxjs/core" + +const PATTERN_CHAIN = "/delegate/:chain/*" +const PATTERN_ACCOUNT = "/delegate/:chain/:account/*" + +export const chain$ = state( + routeMatch$(PATTERN_CHAIN).pipe( + map((routeData) => routeData?.params?.chain ?? null), + ), + null, +) + +export const delegateAccount$ = state( + routeMatch$(PATTERN_ACCOUNT).pipe( + map((routeData) => routeData?.params?.account ?? null), + ), + null, +) diff --git a/src/actions/delegate/index.tsx b/src/actions/delegate/index.tsx new file mode 100644 index 0000000..736a820 --- /dev/null +++ b/src/actions/delegate/index.tsx @@ -0,0 +1,10 @@ +import { Route, Routes } from "react-router-dom" +import { DelegateAction } from "./DelegateAction" + +export default function Delegate() { + return ( + + } /> + + ) +} diff --git a/src/actions/index.ts b/src/actions/index.ts index a6de3c4..e1fe160 100644 --- a/src/actions/index.ts +++ b/src/actions/index.ts @@ -2,4 +2,4 @@ import { lazy } from "react" export const Void = lazy(() => import("./void")) export const Send = lazy(() => import("./send")) -// export const Delegate = lazy(() => import("./delegate")); +export const Delegate = lazy(() => import("./delegate")) From 8556fdebc55f5cc3fbe91b991208b53f950f3ba4 Mon Sep 17 00:00:00 2001 From: Josep M Sobrepere Date: Tue, 20 Aug 2024 16:47:36 +0200 Subject: [PATCH 2/7] WiP --- components.json | 17 + package.json | 11 +- pnpm-lock.yaml | 1685 ++++++++++++++++++++++- src/actions/delegate/DelegateAction.tsx | 155 ++- src/actions/delegate/delegate.ts | 4 +- src/api/delegation.ts | 23 +- src/components/multi-select.tsx | 383 ++++++ src/components/ui/badge.tsx | 36 + src/components/ui/button.tsx | 56 + src/components/ui/command.tsx | 153 ++ src/components/ui/dialog.tsx | 120 ++ src/components/ui/popover.tsx | 29 + src/components/ui/separator.tsx | 29 + src/index.css | 66 + src/lib/utils.ts | 6 + tailwind.config.js | 74 +- 16 files changed, 2788 insertions(+), 59 deletions(-) create mode 100644 components.json create mode 100644 src/components/multi-select.tsx create mode 100644 src/components/ui/badge.tsx create mode 100644 src/components/ui/button.tsx create mode 100644 src/components/ui/command.tsx create mode 100644 src/components/ui/dialog.tsx create mode 100644 src/components/ui/popover.tsx create mode 100644 src/components/ui/separator.tsx create mode 100644 src/lib/utils.ts diff --git a/components.json b/components.json new file mode 100644 index 0000000..08837cd --- /dev/null +++ b/components.json @@ -0,0 +1,17 @@ +{ + "$schema": "https://ui.shadcn.com/schema.json", + "style": "default", + "rsc": false, + "tsx": true, + "tailwind": { + "config": "tailwind.config.js", + "css": "app/globals.css", + "baseColor": "slate", + "cssVariables": true, + "prefix": "" + }, + "aliases": { + "components": "@/components", + "utils": "@/lib/utils" + } +} diff --git a/package.json b/package.json index 6e7273c..e511131 100644 --- a/package.json +++ b/package.json @@ -12,17 +12,26 @@ }, "dependencies": { "@polkadot-api/descriptors": "file:.papi/descriptors", + "@radix-ui/react-dialog": "^1.1.1", + "@radix-ui/react-popover": "^1.1.1", + "@radix-ui/react-separator": "^1.1.0", + "@radix-ui/react-slot": "^1.1.0", "@react-rxjs/core": "^0.10.7", "@react-rxjs/utils": "^0.9.7", "@remix-run/router": "^1.19.1", + "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", + "cmdk": "1.0.0", + "lucide-react": "^0.428.0", "polkadot-api": "^1.0.1", "react": "^18.3.1", "react-dom": "^18.3.1", "react-portal": "^4.2.2", "react-router-dom": "^6.26.1", "rxjs": "^7.8.1", - "tailwind-merge": "^2.5.2" + "shadcn-ui": "^0.8.0", + "tailwind-merge": "^2.5.2", + "tailwindcss-animate": "^1.0.7" }, "devDependencies": { "@eslint/js": "^9.9.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 37ef995..c9197c5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -11,6 +11,18 @@ importers: '@polkadot-api/descriptors': specifier: file:.papi/descriptors version: file:.papi/descriptors(polkadot-api@1.0.1(jiti@1.21.6)(postcss@8.4.41)(rxjs@7.8.1)(smoldot@2.0.30)(yaml@2.5.0)) + '@radix-ui/react-dialog': + specifier: ^1.1.1 + version: 1.1.1(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-popover': + specifier: ^1.1.1 + version: 1.1.1(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-separator': + specifier: ^1.1.0 + version: 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': + specifier: ^1.1.0 + version: 1.1.0(@types/react@18.3.3)(react@18.3.1) '@react-rxjs/core': specifier: ^0.10.7 version: 0.10.7(react@18.3.1)(rxjs@7.8.1) @@ -20,9 +32,18 @@ importers: '@remix-run/router': specifier: ^1.19.1 version: 1.19.1 + class-variance-authority: + specifier: ^0.7.0 + version: 0.7.0 clsx: specifier: ^2.1.1 version: 2.1.1 + cmdk: + specifier: 1.0.0 + version: 1.0.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + lucide-react: + specifier: ^0.428.0 + version: 0.428.0(react@18.3.1) polkadot-api: specifier: ^1.0.1 version: 1.0.1(jiti@1.21.6)(postcss@8.4.41)(rxjs@7.8.1)(smoldot@2.0.30)(yaml@2.5.0) @@ -41,9 +62,15 @@ importers: rxjs: specifier: ^7.8.1 version: 7.8.1 + shadcn-ui: + specifier: ^0.8.0 + version: 0.8.0(typescript@5.5.4) tailwind-merge: specifier: ^2.5.2 version: 2.5.2 + tailwindcss-animate: + specifier: ^1.0.7 + version: 1.0.7(tailwindcss@3.4.10) devDependencies: '@eslint/js': specifier: ^9.9.0 @@ -104,6 +131,10 @@ packages: resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} + '@antfu/ni@0.21.12': + resolution: {integrity: sha512-2aDL3WUv8hMJb2L3r/PIQWsTLyq7RQr3v9xD16fiz6O8ys1xEyLhhTOv8gxtZvJiTzjTF5pHoArvRdesGL1DMQ==} + hasBin: true + '@babel/code-frame@7.24.7': resolution: {integrity: sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==} engines: {node: '>=6.9.0'} @@ -120,10 +151,24 @@ packages: resolution: {integrity: sha512-3LEEcj3PVW8pW2R1SR1M89g/qrYk/m/mB/tLqn7dn4sbBUQyTqnlod+II2U4dqiGtUmkcnAmkMDralTFZttRiw==} engines: {node: '>=6.9.0'} + '@babel/helper-annotate-as-pure@7.24.7': + resolution: {integrity: sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==} + engines: {node: '>=6.9.0'} + '@babel/helper-compilation-targets@7.25.2': resolution: {integrity: sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==} engines: {node: '>=6.9.0'} + '@babel/helper-create-class-features-plugin@7.25.0': + resolution: {integrity: sha512-GYM6BxeQsETc9mnct+nIIpf63SAyzvyYN7UB/IlTyd+MBg06afFGp0mIeUqGyWgS2mxad6vqbMrHVlaL3m70sQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-member-expression-to-functions@7.24.8': + resolution: {integrity: sha512-LABppdt+Lp/RlBxqrh4qgf1oEH/WxdzQNDJIu5gC/W1GyvPVrOBiItmmM8wan2fm4oYqFuFfkXmlGpLQhPY8CA==} + engines: {node: '>=6.9.0'} + '@babel/helper-module-imports@7.24.7': resolution: {integrity: sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==} engines: {node: '>=6.9.0'} @@ -134,14 +179,28 @@ packages: peerDependencies: '@babel/core': ^7.0.0 + '@babel/helper-optimise-call-expression@7.24.7': + resolution: {integrity: sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==} + engines: {node: '>=6.9.0'} + '@babel/helper-plugin-utils@7.24.8': resolution: {integrity: sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==} engines: {node: '>=6.9.0'} + '@babel/helper-replace-supers@7.25.0': + resolution: {integrity: sha512-q688zIvQVYtZu+i2PsdIu/uWGRpfxzr5WESsfpShfZECkO+d2o+WROWezCi/Q6kJ0tfPa5+pUGUlfx2HhrA3Bg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + '@babel/helper-simple-access@7.24.7': resolution: {integrity: sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==} engines: {node: '>=6.9.0'} + '@babel/helper-skip-transparent-expression-wrappers@7.24.7': + resolution: {integrity: sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==} + engines: {node: '>=6.9.0'} + '@babel/helper-string-parser@7.24.8': resolution: {integrity: sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==} engines: {node: '>=6.9.0'} @@ -167,6 +226,12 @@ packages: engines: {node: '>=6.0.0'} hasBin: true + '@babel/plugin-syntax-typescript@7.24.7': + resolution: {integrity: sha512-c/+fVeJBB0FeKsFvwytYiUD+LBvhHjGSI0g446PRGdSVGZLRNArBUno2PETbAly3tpiNAQR5XaZ+JslxkotsbA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-react-jsx-self@7.24.7': resolution: {integrity: sha512-fOPQYbGSgH0HUp4UJO4sMBFjY6DuWq+2i8rixyUMb3CdGixs/gccURvYOAhajBdKDoGajFr3mUq5rH3phtkGzw==} engines: {node: '>=6.9.0'} @@ -179,6 +244,16 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/plugin-transform-typescript@7.25.2': + resolution: {integrity: sha512-lBwRvjSmqiMYe/pS0+1gggjJleUJi7NzjvQ1Fkqtt69hBa/0t1YuW/MLQMAPixfwaQOHUXsd6jeU3Z+vdGv3+A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/runtime@7.25.0': + resolution: {integrity: sha512-7dRy4DwXwtzBrPbZflqxnvfxLF8kdZXPkhymtDeFoFqE6ldzjQFgYTtYIFARcLEYDrqfBfYcZt1WqFxRoyC9Rw==} + engines: {node: '>=6.9.0'} + '@babel/template@7.25.0': resolution: {integrity: sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==} engines: {node: '>=6.9.0'} @@ -504,6 +579,21 @@ packages: resolution: {integrity: sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@floating-ui/core@1.6.7': + resolution: {integrity: sha512-yDzVT/Lm101nQ5TCVeK65LtdN7Tj4Qpr9RTXJ2vPFLqtLxwOrpoxAHAJI8J3yYWUc40J0BDBheaitK5SJmno2g==} + + '@floating-ui/dom@1.6.10': + resolution: {integrity: sha512-fskgCFv8J8OamCmyun8MfjB1Olfn+uZKjOKZ0vhYF3gRmEUXcGOjxWL8bBr7i4kIuPZ2KD2S3EUIOxnjC8kl2A==} + + '@floating-ui/react-dom@2.1.1': + resolution: {integrity: sha512-4h84MJt3CHrtG18mGsXuLCHMrug49d7DFkU0RMIyshRveBeyV2hmV/pDaF2Uxtu8kgq5r46llp5E5FQiR0K2Yg==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + + '@floating-ui/utils@0.2.7': + resolution: {integrity: sha512-X8R8Oj771YRl/w+c1HqAC1szL8zWQRwFvgDwT129k9ACdBoud/+/rX9V0qiMl6LWUdP9voC2nDVZYPMQQsb6eA==} + '@humanwhocodes/module-importer@1.0.1': resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} engines: {node: '>=12.22'} @@ -628,6 +718,403 @@ packages: '@polkadot-api/ws-provider@0.2.0': resolution: {integrity: sha512-R4B+tUR1H9j6AH2p4Dvv5+aV4/DC/TpKOqB1C5ON2Qvlc0TrH7x4HrZLn82Kq7iwUtnxkrU6esze2UgDGoVKPw==} + '@radix-ui/primitive@1.0.1': + resolution: {integrity: sha512-yQ8oGX2GVsEYMWGxcovu1uGWPCxV5BFfeeYxqPmuAzUyLT9qmaMXSAhXpb0WrspIeqYzdJpkh2vHModJPgRIaw==} + + '@radix-ui/primitive@1.1.0': + resolution: {integrity: sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==} + + '@radix-ui/react-arrow@1.1.0': + resolution: {integrity: sha512-FmlW1rCg7hBpEBwFbjHwCW6AmWLQM6g/v0Sn8XbP9NvmSZ2San1FpQeyPtufzOMSIx7Y4dzjlHoifhp+7NkZhw==} + 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 + + '@radix-ui/react-compose-refs@1.0.1': + resolution: {integrity: sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-compose-refs@1.1.0': + resolution: {integrity: sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-context@1.0.1': + resolution: {integrity: sha512-ebbrdFoYTcuZ0v4wG5tedGnp9tzcV8awzsxYph7gXUyvnNLuTIcCk1q17JEbnVhXAKG9oX3KtchwiMIAYp9NLg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-context@1.1.0': + resolution: {integrity: sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-dialog@1.0.5': + resolution: {integrity: sha512-GjWJX/AUpB703eEBanuBnIWdIXg6NvJFCXcNlSZk4xdszCdhrJgBoUd1cGk67vFO+WdA2pfI/plOpqz/5GUP6Q==} + 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 + + '@radix-ui/react-dialog@1.1.1': + resolution: {integrity: sha512-zysS+iU4YP3STKNS6USvFVqI4qqx8EpiwmT5TuCApVEBca+eRCbONi4EgzfNSuVnOXvC5UPHHMjs8RXO6DH9Bg==} + 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 + + '@radix-ui/react-dismissable-layer@1.0.5': + resolution: {integrity: sha512-aJeDjQhywg9LBu2t/At58hCvr7pEm0o2Ke1x33B+MhjNmmZ17sy4KImo0KPLgsnc/zN7GPdce8Cnn0SWvwZO7g==} + 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 + + '@radix-ui/react-dismissable-layer@1.1.0': + resolution: {integrity: sha512-/UovfmmXGptwGcBQawLzvn2jOfM0t4z3/uKffoBlj724+n3FvBbZ7M0aaBOmkp6pqFYpO4yx8tSVJjx3Fl2jig==} + 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 + + '@radix-ui/react-focus-guards@1.0.1': + resolution: {integrity: sha512-Rect2dWbQ8waGzhMavsIbmSVCgYxkXLxxR3ZvCX79JOglzdEy4JXMb98lq4hPxUbLr77nP0UOGf4rcMU+s1pUA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-focus-guards@1.1.0': + resolution: {integrity: sha512-w6XZNUPVv6xCpZUqb/yN9DL6auvpGX3C/ee6Hdi16v2UUy25HV2Q5bcflsiDyT/g5RwbPQ/GIT1vLkeRb+ITBw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-focus-scope@1.0.4': + resolution: {integrity: sha512-sL04Mgvf+FmyvZeYfNu1EPAaaxD+aw7cYeIB9L9Fvq8+urhltTRaEo5ysKOpHuKPclsZcSUMKlN05x4u+CINpA==} + 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 + + '@radix-ui/react-focus-scope@1.1.0': + resolution: {integrity: sha512-200UD8zylvEyL8Bx+z76RJnASR2gRMuxlgFCPAe/Q/679a/r0eK3MBVYMb7vZODZcffZBdob1EGnky78xmVvcA==} + 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 + + '@radix-ui/react-id@1.0.1': + resolution: {integrity: sha512-tI7sT/kqYp8p96yGWY1OAnLHrqDgzHefRBKQ2YAkBS5ja7QLcZ9Z/uY7bEjPUatf8RomoXM8/1sMj1IJaE5UzQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-id@1.1.0': + resolution: {integrity: sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-popover@1.1.1': + resolution: {integrity: sha512-3y1A3isulwnWhvTTwmIreiB8CF4L+qRjZnK1wYLO7pplddzXKby/GnZ2M7OZY3qgnl6p9AodUIHRYGXNah8Y7g==} + 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 + + '@radix-ui/react-popper@1.2.0': + resolution: {integrity: sha512-ZnRMshKF43aBxVWPWvbj21+7TQCvhuULWJ4gNIKYpRlQt5xGRhLx66tMp8pya2UkGHTSlhpXwmjqltDYHhw7Vg==} + 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 + + '@radix-ui/react-portal@1.0.4': + resolution: {integrity: sha512-Qki+C/EuGUVCQTOTD5vzJzJuMUlewbzuKyUy+/iHM2uwGiru9gZeBJtHAPKAEkB5KWGi9mP/CHKcY0wt1aW45Q==} + 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 + + '@radix-ui/react-portal@1.1.1': + resolution: {integrity: sha512-A3UtLk85UtqhzFqtoC8Q0KvR2GbXF3mtPgACSazajqq6A41mEQgo53iPzY4i6BwDxlIFqWIhiQ2G729n+2aw/g==} + 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 + + '@radix-ui/react-presence@1.0.1': + resolution: {integrity: sha512-UXLW4UAbIY5ZjcvzjfRFo5gxva8QirC9hF7wRE4U5gz+TP0DbRk+//qyuAQ1McDxBt1xNMBTaciFGvEmJvAZCg==} + 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 + + '@radix-ui/react-presence@1.1.0': + resolution: {integrity: sha512-Gq6wuRN/asf9H/E/VzdKoUtT8GC9PQc9z40/vEr0VCJ4u5XvvhWIrSsCB6vD2/cH7ugTdSfYq9fLJCcM00acrQ==} + 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 + + '@radix-ui/react-primitive@1.0.3': + resolution: {integrity: sha512-yi58uVyoAcK/Nq1inRY56ZSjKypBNKTa/1mcL8qdl6oJeEaDbOldlzrGn7P6Q3Id5d+SYNGc5AJgc4vGhjs5+g==} + 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 + + '@radix-ui/react-primitive@2.0.0': + resolution: {integrity: sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw==} + 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 + + '@radix-ui/react-separator@1.1.0': + resolution: {integrity: sha512-3uBAs+egzvJBDZAzvb/n4NxxOYpnspmWxO2u5NbZ8Y6FM/NdrGSF9bop3Cf6F6C71z1rTSn8KV0Fo2ZVd79lGA==} + 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 + + '@radix-ui/react-slot@1.0.2': + resolution: {integrity: sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-slot@1.1.0': + resolution: {integrity: sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-callback-ref@1.0.1': + resolution: {integrity: sha512-D94LjX4Sp0xJFVaoQOd3OO9k7tpBYNOXdVhkltUbGv2Qb9OXdrg/CpsjlZv7ia14Sylv398LswWBVVu5nqKzAQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-callback-ref@1.1.0': + resolution: {integrity: sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-controllable-state@1.0.1': + resolution: {integrity: sha512-Svl5GY5FQeN758fWKrjM6Qb7asvXeiZltlT4U2gVfl8Gx5UAv2sMR0LWo8yhsIZh2oQ0eFdZ59aoOOMV7b47VA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-controllable-state@1.1.0': + resolution: {integrity: sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-escape-keydown@1.0.3': + resolution: {integrity: sha512-vyL82j40hcFicA+M4Ex7hVkB9vHgSse1ZWomAqV2Je3RleKGO5iM8KMOEtfoSB0PnIelMd2lATjTGMYqN5ylTg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-escape-keydown@1.1.0': + resolution: {integrity: sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-layout-effect@1.0.1': + resolution: {integrity: sha512-v/5RegiJWYdoCvMnITBkNNx6bCj20fiaJnWtRkU18yITptraXjffz5Qbn05uOiQnOvi+dbkznkoaMltz1GnszQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-layout-effect@1.1.0': + resolution: {integrity: sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-rect@1.1.0': + resolution: {integrity: sha512-0Fmkebhr6PiseyZlYAOtLS+nb7jLmpqTrJyv61Pe68MKYW6OWdRE2kI70TaYY27u7H0lajqM3hSMMLFq18Z7nQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-size@1.1.0': + resolution: {integrity: sha512-XW3/vWuIXHa+2Uwcc2ABSfcCledmXhhQPlGbfcRXbiUQI5Icjcg19BGCZVKKInYbvUCut/ufbbLLPFC5cbb1hw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/rect@1.1.0': + resolution: {integrity: sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg==} + '@react-rxjs/core@0.10.7': resolution: {integrity: sha512-dornp8pUs9OcdqFKKRh9+I2FVe21gWufNun6RYU1ddts7kUy9i4Thvl0iqcPFbGY61cJQMAJF7dxixWMSD/A/A==} peerDependencies: @@ -740,6 +1227,9 @@ packages: resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} engines: {node: '>=18'} + '@ts-morph/common@0.19.0': + resolution: {integrity: sha512-Unz/WHmd4pGax91rdIKWi51wnVUW11QttMEPpBiBgIewnc9UQIX7UDLxr5vRlqeByXCwhkF6VabSsI0raWcyAQ==} + '@types/babel__core@7.20.5': resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} @@ -846,6 +1336,10 @@ packages: engines: {node: '>=0.4.0'} hasBin: true + agent-base@7.1.1: + resolution: {integrity: sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==} + engines: {node: '>= 14'} + ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} @@ -882,10 +1376,18 @@ packages: argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + aria-hidden@1.2.4: + resolution: {integrity: sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==} + engines: {node: '>=10'} + array-union@2.1.0: resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} engines: {node: '>=8'} + ast-types@0.16.1: + resolution: {integrity: sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==} + engines: {node: '>=4'} + autoprefixer@10.4.20: resolution: {integrity: sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==} engines: {node: ^10 || ^12 || >=14} @@ -896,10 +1398,16 @@ packages: balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + binary-extensions@2.3.0: resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} + bl@5.1.0: + resolution: {integrity: sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==} + brace-expansion@1.1.11: resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} @@ -915,6 +1423,9 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true + buffer@6.0.3: + resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + bundle-require@5.0.0: resolution: {integrity: sha512-GuziW3fSSmopcx4KRymQEJVbZUfqlCqcq7dvs6TYwKRZiegK/2buMxQTPs6MGlNv50wms1699qYO54R8XfRX4w==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -944,6 +1455,10 @@ packages: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} + chalk@5.2.0: + resolution: {integrity: sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + chalk@5.3.0: resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} @@ -952,6 +1467,9 @@ packages: resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} + class-variance-authority@0.7.0: + resolution: {integrity: sha512-jFI8IQw4hczaL4ALINxqLEXQbWcNjoSkloa4IaufXCJr6QawJyw7tuRysRsrE8w2p/4gGaxKIt/hX3qz/IbD1A==} + cli-cursor@4.0.0: resolution: {integrity: sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -960,10 +1478,27 @@ packages: resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} engines: {node: '>=6'} + clone@1.0.4: + resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} + engines: {node: '>=0.8'} + + clsx@2.0.0: + resolution: {integrity: sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==} + engines: {node: '>=6'} + clsx@2.1.1: resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} engines: {node: '>=6'} + cmdk@1.0.0: + resolution: {integrity: sha512-gDzVf0a09TvoJ5jnuPvygTB77+XdOSwEmJ88L6XPFPlv7T3RxbP9jgenfylrAMD0+Le1aO0nVjQUzl2g+vjz5Q==} + peerDependencies: + react: ^18.0.0 + react-dom: ^18.0.0 + + code-block-writer@12.0.0: + resolution: {integrity: sha512-q4dMFMlXtKR3XNBHyMHt/3pwYNA69EDk00lloMOaaUMKPUXBw6lpXtbu3MMVG6/uOihGnRDOlkyqsONEUj60+w==} + color-convert@1.9.3: resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} @@ -977,6 +1512,10 @@ packages: color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + commander@10.0.1: + resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==} + engines: {node: '>=14'} + commander@12.1.0: resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} engines: {node: '>=18'} @@ -995,6 +1534,15 @@ packages: convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + cosmiconfig@8.3.6: + resolution: {integrity: sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==} + engines: {node: '>=14'} + peerDependencies: + typescript: '>=4.9.5' + peerDependenciesMeta: + typescript: + optional: true + cross-spawn@7.0.3: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} engines: {node: '>= 8'} @@ -1007,6 +1555,10 @@ packages: csstype@3.1.3: resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + data-uri-to-buffer@4.0.1: + resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} + engines: {node: '>= 12'} + debug@4.3.6: resolution: {integrity: sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==} engines: {node: '>=6.0'} @@ -1023,13 +1575,23 @@ packages: resolution: {integrity: sha512-q6bNsfNBtgr8ZOQqmZbl94MmYWm+QcDNIkqCxVWiw1vKvf+y/N2dZQKdnDXn4c5Ygt/y63tDof6OCN+2YwWVEg==} engines: {node: '>=16.0.0'} + defaults@1.0.4: + resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} + detect-indent@7.0.1: resolution: {integrity: sha512-Mc7QhQ8s+cLrnUfU/Ji94vG/r8M26m8f++vyres4ZoojaRDpZ1eSIh/EpzLNwlWuvzSZ3UbDFspjFvTDXe6e/g==} engines: {node: '>=12.20'} + detect-node-es@1.1.0: + resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} + didyoumean@1.2.2: resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} + diff@5.2.0: + resolution: {integrity: sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==} + engines: {node: '>=0.3.1'} + dir-glob@3.0.1: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} engines: {node: '>=8'} @@ -1052,6 +1614,9 @@ packages: emoji-regex@9.2.2: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + error-ex@1.3.2: + resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + esbuild@0.21.5: resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} engines: {node: '>=12'} @@ -1111,6 +1676,11 @@ packages: resolution: {integrity: sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + esquery@1.6.0: resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} engines: {node: '>=0.10'} @@ -1131,6 +1701,10 @@ packages: resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} engines: {node: '>=10'} + execa@7.2.0: + resolution: {integrity: sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==} + engines: {node: ^14.18.0 || ^16.14.0 || >=18.0.0} + execa@9.3.1: resolution: {integrity: sha512-gdhefCCNy/8tpH/2+ajP9IQc14vXchNdd0weyzSJEFURhRMGncQ+zKFxwjAufIewPEJm9BPOaJnvg2UtlH2gPQ==} engines: {node: ^18.19.0 || >=20.5.0} @@ -1151,6 +1725,10 @@ packages: fastq@1.17.1: resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} + fetch-blob@3.2.0: + resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} + engines: {node: ^12.20 || >= 14.13} + figures@6.1.0: resolution: {integrity: sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==} engines: {node: '>=18'} @@ -1178,9 +1756,17 @@ packages: resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} engines: {node: '>=14'} + formdata-polyfill@4.0.10: + resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} + engines: {node: '>=12.20.0'} + fraction.js@4.3.7: resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} + fs-extra@11.2.0: + resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==} + engines: {node: '>=14.14'} + fs.promises.exists@1.1.4: resolution: {integrity: sha512-lJzUGWbZn8vhGWBedA+RYjB/BeJ+3458ljUfmplqhIeb6ewzTFWNPCR1HCiYCkXV9zxcHz9zXkJzMsEgDLzh3Q==} @@ -1200,6 +1786,10 @@ packages: resolution: {integrity: sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==} engines: {node: '>=18'} + get-nonce@1.0.1: + resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} + engines: {node: '>=6'} + get-stream@6.0.1: resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} engines: {node: '>=10'} @@ -1236,6 +1826,9 @@ packages: resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} engines: {node: '>=10'} + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} @@ -1255,14 +1848,25 @@ packages: resolution: {integrity: sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==} engines: {node: ^16.14.0 || >=18.0.0} + https-proxy-agent@6.2.1: + resolution: {integrity: sha512-ONsE3+yfZF2caH5+bJlcddtWqNI3Gvs5A38+ngvljxaBiRXRswym2c7yf8UAeFpRFKjFNHIFEHqR/OLAWJzyiA==} + engines: {node: '>= 14'} + human-signals@2.1.0: resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} engines: {node: '>=10.17.0'} + human-signals@4.3.1: + resolution: {integrity: sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==} + engines: {node: '>=14.18.0'} + human-signals@8.0.0: resolution: {integrity: sha512-/1/GPCpDUCCYwlERiYjxoczfP0zfvZMU/OWgQPMya9AbAE24vseigFdhAMObpc8Q4lc/kjutPfUddDYyAmejnA==} engines: {node: '>=18.18.0'} + ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + ignore@5.3.2: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} @@ -1279,6 +1883,15 @@ packages: resolution: {integrity: sha512-MWDKS3AS1bGCHLBA2VLImJz42f7bJh8wQsTGCzI3j519/CASStoDONUBVz2I/VID0MpiX3SGSnbOD2xUalbE5g==} engines: {node: '>=18'} + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + invariant@2.2.4: + resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==} + + is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + is-binary-path@2.1.0: resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} engines: {node: '>=8'} @@ -1319,6 +1932,10 @@ packages: resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} engines: {node: '>=8'} + is-stream@3.0.0: + resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + is-stream@4.0.1: resolution: {integrity: sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==} engines: {node: '>=18'} @@ -1360,6 +1977,9 @@ packages: json-buffer@3.0.1: resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + json-parse-even-better-errors@2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + json-schema-traverse@0.4.1: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} @@ -1371,9 +1991,16 @@ packages: engines: {node: '>=6'} hasBin: true + jsonfile@6.1.0: + resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + kleur@3.0.3: + resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} + engines: {node: '>=6'} + levn@0.4.1: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} @@ -1397,12 +2024,25 @@ packages: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} + lodash._reinterpolate@3.0.0: + resolution: {integrity: sha512-xYHt68QRoYGjeeM/XOE1uJtvXQAgvszfBhjV4yvsQH0u2i9I6cI6c6/eG4Hh3UAOVn0y/xAXwmTzEay49Q//HA==} + lodash.merge@4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} lodash.sortby@4.7.0: resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==} + lodash.template@4.5.0: + resolution: {integrity: sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==} + + lodash.templatesettings@4.2.0: + resolution: {integrity: sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==} + + log-symbols@5.1.0: + resolution: {integrity: sha512-l0x2DvrW294C9uDCoQe1VSU4gf529FkSZ6leBl4TiqZH/e+0R7hSfHQBNut2mNygDgHwvYHfFLn6Oxb3VWj2rA==} + engines: {node: '>=12'} + log-symbols@6.0.0: resolution: {integrity: sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==} engines: {node: '>=18'} @@ -1417,6 +2057,11 @@ packages: lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + lucide-react@0.428.0: + resolution: {integrity: sha512-rGrzslfEcgqwh+TLBC5qJ8wvVIXhLvAIXVFKNHndYyb1utSxxn9rXOC+1CNJLi6yNOooyPqIs6+3YCp6uSiEvg==} + peerDependencies: + react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0-rc + merge-stream@2.0.0: resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} @@ -1432,17 +2077,33 @@ packages: resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} engines: {node: '>=6'} + mimic-fn@4.0.0: + resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} + engines: {node: '>=12'} + minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + minimatch@7.4.6: + resolution: {integrity: sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==} + engines: {node: '>=10'} + minimatch@9.0.5: resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} engines: {node: '>=16 || 14 >=14.17'} + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + minipass@7.1.2: resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} engines: {node: '>=16 || 14 >=14.17'} + mkdirp@2.1.6: + resolution: {integrity: sha512-+hEnITedc8LAtIP9u3HJDFIdcLV2vXP33sqLLIzkv1Db1zO/1OxbvYf0Y1OC/S/Qo5dxHXepofhmxL02PsKe+A==} + engines: {node: '>=10'} + hasBin: true + ms@2.1.2: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} @@ -1457,6 +2118,14 @@ packages: natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + node-domexception@1.0.0: + resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} + engines: {node: '>=10.5.0'} + + node-fetch@3.3.2: + resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + node-releases@2.0.18: resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==} @@ -1492,10 +2161,18 @@ packages: resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} engines: {node: '>=6'} + onetime@6.0.0: + resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} + engines: {node: '>=12'} + optionator@0.9.4: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} + ora@6.3.1: + resolution: {integrity: sha512-ERAyNnZOfqM+Ao3RAvIXkYh5joP220yf59gVe2X/cI6SiCxIdi4c9HZKZD8R6q/RDXEje1THBju6iExiSsgJaQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + ora@8.0.1: resolution: {integrity: sha512-ANIvzobt1rls2BDny5fWZ3ZVKyD6nscLvfFRpQgfWsythlcsVUC9kL0zq6j2Z5z9wwp1kd7wpsD/T9qNPVLCaQ==} engines: {node: '>=18'} @@ -1515,6 +2192,10 @@ packages: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} + parse-json@5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + parse-json@8.1.0: resolution: {integrity: sha512-rum1bPifK5SSar35Z6EKZuYPJx85pkNaFrxBK3mwdfSJ1/WKbYrjoW/zTPSjRRamfmVX1ACBIdFAO0VRErW/EA==} engines: {node: '>=18'} @@ -1523,6 +2204,9 @@ packages: resolution: {integrity: sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==} engines: {node: '>=18'} + path-browserify@1.0.1: + resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} + path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} @@ -1639,6 +2323,10 @@ packages: resolution: {integrity: sha512-o1piW0n3tgKIKCwk2vpM/vOV13zjJzvP37Ioze54YlTHE06m4tjEbzg9WsKkvTuyYln2DHjo5pY4qrZGI0otpw==} engines: {node: '>=18'} + prompts@2.4.2: + resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} + engines: {node: '>= 6'} + prop-types@15.8.1: resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} @@ -1667,6 +2355,36 @@ packages: resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==} engines: {node: '>=0.10.0'} + react-remove-scroll-bar@2.3.6: + resolution: {integrity: sha512-DtSYaao4mBmX+HDo5YWYdBWQwYIQQshUV/dVxFxK+KM26Wjwp1gZ6rv6OC3oujI6Bfu6Xyg3TwK533AQutsn/g==} + 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 + + react-remove-scroll@2.5.5: + resolution: {integrity: sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw==} + 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 + + react-remove-scroll@2.5.7: + resolution: {integrity: sha512-FnrTWO4L7/Bhhf3CYBNArEG/yROV0tKmTv7/3h9QCFvH6sndeFf1wPqOcbFVu5VAulS5dV1wGT3GZZ/1GawqiA==} + 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 + react-router-dom@6.26.1: resolution: {integrity: sha512-veut7m41S1fLql4pLhxeSW3jlqs+4MtjRLj0xvuCEXsxusJCbs6I8yn9BxzzDX2XDgafrccY6hwjmd/bL54tFw==} engines: {node: '>=14.0.0'} @@ -1680,6 +2398,16 @@ packages: peerDependencies: react: '>=16.8' + react-style-singleton@2.2.1: + resolution: {integrity: sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==} + 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 + react@18.3.1: resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} engines: {node: '>=0.10.0'} @@ -1691,10 +2419,21 @@ packages: resolution: {integrity: sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA==} engines: {node: '>=18'} + readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + readdirp@3.6.0: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} + recast@0.23.9: + resolution: {integrity: sha512-Hx/BGIbwj+Des3+xy5uAtAbdCyqK9y9wbBcDFDYanLS9JnMqf7OeF87HQwUimE87OEc72mr6tkKUKMBBL+hF9Q==} + engines: {node: '>= 4'} + + regenerator-runtime@0.14.1: + resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} + resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} @@ -1726,6 +2465,9 @@ packages: rxjs@7.8.1: resolution: {integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==} + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + scale-ts@1.6.0: resolution: {integrity: sha512-Ja5VCjNZR8TGKhUumy9clVVxcDpM+YFjAnkMuwQy68Hixio3VRRvWdE3g8T/yC+HXA0ZDQl2TGyUmtmbcVl40Q==} @@ -1741,6 +2483,10 @@ packages: engines: {node: '>=10'} hasBin: true + shadcn-ui@0.8.0: + resolution: {integrity: sha512-avqRgjJ6PIQQXdfvoCAWQpyLTLk6oHhtU5DQKmLeYcgu1ZIsgMqA9MKWAkr0HpEdCAenCCZvFbvJ2C2m5ZXRiA==} + hasBin: true + shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} @@ -1756,6 +2502,9 @@ packages: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} + sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + slash@3.0.0: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} @@ -1771,6 +2520,10 @@ packages: resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} engines: {node: '>=0.10.0'} + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + source-map@0.8.0-beta.0: resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==} engines: {node: '>= 8'} @@ -1787,6 +2540,10 @@ packages: spdx-license-ids@3.0.18: resolution: {integrity: sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==} + stdin-discarder@0.1.0: + resolution: {integrity: sha512-xhV7w8S+bUwlPTb4bAOUQhv8/cSS5offJuX8GQGq32ONF0ZtDWKfkdomM3HMRA+LhX6um/FZ0COqlwsjD53LeQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + stdin-discarder@0.2.2: resolution: {integrity: sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==} engines: {node: '>=18'} @@ -1803,6 +2560,9 @@ packages: resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} engines: {node: '>=18'} + string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} @@ -1811,10 +2571,18 @@ packages: resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} engines: {node: '>=12'} + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + strip-final-newline@2.0.0: resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} engines: {node: '>=6'} + strip-final-newline@3.0.0: + resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} + engines: {node: '>=12'} + strip-final-newline@4.0.0: resolution: {integrity: sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==} engines: {node: '>=18'} @@ -1843,6 +2611,11 @@ packages: tailwind-merge@2.5.2: resolution: {integrity: sha512-kjEBm+pvD+6eAwzJL2Bi+02/9LFLal1Gs61+QB7HvTfQQ0aXwC5LGT8PEt1gS0CWKktKe6ysPTAy3cBC5MeiIg==} + tailwindcss-animate@1.0.7: + resolution: {integrity: sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==} + peerDependencies: + tailwindcss: '>=3.0.0 || insiders' + tailwindcss@3.4.10: resolution: {integrity: sha512-KWZkVPm7yJRhdu4SRSl9d4AK2wM3a50UsvgHZO7xY77NQr2V+fIrEuoDGQcbvswWvFGbS2f6e+jC/6WJm1Dl0w==} engines: {node: '>=14.0.0'} @@ -1858,6 +2631,9 @@ packages: thenify@3.3.1: resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + tiny-invariant@1.3.3: + resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} + to-fast-properties@2.0.0: resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} engines: {node: '>=4'} @@ -1882,12 +2658,19 @@ packages: ts-interface-checker@0.1.13: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + ts-morph@18.0.0: + resolution: {integrity: sha512-Kg5u0mk19PIIe4islUI/HWRvm9bC1lHejK4S0oh1zaZ77TMZAEmQC0sHQYiu2RgCQFZKXz1fMVi/7nOOeirznA==} + tsc-prog@2.3.0: resolution: {integrity: sha512-ycET2d75EgcX7y8EmG4KiZkLAwUzbY4xRhA6NU0uVbHkY4ZjrAAuzTMxXI85kOwATqPnBI5C/7y7rlpY0xdqHA==} engines: {node: '>=12'} peerDependencies: typescript: '>=4' + tsconfig-paths@4.2.0: + resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==} + engines: {node: '>=6'} + tslib@2.6.3: resolution: {integrity: sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==} @@ -1939,6 +2722,10 @@ packages: resolution: {integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==} engines: {node: '>=18'} + universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + update-browserslist-db@1.1.0: resolution: {integrity: sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==} hasBin: true @@ -1948,6 +2735,26 @@ packages: uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + use-callback-ref@1.3.2: + resolution: {integrity: sha512-elOQwe6Q8gqZgDA8mrh44qRTQqpIHDcZ3hXTLjBe1i4ph8XpNJnO+aQf3NaG+lriLopI4HMx9VjQLfPQ6vhnoA==} + 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 + + use-sidecar@1.1.2: + resolution: {integrity: sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': ^16.9.0 || ^17.0.0 || ^18.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + use-sync-external-store@1.2.2: resolution: {integrity: sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==} peerDependencies: @@ -1990,6 +2797,13 @@ packages: terser: optional: true + wcwidth@1.0.1: + resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} + + web-streams-polyfill@3.3.3: + resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} + engines: {node: '>= 8'} + webidl-conversions@4.0.2: resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==} @@ -2053,6 +2867,9 @@ packages: resolution: {integrity: sha512-GQHQqAopRhwU8Kt1DDM8NjibDXHC8eoh1erhGAJPEyveY9qqVeXvVikNKrDz69sHowPMorbPUrH/mx8c50eiBQ==} engines: {node: '>=18'} + zod@3.23.8: + resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==} + snapshots: '@alloc/quick-lru@5.2.0': {} @@ -2062,6 +2879,8 @@ snapshots: '@jridgewell/gen-mapping': 0.3.5 '@jridgewell/trace-mapping': 0.3.25 + '@antfu/ni@0.21.12': {} + '@babel/code-frame@7.24.7': dependencies: '@babel/highlight': 7.24.7 @@ -2096,6 +2915,10 @@ snapshots: '@jridgewell/trace-mapping': 0.3.25 jsesc: 2.5.2 + '@babel/helper-annotate-as-pure@7.24.7': + dependencies: + '@babel/types': 7.25.2 + '@babel/helper-compilation-targets@7.25.2': dependencies: '@babel/compat-data': 7.25.2 @@ -2104,6 +2927,26 @@ snapshots: lru-cache: 5.1.1 semver: 6.3.1 + '@babel/helper-create-class-features-plugin@7.25.0(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-annotate-as-pure': 7.24.7 + '@babel/helper-member-expression-to-functions': 7.24.8 + '@babel/helper-optimise-call-expression': 7.24.7 + '@babel/helper-replace-supers': 7.25.0(@babel/core@7.25.2) + '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 + '@babel/traverse': 7.25.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/helper-member-expression-to-functions@7.24.8': + dependencies: + '@babel/traverse': 7.25.3 + '@babel/types': 7.25.2 + transitivePeerDependencies: + - supports-color + '@babel/helper-module-imports@7.24.7': dependencies: '@babel/traverse': 7.25.3 @@ -2121,8 +2964,21 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/helper-optimise-call-expression@7.24.7': + dependencies: + '@babel/types': 7.25.2 + '@babel/helper-plugin-utils@7.24.8': {} + '@babel/helper-replace-supers@7.25.0(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-member-expression-to-functions': 7.24.8 + '@babel/helper-optimise-call-expression': 7.24.7 + '@babel/traverse': 7.25.3 + transitivePeerDependencies: + - supports-color + '@babel/helper-simple-access@7.24.7': dependencies: '@babel/traverse': 7.25.3 @@ -2130,6 +2986,13 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/helper-skip-transparent-expression-wrappers@7.24.7': + dependencies: + '@babel/traverse': 7.25.3 + '@babel/types': 7.25.2 + transitivePeerDependencies: + - supports-color + '@babel/helper-string-parser@7.24.8': {} '@babel/helper-validator-identifier@7.24.7': {} @@ -2152,6 +3015,11 @@ snapshots: dependencies: '@babel/types': 7.25.2 + '@babel/plugin-syntax-typescript@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/plugin-transform-react-jsx-self@7.24.7(@babel/core@7.25.2)': dependencies: '@babel/core': 7.25.2 @@ -2162,6 +3030,21 @@ snapshots: '@babel/core': 7.25.2 '@babel/helper-plugin-utils': 7.24.8 + '@babel/plugin-transform-typescript@7.25.2(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-annotate-as-pure': 7.24.7 + '@babel/helper-create-class-features-plugin': 7.25.0(@babel/core@7.25.2) + '@babel/helper-plugin-utils': 7.24.8 + '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 + '@babel/plugin-syntax-typescript': 7.24.7(@babel/core@7.25.2) + transitivePeerDependencies: + - supports-color + + '@babel/runtime@7.25.0': + dependencies: + regenerator-runtime: 0.14.1 + '@babel/template@7.25.0': dependencies: '@babel/code-frame': 7.24.7 @@ -2364,6 +3247,23 @@ snapshots: '@eslint/object-schema@2.1.4': {} + '@floating-ui/core@1.6.7': + dependencies: + '@floating-ui/utils': 0.2.7 + + '@floating-ui/dom@1.6.10': + dependencies: + '@floating-ui/core': 1.6.7 + '@floating-ui/utils': 0.2.7 + + '@floating-ui/react-dom@2.1.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@floating-ui/dom': 1.6.10 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + '@floating-ui/utils@0.2.7': {} + '@humanwhocodes/module-importer@1.0.1': {} '@humanwhocodes/retry@0.3.0': {} @@ -2508,56 +3408,417 @@ snapshots: dependencies: '@polkadot-api/json-rpc-provider': 0.0.3 - '@polkadot-api/polkadot-signer@0.1.3': + '@polkadot-api/polkadot-signer@0.1.3': + dependencies: + '@polkadot-api/metadata-builders': 0.5.0 + '@polkadot-api/substrate-bindings': 0.6.3 + '@polkadot-api/utils': 0.1.1 + + '@polkadot-api/signer@0.1.3': + dependencies: + '@polkadot-api/polkadot-signer': 0.1.3 + '@polkadot-api/substrate-bindings': 0.6.3 + '@polkadot-api/utils': 0.1.1 + + '@polkadot-api/sm-provider@0.1.1(smoldot@2.0.30)': + dependencies: + '@polkadot-api/json-rpc-provider': 0.0.2 + '@polkadot-api/json-rpc-provider-proxy': 0.2.0 + smoldot: 2.0.30 + + '@polkadot-api/smoldot@0.3.2': + dependencies: + '@types/node': 22.4.1 + smoldot: 2.0.30 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@polkadot-api/substrate-bindings@0.6.3': + dependencies: + '@noble/hashes': 1.4.0 + '@polkadot-api/utils': 0.1.1 + '@scure/base': 1.1.7 + scale-ts: 1.6.0 + + '@polkadot-api/substrate-client@0.2.1': + dependencies: + '@polkadot-api/json-rpc-provider': 0.0.3 + '@polkadot-api/utils': 0.1.1 + + '@polkadot-api/utils@0.1.1': {} + + '@polkadot-api/wasm-executor@0.1.1': {} + + '@polkadot-api/ws-provider@0.2.0': + dependencies: + '@polkadot-api/json-rpc-provider': 0.0.3 + '@polkadot-api/json-rpc-provider-proxy': 0.2.0 + ws: 8.18.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@radix-ui/primitive@1.0.1': + dependencies: + '@babel/runtime': 7.25.0 + + '@radix-ui/primitive@1.1.0': {} + + '@radix-ui/react-arrow@1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.3 + '@types/react-dom': 18.3.0 + + '@radix-ui/react-compose-refs@1.0.1(@types/react@18.3.3)(react@18.3.1)': + dependencies: + '@babel/runtime': 7.25.0 + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.3 + + '@radix-ui/react-compose-refs@1.1.0(@types/react@18.3.3)(react@18.3.1)': + dependencies: + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.3 + + '@radix-ui/react-context@1.0.1(@types/react@18.3.3)(react@18.3.1)': + dependencies: + '@babel/runtime': 7.25.0 + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.3 + + '@radix-ui/react-context@1.1.0(@types/react@18.3.3)(react@18.3.1)': + dependencies: + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.3 + + '@radix-ui/react-dialog@1.0.5(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@babel/runtime': 7.25.0 + '@radix-ui/primitive': 1.0.1 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-context': 1.0.1(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.0.5(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-focus-guards': 1.0.1(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-focus-scope': 1.0.4(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-id': 1.0.1(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-portal': 1.0.4(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.0.2(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.3.3)(react@18.3.1) + aria-hidden: 1.2.4 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-remove-scroll: 2.5.5(@types/react@18.3.3)(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.3 + '@types/react-dom': 18.3.0 + + '@radix-ui/react-dialog@1.1.1(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.0 + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-context': 1.1.0(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-focus-guards': 1.1.0(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-focus-scope': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-id': 1.1.0(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-portal': 1.1.1(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.1.0(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.3)(react@18.3.1) + aria-hidden: 1.2.4 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-remove-scroll: 2.5.7(@types/react@18.3.3)(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.3 + '@types/react-dom': 18.3.0 + + '@radix-ui/react-dismissable-layer@1.0.5(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@babel/runtime': 7.25.0 + '@radix-ui/primitive': 1.0.1 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-use-escape-keydown': 1.0.3(@types/react@18.3.3)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.3 + '@types/react-dom': 18.3.0 + + '@radix-ui/react-dismissable-layer@1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.0 + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-use-escape-keydown': 1.1.0(@types/react@18.3.3)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.3 + '@types/react-dom': 18.3.0 + + '@radix-ui/react-focus-guards@1.0.1(@types/react@18.3.3)(react@18.3.1)': + dependencies: + '@babel/runtime': 7.25.0 + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.3 + + '@radix-ui/react-focus-guards@1.1.0(@types/react@18.3.3)(react@18.3.1)': + dependencies: + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.3 + + '@radix-ui/react-focus-scope@1.0.4(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@babel/runtime': 7.25.0 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.3.3)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.3 + '@types/react-dom': 18.3.0 + + '@radix-ui/react-focus-scope@1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.3)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.3 + '@types/react-dom': 18.3.0 + + '@radix-ui/react-id@1.0.1(@types/react@18.3.3)(react@18.3.1)': + dependencies: + '@babel/runtime': 7.25.0 + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.3.3)(react@18.3.1) + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.3 + + '@radix-ui/react-id@1.1.0(@types/react@18.3.3)(react@18.3.1)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.3)(react@18.3.1) + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.3 + + '@radix-ui/react-popover@1.1.1(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/primitive': 1.1.0 + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-context': 1.1.0(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-focus-guards': 1.1.0(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-focus-scope': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-id': 1.1.0(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-popper': 1.2.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-portal': 1.1.1(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-presence': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-slot': 1.1.0(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.3)(react@18.3.1) + aria-hidden: 1.2.4 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-remove-scroll: 2.5.7(@types/react@18.3.3)(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.3 + '@types/react-dom': 18.3.0 + + '@radix-ui/react-popper@1.2.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@floating-ui/react-dom': 2.1.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-arrow': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-context': 1.1.0(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-use-rect': 1.1.0(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-use-size': 1.1.0(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/rect': 1.1.0 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.3 + '@types/react-dom': 18.3.0 + + '@radix-ui/react-portal@1.0.4(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@babel/runtime': 7.25.0 + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.3 + '@types/react-dom': 18.3.0 + + '@radix-ui/react-portal@1.1.1(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.3)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.3 + '@types/react-dom': 18.3.0 + + '@radix-ui/react-presence@1.0.1(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@babel/runtime': 7.25.0 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.3.3)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.3 + '@types/react-dom': 18.3.0 + + '@radix-ui/react-presence@1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.3)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.3)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.3 + '@types/react-dom': 18.3.0 + + '@radix-ui/react-primitive@1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@babel/runtime': 7.25.0 + '@radix-ui/react-slot': 1.0.2(@types/react@18.3.3)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.3 + '@types/react-dom': 18.3.0 + + '@radix-ui/react-primitive@2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/react-slot': 1.1.0(@types/react@18.3.3)(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.3 + '@types/react-dom': 18.3.0 + + '@radix-ui/react-separator@1.1.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.3 + '@types/react-dom': 18.3.0 + + '@radix-ui/react-slot@1.0.2(@types/react@18.3.3)(react@18.3.1)': + dependencies: + '@babel/runtime': 7.25.0 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.3.3)(react@18.3.1) + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.3 + + '@radix-ui/react-slot@1.1.0(@types/react@18.3.3)(react@18.3.1)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.3.3)(react@18.3.1) + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.3 + + '@radix-ui/react-use-callback-ref@1.0.1(@types/react@18.3.3)(react@18.3.1)': + dependencies: + '@babel/runtime': 7.25.0 + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.3 + + '@radix-ui/react-use-callback-ref@1.1.0(@types/react@18.3.3)(react@18.3.1)': dependencies: - '@polkadot-api/metadata-builders': 0.5.0 - '@polkadot-api/substrate-bindings': 0.6.3 - '@polkadot-api/utils': 0.1.1 + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.3 - '@polkadot-api/signer@0.1.3': + '@radix-ui/react-use-controllable-state@1.0.1(@types/react@18.3.3)(react@18.3.1)': dependencies: - '@polkadot-api/polkadot-signer': 0.1.3 - '@polkadot-api/substrate-bindings': 0.6.3 - '@polkadot-api/utils': 0.1.1 + '@babel/runtime': 7.25.0 + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.3.3)(react@18.3.1) + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.3 - '@polkadot-api/sm-provider@0.1.1(smoldot@2.0.30)': + '@radix-ui/react-use-controllable-state@1.1.0(@types/react@18.3.3)(react@18.3.1)': dependencies: - '@polkadot-api/json-rpc-provider': 0.0.2 - '@polkadot-api/json-rpc-provider-proxy': 0.2.0 - smoldot: 2.0.30 + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.3)(react@18.3.1) + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.3 - '@polkadot-api/smoldot@0.3.2': + '@radix-ui/react-use-escape-keydown@1.0.3(@types/react@18.3.3)(react@18.3.1)': dependencies: - '@types/node': 22.4.1 - smoldot: 2.0.30 - transitivePeerDependencies: - - bufferutil - - utf-8-validate + '@babel/runtime': 7.25.0 + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.3.3)(react@18.3.1) + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.3 - '@polkadot-api/substrate-bindings@0.6.3': + '@radix-ui/react-use-escape-keydown@1.1.0(@types/react@18.3.3)(react@18.3.1)': dependencies: - '@noble/hashes': 1.4.0 - '@polkadot-api/utils': 0.1.1 - '@scure/base': 1.1.7 - scale-ts: 1.6.0 + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.3)(react@18.3.1) + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.3 - '@polkadot-api/substrate-client@0.2.1': + '@radix-ui/react-use-layout-effect@1.0.1(@types/react@18.3.3)(react@18.3.1)': dependencies: - '@polkadot-api/json-rpc-provider': 0.0.3 - '@polkadot-api/utils': 0.1.1 + '@babel/runtime': 7.25.0 + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.3 - '@polkadot-api/utils@0.1.1': {} + '@radix-ui/react-use-layout-effect@1.1.0(@types/react@18.3.3)(react@18.3.1)': + dependencies: + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.3 - '@polkadot-api/wasm-executor@0.1.1': {} + '@radix-ui/react-use-rect@1.1.0(@types/react@18.3.3)(react@18.3.1)': + dependencies: + '@radix-ui/rect': 1.1.0 + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.3 - '@polkadot-api/ws-provider@0.2.0': + '@radix-ui/react-use-size@1.1.0(@types/react@18.3.3)(react@18.3.1)': dependencies: - '@polkadot-api/json-rpc-provider': 0.0.3 - '@polkadot-api/json-rpc-provider-proxy': 0.2.0 - ws: 8.18.0 - transitivePeerDependencies: - - bufferutil - - utf-8-validate + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.3)(react@18.3.1) + react: 18.3.1 + optionalDependencies: + '@types/react': 18.3.3 + + '@radix-ui/rect@1.1.0': {} '@react-rxjs/core@0.10.7(react@18.3.1)(rxjs@7.8.1)': dependencies: @@ -2632,6 +3893,13 @@ snapshots: '@sindresorhus/merge-streams@4.0.0': {} + '@ts-morph/common@0.19.0': + dependencies: + fast-glob: 3.3.2 + minimatch: 7.4.6 + mkdirp: 2.1.6 + path-browserify: 1.0.1 + '@types/babel__core@7.20.5': dependencies: '@babel/parser': 7.25.3 @@ -2774,6 +4042,12 @@ snapshots: acorn@8.12.1: {} + agent-base@7.1.1: + dependencies: + debug: 4.3.6 + transitivePeerDependencies: + - supports-color + ajv@6.12.6: dependencies: fast-deep-equal: 3.1.3 @@ -2806,8 +4080,16 @@ snapshots: argparse@2.0.1: {} + aria-hidden@1.2.4: + dependencies: + tslib: 2.6.3 + array-union@2.1.0: {} + ast-types@0.16.1: + dependencies: + tslib: 2.6.3 + autoprefixer@10.4.20(postcss@8.4.41): dependencies: browserslist: 4.23.3 @@ -2820,8 +4102,16 @@ snapshots: balanced-match@1.0.2: {} + base64-js@1.5.1: {} + binary-extensions@2.3.0: {} + bl@5.1.0: + dependencies: + buffer: 6.0.3 + inherits: 2.0.4 + readable-stream: 3.6.2 + brace-expansion@1.1.11: dependencies: balanced-match: 1.0.2 @@ -2842,6 +4132,11 @@ snapshots: node-releases: 2.0.18 update-browserslist-db: 1.1.0(browserslist@4.23.3) + buffer@6.0.3: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + bundle-require@5.0.0(esbuild@0.23.1): dependencies: esbuild: 0.23.1 @@ -2866,6 +4161,8 @@ snapshots: ansi-styles: 4.3.0 supports-color: 7.2.0 + chalk@5.2.0: {} + chalk@5.3.0: {} chokidar@3.6.0: @@ -2880,14 +4177,34 @@ snapshots: optionalDependencies: fsevents: 2.3.3 + class-variance-authority@0.7.0: + dependencies: + clsx: 2.0.0 + cli-cursor@4.0.0: dependencies: restore-cursor: 4.0.0 cli-spinners@2.9.2: {} + clone@1.0.4: {} + + clsx@2.0.0: {} + clsx@2.1.1: {} + cmdk@1.0.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@radix-ui/react-dialog': 1.0.5(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + transitivePeerDependencies: + - '@types/react' + - '@types/react-dom' + + code-block-writer@12.0.0: {} + color-convert@1.9.3: dependencies: color-name: 1.1.3 @@ -2900,6 +4217,8 @@ snapshots: color-name@1.1.4: {} + commander@10.0.1: {} + commander@12.1.0: {} commander@4.1.1: {} @@ -2910,6 +4229,15 @@ snapshots: convert-source-map@2.0.0: {} + cosmiconfig@8.3.6(typescript@5.5.4): + dependencies: + import-fresh: 3.3.0 + js-yaml: 4.1.0 + parse-json: 5.2.0 + path-type: 4.0.0 + optionalDependencies: + typescript: 5.5.4 + cross-spawn@7.0.3: dependencies: path-key: 3.1.1 @@ -2920,6 +4248,8 @@ snapshots: csstype@3.1.3: {} + data-uri-to-buffer@4.0.1: {} + debug@4.3.6: dependencies: ms: 2.1.2 @@ -2928,10 +4258,18 @@ snapshots: deepmerge-ts@7.1.0: {} + defaults@1.0.4: + dependencies: + clone: 1.0.4 + detect-indent@7.0.1: {} + detect-node-es@1.1.0: {} + didyoumean@1.2.2: {} + diff@5.2.0: {} + dir-glob@3.0.1: dependencies: path-type: 4.0.0 @@ -2948,6 +4286,10 @@ snapshots: emoji-regex@9.2.2: {} + error-ex@1.3.2: + dependencies: + is-arrayish: 0.2.1 + esbuild@0.21.5: optionalDependencies: '@esbuild/aix-ppc64': 0.21.5 @@ -3071,6 +4413,8 @@ snapshots: acorn-jsx: 5.3.2(acorn@8.12.1) eslint-visitor-keys: 4.0.0 + esprima@4.0.1: {} + esquery@1.6.0: dependencies: estraverse: 5.3.0 @@ -3095,6 +4439,18 @@ snapshots: signal-exit: 3.0.7 strip-final-newline: 2.0.0 + execa@7.2.0: + dependencies: + cross-spawn: 7.0.3 + get-stream: 6.0.1 + human-signals: 4.3.1 + is-stream: 3.0.0 + merge-stream: 2.0.0 + npm-run-path: 5.3.0 + onetime: 6.0.0 + signal-exit: 3.0.7 + strip-final-newline: 3.0.0 + execa@9.3.1: dependencies: '@sindresorhus/merge-streams': 4.0.0 @@ -3128,6 +4484,11 @@ snapshots: dependencies: reusify: 1.0.4 + fetch-blob@3.2.0: + dependencies: + node-domexception: 1.0.0 + web-streams-polyfill: 3.3.3 + figures@6.1.0: dependencies: is-unicode-supported: 2.0.0 @@ -3157,8 +4518,18 @@ snapshots: cross-spawn: 7.0.3 signal-exit: 4.1.0 + formdata-polyfill@4.0.10: + dependencies: + fetch-blob: 3.2.0 + fraction.js@4.3.7: {} + fs-extra@11.2.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.1 + fs.promises.exists@1.1.4: {} fsevents@2.3.3: @@ -3170,6 +4541,8 @@ snapshots: get-east-asian-width@1.2.0: {} + get-nonce@1.0.1: {} + get-stream@6.0.1: {} get-stream@9.0.1: @@ -3209,6 +4582,8 @@ snapshots: merge2: 1.4.1 slash: 3.0.0 + graceful-fs@4.2.11: {} + graphemer@1.4.0: {} has-flag@3.0.0: {} @@ -3223,10 +4598,21 @@ snapshots: dependencies: lru-cache: 10.4.3 + https-proxy-agent@6.2.1: + dependencies: + agent-base: 7.1.1 + debug: 4.3.6 + transitivePeerDependencies: + - supports-color + human-signals@2.1.0: {} + human-signals@4.3.1: {} + human-signals@8.0.0: {} + ieee754@1.2.1: {} + ignore@5.3.2: {} import-fresh@3.3.0: @@ -3238,6 +4624,14 @@ snapshots: index-to-position@0.1.2: {} + inherits@2.0.4: {} + + invariant@2.2.4: + dependencies: + loose-envify: 1.4.0 + + is-arrayish@0.2.1: {} + is-binary-path@2.1.0: dependencies: binary-extensions: 2.3.0 @@ -3264,6 +4658,8 @@ snapshots: is-stream@2.0.1: {} + is-stream@3.0.0: {} + is-stream@4.0.1: {} is-unicode-supported@1.3.0: {} @@ -3292,16 +4688,26 @@ snapshots: json-buffer@3.0.1: {} + json-parse-even-better-errors@2.3.1: {} + json-schema-traverse@0.4.1: {} json-stable-stringify-without-jsonify@1.0.1: {} json5@2.2.3: {} + jsonfile@6.1.0: + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + keyv@4.5.4: dependencies: json-buffer: 3.0.1 + kleur@3.0.3: {} + levn@0.4.1: dependencies: prelude-ls: 1.2.1 @@ -3319,10 +4725,26 @@ snapshots: dependencies: p-locate: 5.0.0 + lodash._reinterpolate@3.0.0: {} + lodash.merge@4.6.2: {} lodash.sortby@4.7.0: {} + lodash.template@4.5.0: + dependencies: + lodash._reinterpolate: 3.0.0 + lodash.templatesettings: 4.2.0 + + lodash.templatesettings@4.2.0: + dependencies: + lodash._reinterpolate: 3.0.0 + + log-symbols@5.1.0: + dependencies: + chalk: 5.3.0 + is-unicode-supported: 1.3.0 + log-symbols@6.0.0: dependencies: chalk: 5.3.0 @@ -3338,6 +4760,10 @@ snapshots: dependencies: yallist: 3.1.1 + lucide-react@0.428.0(react@18.3.1): + dependencies: + react: 18.3.1 + merge-stream@2.0.0: {} merge2@1.4.1: {} @@ -3349,16 +4775,26 @@ snapshots: mimic-fn@2.1.0: {} + mimic-fn@4.0.0: {} + minimatch@3.1.2: dependencies: brace-expansion: 1.1.11 + minimatch@7.4.6: + dependencies: + brace-expansion: 2.0.1 + minimatch@9.0.5: dependencies: brace-expansion: 2.0.1 + minimist@1.2.8: {} + minipass@7.1.2: {} + mkdirp@2.1.6: {} + ms@2.1.2: {} mz@2.7.0: @@ -3371,6 +4807,14 @@ snapshots: natural-compare@1.4.0: {} + node-domexception@1.0.0: {} + + node-fetch@3.3.2: + dependencies: + data-uri-to-buffer: 4.0.1 + fetch-blob: 3.2.0 + formdata-polyfill: 4.0.10 + node-releases@2.0.18: {} normalize-package-data@6.0.2: @@ -3399,6 +4843,10 @@ snapshots: dependencies: mimic-fn: 2.1.0 + onetime@6.0.0: + dependencies: + mimic-fn: 4.0.0 + optionator@0.9.4: dependencies: deep-is: 0.1.4 @@ -3408,6 +4856,18 @@ snapshots: type-check: 0.4.0 word-wrap: 1.2.5 + ora@6.3.1: + dependencies: + chalk: 5.3.0 + cli-cursor: 4.0.0 + cli-spinners: 2.9.2 + is-interactive: 2.0.0 + is-unicode-supported: 1.3.0 + log-symbols: 5.1.0 + stdin-discarder: 0.1.0 + strip-ansi: 7.1.0 + wcwidth: 1.0.1 + ora@8.0.1: dependencies: chalk: 5.3.0 @@ -3434,6 +4894,13 @@ snapshots: dependencies: callsites: 3.1.0 + parse-json@5.2.0: + dependencies: + '@babel/code-frame': 7.24.7 + error-ex: 1.3.2 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 + parse-json@8.1.0: dependencies: '@babel/code-frame': 7.24.7 @@ -3442,6 +4909,8 @@ snapshots: parse-ms@4.0.0: {} + path-browserify@1.0.1: {} + path-exists@4.0.0: {} path-key@3.1.1: {} @@ -3550,6 +5019,11 @@ snapshots: dependencies: parse-ms: 4.0.0 + prompts@2.4.2: + dependencies: + kleur: 3.0.3 + sisteransi: 1.0.5 + prop-types@15.8.1: dependencies: loose-envify: 1.4.0 @@ -3576,6 +5050,36 @@ snapshots: react-refresh@0.14.2: {} + react-remove-scroll-bar@2.3.6(@types/react@18.3.3)(react@18.3.1): + dependencies: + react: 18.3.1 + react-style-singleton: 2.2.1(@types/react@18.3.3)(react@18.3.1) + tslib: 2.6.3 + optionalDependencies: + '@types/react': 18.3.3 + + react-remove-scroll@2.5.5(@types/react@18.3.3)(react@18.3.1): + dependencies: + react: 18.3.1 + react-remove-scroll-bar: 2.3.6(@types/react@18.3.3)(react@18.3.1) + react-style-singleton: 2.2.1(@types/react@18.3.3)(react@18.3.1) + tslib: 2.6.3 + use-callback-ref: 1.3.2(@types/react@18.3.3)(react@18.3.1) + use-sidecar: 1.1.2(@types/react@18.3.3)(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.3 + + react-remove-scroll@2.5.7(@types/react@18.3.3)(react@18.3.1): + dependencies: + react: 18.3.1 + react-remove-scroll-bar: 2.3.6(@types/react@18.3.3)(react@18.3.1) + react-style-singleton: 2.2.1(@types/react@18.3.3)(react@18.3.1) + tslib: 2.6.3 + use-callback-ref: 1.3.2(@types/react@18.3.3)(react@18.3.1) + use-sidecar: 1.1.2(@types/react@18.3.3)(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.3 + react-router-dom@6.26.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: '@remix-run/router': 1.19.1 @@ -3588,6 +5092,15 @@ snapshots: '@remix-run/router': 1.19.1 react: 18.3.1 + react-style-singleton@2.2.1(@types/react@18.3.3)(react@18.3.1): + dependencies: + get-nonce: 1.0.1 + invariant: 2.2.4 + react: 18.3.1 + tslib: 2.6.3 + optionalDependencies: + '@types/react': 18.3.3 + react@18.3.1: dependencies: loose-envify: 1.4.0 @@ -3604,10 +5117,26 @@ snapshots: type-fest: 4.25.0 unicorn-magic: 0.1.0 + readable-stream@3.6.2: + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + readdirp@3.6.0: dependencies: picomatch: 2.3.1 + recast@0.23.9: + dependencies: + ast-types: 0.16.1 + esprima: 4.0.1 + source-map: 0.6.1 + tiny-invariant: 1.3.3 + tslib: 2.6.3 + + regenerator-runtime@0.14.1: {} + resolve-from@4.0.0: {} resolve-from@5.0.0: {} @@ -3655,6 +5184,8 @@ snapshots: dependencies: tslib: 2.6.3 + safe-buffer@5.2.1: {} + scale-ts@1.6.0: {} scheduler@0.23.2: @@ -3665,6 +5196,32 @@ snapshots: semver@7.6.3: {} + shadcn-ui@0.8.0(typescript@5.5.4): + dependencies: + '@antfu/ni': 0.21.12 + '@babel/core': 7.25.2 + '@babel/parser': 7.25.3 + '@babel/plugin-transform-typescript': 7.25.2(@babel/core@7.25.2) + chalk: 5.2.0 + commander: 10.0.1 + cosmiconfig: 8.3.6(typescript@5.5.4) + diff: 5.2.0 + execa: 7.2.0 + fast-glob: 3.3.2 + fs-extra: 11.2.0 + https-proxy-agent: 6.2.1 + lodash.template: 4.5.0 + node-fetch: 3.3.2 + ora: 6.3.1 + prompts: 2.4.2 + recast: 0.23.9 + ts-morph: 18.0.0 + tsconfig-paths: 4.2.0 + zod: 3.23.8 + transitivePeerDependencies: + - supports-color + - typescript + shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 @@ -3675,6 +5232,8 @@ snapshots: signal-exit@4.1.0: {} + sisteransi@1.0.5: {} + slash@3.0.0: {} smoldot@2.0.30: @@ -3690,6 +5249,8 @@ snapshots: source-map-js@1.2.0: {} + source-map@0.6.1: {} + source-map@0.8.0-beta.0: dependencies: whatwg-url: 7.1.0 @@ -3708,6 +5269,10 @@ snapshots: spdx-license-ids@3.0.18: {} + stdin-discarder@0.1.0: + dependencies: + bl: 5.1.0 + stdin-discarder@0.2.2: {} string-width@4.2.3: @@ -3728,6 +5293,10 @@ snapshots: get-east-asian-width: 1.2.0 strip-ansi: 7.1.0 + string_decoder@1.3.0: + dependencies: + safe-buffer: 5.2.1 + strip-ansi@6.0.1: dependencies: ansi-regex: 5.0.1 @@ -3736,8 +5305,12 @@ snapshots: dependencies: ansi-regex: 6.0.1 + strip-bom@3.0.0: {} + strip-final-newline@2.0.0: {} + strip-final-newline@3.0.0: {} + strip-final-newline@4.0.0: {} strip-json-comments@3.1.1: {} @@ -3764,6 +5337,10 @@ snapshots: tailwind-merge@2.5.2: {} + tailwindcss-animate@1.0.7(tailwindcss@3.4.10): + dependencies: + tailwindcss: 3.4.10 + tailwindcss@3.4.10: dependencies: '@alloc/quick-lru': 5.2.0 @@ -3801,6 +5378,8 @@ snapshots: dependencies: any-promise: 1.3.0 + tiny-invariant@1.3.3: {} + to-fast-properties@2.0.0: {} to-regex-range@5.0.1: @@ -3819,10 +5398,21 @@ snapshots: ts-interface-checker@0.1.13: {} + ts-morph@18.0.0: + dependencies: + '@ts-morph/common': 0.19.0 + code-block-writer: 12.0.0 + tsc-prog@2.3.0(typescript@5.5.4): dependencies: typescript: 5.5.4 + tsconfig-paths@4.2.0: + dependencies: + json5: 2.2.3 + minimist: 1.2.8 + strip-bom: 3.0.0 + tslib@2.6.3: {} tsup@8.2.4(jiti@1.21.6)(postcss@8.4.41)(typescript@5.5.4)(yaml@2.5.0): @@ -3875,6 +5465,8 @@ snapshots: unicorn-magic@0.1.0: {} + universalify@2.0.1: {} + update-browserslist-db@1.1.0(browserslist@4.23.3): dependencies: browserslist: 4.23.3 @@ -3885,6 +5477,21 @@ snapshots: dependencies: punycode: 2.3.1 + use-callback-ref@1.3.2(@types/react@18.3.3)(react@18.3.1): + dependencies: + react: 18.3.1 + tslib: 2.6.3 + optionalDependencies: + '@types/react': 18.3.3 + + use-sidecar@1.1.2(@types/react@18.3.3)(react@18.3.1): + dependencies: + detect-node-es: 1.1.0 + react: 18.3.1 + tslib: 2.6.3 + optionalDependencies: + '@types/react': 18.3.3 + use-sync-external-store@1.2.2(react@18.3.1): dependencies: react: 18.3.1 @@ -3905,6 +5512,12 @@ snapshots: '@types/node': 22.4.1 fsevents: 2.3.3 + wcwidth@1.0.1: + dependencies: + defaults: 1.0.4 + + web-streams-polyfill@3.3.3: {} + webidl-conversions@4.0.2: {} whatwg-url@7.1.0: @@ -3960,3 +5573,5 @@ snapshots: yocto-queue@0.1.0: {} yoctocolors@2.1.1: {} + + zod@3.23.8: {} diff --git a/src/actions/delegate/DelegateAction.tsx b/src/actions/delegate/DelegateAction.tsx index f7e952f..e232dd2 100644 --- a/src/actions/delegate/DelegateAction.tsx +++ b/src/actions/delegate/DelegateAction.tsx @@ -1,13 +1,143 @@ -import { useStateObservable } from "@react-rxjs/core" -import { chain$, delegateAccount$ } from "./delegate" +import { + state, + StateObservable, + Subscribe, + SUSPENSE, + useStateObservable, +} from "@react-rxjs/core" +import { routeChain$, delegateAccount$ } from "./delegate" +import { + combineLatest, + concat, + defer, + EMPTY, + from, + map, + startWith, + switchMap, + take, +} from "rxjs" +import { createSignal, switchMapSuspended } from "@react-rxjs/utils" +import { getOptimalAmount, getTracks } from "@/api/delegation" +import { SS58String } from "polkadot-api" +import { selectedAccount$ } from "@/services/accounts" +import { TokenInput } from "@/components/TokenInput" +import { VotingConviction } from "@polkadot-api/descriptors" +import { MultiSelect } from "@/components/multi-select" +import { useState } from "react" -chain$.subscribe() -delegateAccount$.subscribe() +const [amountInput$, onAmountChange] = createSignal() + +const optimalAmount$ = state((account: SS58String) => + from(getOptimalAmount(account)), +) +const amount$ = state( + combineLatest(routeChain$, delegateAccount$, selectedAccount$).pipe( + switchMapSuspended(([, , account]) => { + if (!account) return EMPTY + return concat( + optimalAmount$(account.address).pipe( + map((optimalAmount) => optimalAmount ?? 0n), + take(1), + ), + amountInput$, + ) + }), + ), +) + +const AmountInput: React.FC = () => { + const amount = useStateObservable(amount$) + return ( + + ) +} + +const convictionVotes: Array = [ + "None", + "Locked1x", + "Locked2x", + "Locked3x", + "Locked4x", + "Locked5x", + "Locked6x", +] + +const frameworksList = [ + { value: "react", label: "React" }, + { value: "angular", label: "Angular" }, + { value: "vue", label: "Vue" }, + { value: "svelte", label: "Svelte" }, + { value: "ember", label: "Ember" }, +] + +const [convictionInput$, onConvictionInputChanges] = createSignal< + 0 | 1 | 2 | 3 | 4 | 5 | 6 +>() +const conviction$: StateObservable<0 | 1 | 2 | 3 | 4 | 5 | 6 | SUSPENSE> = + state( + combineLatest(routeChain$, delegateAccount$, selectedAccount$).pipe( + switchMapSuspended(([, , account]) => { + if (!account) return EMPTY + return concat( + optimalAmount$(account.address).pipe( + map((optimalAmount) => (optimalAmount ? 3 : 0)), + take(1), + ), + convictionInput$, + ) + }), + ), + ) + +const ConvictionInput: React.FC = () => { + const conviction = useStateObservable(conviction$) + return ( + <> + {Array(7) + .fill(null) + .map((_, idx) => ( + + ))} + + ) +} + +const tracks$ = state( + defer(getTracks).pipe( + map((x) => Object.entries(x).map(([value, label]) => ({ value, label }))), + ), +) + +const SelectTracks: React.FC = () => { + const tracks = useStateObservable(tracks$) +} export const DelegateAction = () => { - console.log("delegating") - const chainData = useStateObservable(chain$) + const chainData = useStateObservable(routeChain$) const delegateAccount = useStateObservable(delegateAccount$) + const [selectedFrameworks, setSelectedFrameworks] = useState([ + "react", + "angular", + ]) return (
@@ -21,6 +151,19 @@ export const DelegateAction = () => { Delegate Account:
{delegateAccount ?? "NOT DEFINED"}
+ Loading...}> + + + + ) diff --git a/src/actions/delegate/delegate.ts b/src/actions/delegate/delegate.ts index 7eaaf0e..695bd8f 100644 --- a/src/actions/delegate/delegate.ts +++ b/src/actions/delegate/delegate.ts @@ -5,12 +5,13 @@ import { state } from "@react-rxjs/core" const PATTERN_CHAIN = "/delegate/:chain/*" const PATTERN_ACCOUNT = "/delegate/:chain/:account/*" -export const chain$ = state( +export const routeChain$ = state( routeMatch$(PATTERN_CHAIN).pipe( map((routeData) => routeData?.params?.chain ?? null), ), null, ) +routeChain$.subscribe() export const delegateAccount$ = state( routeMatch$(PATTERN_ACCOUNT).pipe( @@ -18,3 +19,4 @@ export const delegateAccount$ = state( ), null, ) +delegateAccount$.subscribe() diff --git a/src/api/delegation.ts b/src/api/delegation.ts index e418a32..c348c0f 100644 --- a/src/api/delegation.ts +++ b/src/api/delegation.ts @@ -1,11 +1,12 @@ import { SS58String } from "polkadot-api" -import { polkadotApi as paseoApi } from "./" +import { polkadotApi as api } from "./" import { MultiAddress, VotingConviction } from "@polkadot-api/descriptors" export const getOptimalAmount = async ( account: SS58String, at: string = "best", -) => (await paseoApi.query.Staking.Ledger.getValue(account, { at }))?.active +): Promise => + (await api.query.Staking.Ledger.getValue(account, { at }))?.active interface Casting { type: "Casting" @@ -21,7 +22,7 @@ interface Delegating { export const getTracks = async (): Promise> => Object.fromEntries( - (await paseoApi.constants.Referenda.Tracks()).map(([trackId, { name }]) => [ + (await api.constants.Referenda.Tracks()).map(([trackId, { name }]) => [ trackId, name .split("_") @@ -34,7 +35,7 @@ const getTrackInfo = async ( address: SS58String, ): Promise> => { const convictionVoting = - await paseoApi.query.ConvictionVoting.VotingFor.getEntries(address) + await api.query.ConvictionVoting.VotingFor.getEntries(address) return Object.fromEntries( convictionVoting @@ -70,9 +71,9 @@ export const delegate = async ( const tracksInfo = await getTrackInfo(from) const txs: Array< - | ReturnType - | ReturnType - | ReturnType + | ReturnType + | ReturnType + | ReturnType > = [] tracks.forEach((trackId) => { const trackInfo = tracksInfo[trackId] @@ -89,7 +90,7 @@ export const delegate = async ( if (trackInfo.type === "Casting") { trackInfo.referendums.forEach((index) => { txs.push( - paseoApi.tx.ConvictionVoting.remove_vote({ + api.tx.ConvictionVoting.remove_vote({ class: trackId, index, }), @@ -97,14 +98,14 @@ export const delegate = async ( }) } else txs.push( - paseoApi.tx.ConvictionVoting.undelegate({ + api.tx.ConvictionVoting.undelegate({ class: trackId, }), ) } txs.push( - paseoApi.tx.ConvictionVoting.delegate({ + api.tx.ConvictionVoting.delegate({ class: trackId, conviction, to: MultiAddress.Id(target), @@ -113,7 +114,7 @@ export const delegate = async ( ) }) - return paseoApi.tx.Utility.batch_all({ + return api.tx.Utility.batch_all({ calls: txs.map((tx) => tx.decodedCall), }) } diff --git a/src/components/multi-select.tsx b/src/components/multi-select.tsx new file mode 100644 index 0000000..ca6fabc --- /dev/null +++ b/src/components/multi-select.tsx @@ -0,0 +1,383 @@ +import * as React from "react" +import { cva, type VariantProps } from "class-variance-authority" +import { + CheckIcon, + XCircle, + ChevronDown, + XIcon, + WandSparkles, +} from "lucide-react" + +import { cn } from "@/lib/utils" +import { Separator } from "@/components/ui/separator" +import { Button } from "@/components/ui/button" +import { Badge } from "@/components/ui/badge" +import { + Popover, + PopoverContent, + PopoverTrigger, +} from "@/components/ui/popover" +import { + Command, + CommandEmpty, + CommandGroup, + CommandInput, + CommandItem, + CommandList, + CommandSeparator, +} from "@/components/ui/command" + +/** + * Variants for the multi-select component to handle different styles. + * Uses class-variance-authority (cva) to define different styles based on "variant" prop. + */ +const multiSelectVariants = cva( + "m-1 transition ease-in-out delay-150 hover:-translate-y-1 hover:scale-110 duration-300", + { + variants: { + variant: { + default: + "border-foreground/10 text-foreground bg-card hover:bg-card/80", + secondary: + "border-foreground/10 bg-secondary text-secondary-foreground hover:bg-secondary/80", + destructive: + "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80", + inverted: "inverted", + }, + }, + defaultVariants: { + variant: "default", + }, + }, +) + +/** + * Props for MultiSelect component + */ +interface MultiSelectProps + extends React.ButtonHTMLAttributes, + VariantProps { + /** + * An array of option objects to be displayed in the multi-select component. + * Each option object has a label, value, and an optional icon. + */ + options: { + /** The text to display for the option. */ + label: string + /** The unique value associated with the option. */ + value: string + /** Optional icon component to display alongside the option. */ + icon?: React.ComponentType<{ className?: string }> + }[] + + /** + * Callback function triggered when the selected values change. + * Receives an array of the new selected values. + */ + onValueChange: (value: string[]) => void + + /** The default selected values when the component mounts. */ + defaultValue: string[] + + /** + * Placeholder text to be displayed when no values are selected. + * Optional, defaults to "Select options". + */ + placeholder?: string + + /** + * Animation duration in seconds for the visual effects (e.g., bouncing badges). + * Optional, defaults to 0 (no animation). + */ + animation?: number + + /** + * Maximum number of items to display. Extra selected items will be summarized. + * Optional, defaults to 3. + */ + maxCount?: number + + /** + * The modality of the popover. When set to true, interaction with outside elements + * will be disabled and only popover content will be visible to screen readers. + * Optional, defaults to false. + */ + modalPopover?: boolean + + /** + * If true, renders the multi-select component as a child of another component. + * Optional, defaults to false. + */ + asChild?: boolean + + /** + * Additional class names to apply custom styles to the multi-select component. + * Optional, can be used to add custom styles. + */ + className?: string +} + +export const MultiSelect = React.forwardRef< + HTMLButtonElement, + MultiSelectProps +>( + ( + { + options, + onValueChange, + variant, + defaultValue = [], + placeholder = "Select options", + animation = 0, + maxCount = 3, + modalPopover = false, + asChild = false, + className, + ...props + }, + ref, + ) => { + const [selectedValues, setSelectedValues] = + React.useState(defaultValue) + const [isPopoverOpen, setIsPopoverOpen] = React.useState(false) + const [isAnimating, setIsAnimating] = React.useState(false) + + React.useEffect(() => { + setSelectedValues(defaultValue) + }, [defaultValue]) + + const handleInputKeyDown = ( + event: React.KeyboardEvent, + ) => { + if (event.key === "Enter") { + setIsPopoverOpen(true) + } else if (event.key === "Backspace" && !event.currentTarget.value) { + const newSelectedValues = [...selectedValues] + newSelectedValues.pop() + setSelectedValues(newSelectedValues) + onValueChange(newSelectedValues) + } + } + + const toggleOption = (value: string) => { + const newSelectedValues = selectedValues.includes(value) + ? selectedValues.filter((v) => v !== value) + : [...selectedValues, value] + setSelectedValues(newSelectedValues) + onValueChange(newSelectedValues) + } + + const handleClear = () => { + setSelectedValues([]) + onValueChange([]) + } + + const handleTogglePopover = () => { + setIsPopoverOpen((prev) => !prev) + } + + const clearExtraOptions = () => { + const newSelectedValues = selectedValues.slice(0, maxCount) + setSelectedValues(newSelectedValues) + onValueChange(newSelectedValues) + } + + const toggleAll = () => { + if (selectedValues.length === options.length) { + handleClear() + } else { + const allValues = options.map((option) => option.value) + setSelectedValues(allValues) + onValueChange(allValues) + } + } + + return ( + + + + + setIsPopoverOpen(false)} + > + + + + No results found. + + +
+ +
+ (Select All) +
+ {options.map((option) => { + const isSelected = selectedValues.includes(option.value) + return ( + toggleOption(option.value)} + className="cursor-pointer" + > +
+ +
+ {option.icon && ( + + )} + {option.label} +
+ ) + })} +
+ + +
+ {selectedValues.length > 0 && ( + <> + + Clear + + + + )} + setIsPopoverOpen(false)} + className="flex-1 justify-center cursor-pointer max-w-full" + > + Close + +
+
+
+
+
+ {animation > 0 && selectedValues.length > 0 && ( + setIsAnimating(!isAnimating)} + /> + )} +
+ ) + }, +) + +MultiSelect.displayName = "MultiSelect" diff --git a/src/components/ui/badge.tsx b/src/components/ui/badge.tsx new file mode 100644 index 0000000..f000e3e --- /dev/null +++ b/src/components/ui/badge.tsx @@ -0,0 +1,36 @@ +import * as React from "react" +import { cva, type VariantProps } from "class-variance-authority" + +import { cn } from "@/lib/utils" + +const badgeVariants = cva( + "inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2", + { + variants: { + variant: { + default: + "border-transparent bg-primary text-primary-foreground hover:bg-primary/80", + secondary: + "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80", + destructive: + "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80", + outline: "text-foreground", + }, + }, + defaultVariants: { + variant: "default", + }, + } +) + +export interface BadgeProps + extends React.HTMLAttributes, + VariantProps {} + +function Badge({ className, variant, ...props }: BadgeProps) { + return ( +
+ ) +} + +export { Badge, badgeVariants } diff --git a/src/components/ui/button.tsx b/src/components/ui/button.tsx new file mode 100644 index 0000000..0ba4277 --- /dev/null +++ b/src/components/ui/button.tsx @@ -0,0 +1,56 @@ +import * as React from "react" +import { Slot } from "@radix-ui/react-slot" +import { cva, type VariantProps } from "class-variance-authority" + +import { cn } from "@/lib/utils" + +const buttonVariants = cva( + "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50", + { + variants: { + variant: { + default: "bg-primary text-primary-foreground hover:bg-primary/90", + destructive: + "bg-destructive text-destructive-foreground hover:bg-destructive/90", + outline: + "border border-input bg-background hover:bg-accent hover:text-accent-foreground", + secondary: + "bg-secondary text-secondary-foreground hover:bg-secondary/80", + ghost: "hover:bg-accent hover:text-accent-foreground", + link: "text-primary underline-offset-4 hover:underline", + }, + size: { + default: "h-10 px-4 py-2", + sm: "h-9 rounded-md px-3", + lg: "h-11 rounded-md px-8", + icon: "h-10 w-10", + }, + }, + defaultVariants: { + variant: "default", + size: "default", + }, + } +) + +export interface ButtonProps + extends React.ButtonHTMLAttributes, + VariantProps { + asChild?: boolean +} + +const Button = React.forwardRef( + ({ className, variant, size, asChild = false, ...props }, ref) => { + const Comp = asChild ? Slot : "button" + return ( + + ) + } +) +Button.displayName = "Button" + +export { Button, buttonVariants } diff --git a/src/components/ui/command.tsx b/src/components/ui/command.tsx new file mode 100644 index 0000000..56a0979 --- /dev/null +++ b/src/components/ui/command.tsx @@ -0,0 +1,153 @@ +import * as React from "react" +import { type DialogProps } from "@radix-ui/react-dialog" +import { Command as CommandPrimitive } from "cmdk" +import { Search } from "lucide-react" + +import { cn } from "@/lib/utils" +import { Dialog, DialogContent } from "@/components/ui/dialog" + +const Command = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +Command.displayName = CommandPrimitive.displayName + +interface CommandDialogProps extends DialogProps {} + +const CommandDialog = ({ children, ...props }: CommandDialogProps) => { + return ( + + + + {children} + + + + ) +} + +const CommandInput = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( +
+ + +
+)) + +CommandInput.displayName = CommandPrimitive.Input.displayName + +const CommandList = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) + +CommandList.displayName = CommandPrimitive.List.displayName + +const CommandEmpty = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>((props, ref) => ( + +)) + +CommandEmpty.displayName = CommandPrimitive.Empty.displayName + +const CommandGroup = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) + +CommandGroup.displayName = CommandPrimitive.Group.displayName + +const CommandSeparator = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +CommandSeparator.displayName = CommandPrimitive.Separator.displayName + +const CommandItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) + +CommandItem.displayName = CommandPrimitive.Item.displayName + +const CommandShortcut = ({ + className, + ...props +}: React.HTMLAttributes) => { + return ( + + ) +} +CommandShortcut.displayName = "CommandShortcut" + +export { + Command, + CommandDialog, + CommandInput, + CommandList, + CommandEmpty, + CommandGroup, + CommandItem, + CommandShortcut, + CommandSeparator, +} diff --git a/src/components/ui/dialog.tsx b/src/components/ui/dialog.tsx new file mode 100644 index 0000000..c23630e --- /dev/null +++ b/src/components/ui/dialog.tsx @@ -0,0 +1,120 @@ +import * as React from "react" +import * as DialogPrimitive from "@radix-ui/react-dialog" +import { X } from "lucide-react" + +import { cn } from "@/lib/utils" + +const Dialog = DialogPrimitive.Root + +const DialogTrigger = DialogPrimitive.Trigger + +const DialogPortal = DialogPrimitive.Portal + +const DialogClose = DialogPrimitive.Close + +const DialogOverlay = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +DialogOverlay.displayName = DialogPrimitive.Overlay.displayName + +const DialogContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + + + {children} + + + Close + + + +)) +DialogContent.displayName = DialogPrimitive.Content.displayName + +const DialogHeader = ({ + className, + ...props +}: React.HTMLAttributes) => ( +
+) +DialogHeader.displayName = "DialogHeader" + +const DialogFooter = ({ + className, + ...props +}: React.HTMLAttributes) => ( +
+) +DialogFooter.displayName = "DialogFooter" + +const DialogTitle = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +DialogTitle.displayName = DialogPrimitive.Title.displayName + +const DialogDescription = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +DialogDescription.displayName = DialogPrimitive.Description.displayName + +export { + Dialog, + DialogPortal, + DialogOverlay, + DialogClose, + DialogTrigger, + DialogContent, + DialogHeader, + DialogFooter, + DialogTitle, + DialogDescription, +} diff --git a/src/components/ui/popover.tsx b/src/components/ui/popover.tsx new file mode 100644 index 0000000..bbba7e0 --- /dev/null +++ b/src/components/ui/popover.tsx @@ -0,0 +1,29 @@ +import * as React from "react" +import * as PopoverPrimitive from "@radix-ui/react-popover" + +import { cn } from "@/lib/utils" + +const Popover = PopoverPrimitive.Root + +const PopoverTrigger = PopoverPrimitive.Trigger + +const PopoverContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, align = "center", sideOffset = 4, ...props }, ref) => ( + + + +)) +PopoverContent.displayName = PopoverPrimitive.Content.displayName + +export { Popover, PopoverTrigger, PopoverContent } diff --git a/src/components/ui/separator.tsx b/src/components/ui/separator.tsx new file mode 100644 index 0000000..6d7f122 --- /dev/null +++ b/src/components/ui/separator.tsx @@ -0,0 +1,29 @@ +import * as React from "react" +import * as SeparatorPrimitive from "@radix-ui/react-separator" + +import { cn } from "@/lib/utils" + +const Separator = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>( + ( + { className, orientation = "horizontal", decorative = true, ...props }, + ref + ) => ( + + ) +) +Separator.displayName = SeparatorPrimitive.Root.displayName + +export { Separator } diff --git a/src/index.css b/src/index.css index b5c61c9..d924e24 100644 --- a/src/index.css +++ b/src/index.css @@ -1,3 +1,69 @@ @tailwind base; @tailwind components; @tailwind utilities; + +@layer base { + :root { + --background: 0 0% 100%; + --foreground: 222.2 84% 4.9%; + --card: 0 0% 100%; + --card-foreground: 222.2 84% 4.9%; + --popover: 0 0% 100%; + --popover-foreground: 222.2 84% 4.9%; + --primary: 222.2 47.4% 11.2%; + --primary-foreground: 210 40% 98%; + --secondary: 210 40% 96.1%; + --secondary-foreground: 222.2 47.4% 11.2%; + --muted: 210 40% 96.1%; + --muted-foreground: 215.4 16.3% 46.9%; + --accent: 210 40% 96.1%; + --accent-foreground: 222.2 47.4% 11.2%; + --destructive: 0 84.2% 60.2%; + --destructive-foreground: 210 40% 98%; + --border: 214.3 31.8% 91.4%; + --input: 214.3 31.8% 91.4%; + --ring: 222.2 84% 4.9%; + --radius: 0.5rem; + --chart-1: 12 76% 61%; + --chart-2: 173 58% 39%; + --chart-3: 197 37% 24%; + --chart-4: 43 74% 66%; + --chart-5: 27 87% 67%; + } + + .dark { + --background: 222.2 84% 4.9%; + --foreground: 210 40% 98%; + --card: 222.2 84% 4.9%; + --card-foreground: 210 40% 98%; + --popover: 222.2 84% 4.9%; + --popover-foreground: 210 40% 98%; + --primary: 210 40% 98%; + --primary-foreground: 222.2 47.4% 11.2%; + --secondary: 217.2 32.6% 17.5%; + --secondary-foreground: 210 40% 98%; + --muted: 217.2 32.6% 17.5%; + --muted-foreground: 215 20.2% 65.1%; + --accent: 217.2 32.6% 17.5%; + --accent-foreground: 210 40% 98%; + --destructive: 0 62.8% 30.6%; + --destructive-foreground: 210 40% 98%; + --border: 217.2 32.6% 17.5%; + --input: 217.2 32.6% 17.5%; + --ring: 212.7 26.8% 83.9%; + --chart-1: 220 70% 50%; + --chart-2: 160 60% 45%; + --chart-3: 30 80% 55%; + --chart-4: 280 65% 60%; + --chart-5: 340 75% 55%; + } +} + +@layer base { + * { + @apply border-border; + } + body { + @apply bg-background text-foreground; + } +} diff --git a/src/lib/utils.ts b/src/lib/utils.ts new file mode 100644 index 0000000..d084cca --- /dev/null +++ b/src/lib/utils.ts @@ -0,0 +1,6 @@ +import { type ClassValue, clsx } from "clsx" +import { twMerge } from "tailwind-merge" + +export function cn(...inputs: ClassValue[]) { + return twMerge(clsx(inputs)) +} diff --git a/tailwind.config.js b/tailwind.config.js index 0a2bad2..e51fa08 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -1,8 +1,72 @@ /** @type {import('tailwindcss').Config} */ -export default { - content: ["./src/**/*.tsx", "./index.html"], +module.exports = { + darkMode: ["class"], + content: ["./src/**/*.{ts,tsx}"], + prefix: "", theme: { - extend: {}, + container: { + center: true, + padding: "2rem", + screens: { + "2xl": "1400px", + }, + }, + extend: { + colors: { + border: "hsl(var(--border))", + input: "hsl(var(--input))", + ring: "hsl(var(--ring))", + background: "hsl(var(--background))", + foreground: "hsl(var(--foreground))", + primary: { + DEFAULT: "hsl(var(--primary))", + foreground: "hsl(var(--primary-foreground))", + }, + secondary: { + DEFAULT: "hsl(var(--secondary))", + foreground: "hsl(var(--secondary-foreground))", + }, + destructive: { + DEFAULT: "hsl(var(--destructive))", + foreground: "hsl(var(--destructive-foreground))", + }, + muted: { + DEFAULT: "hsl(var(--muted))", + foreground: "hsl(var(--muted-foreground))", + }, + accent: { + DEFAULT: "hsl(var(--accent))", + foreground: "hsl(var(--accent-foreground))", + }, + popover: { + DEFAULT: "hsl(var(--popover))", + foreground: "hsl(var(--popover-foreground))", + }, + card: { + DEFAULT: "hsl(var(--card))", + foreground: "hsl(var(--card-foreground))", + }, + }, + borderRadius: { + lg: "var(--radius)", + md: "calc(var(--radius) - 2px)", + sm: "calc(var(--radius) - 4px)", + }, + keyframes: { + "accordion-down": { + from: { height: "0" }, + to: { height: "var(--radix-accordion-content-height)" }, + }, + "accordion-up": { + from: { height: "var(--radix-accordion-content-height)" }, + to: { height: "0" }, + }, + }, + animation: { + "accordion-down": "accordion-down 0.2s ease-out", + "accordion-up": "accordion-up 0.2s ease-out", + }, + }, }, - plugins: [], -}; + plugins: [require("tailwindcss-animate")], +} From 3c27274f3580d56be94ffb3313a48b78c4686535 Mon Sep 17 00:00:00 2001 From: Carlo Sala Date: Tue, 20 Aug 2024 16:48:32 +0200 Subject: [PATCH 3/7] caca --- src/actions/delegate/ChooseChain.tsx | 20 ++++++++++++++ src/actions/delegate/ChooseDelegate.tsx | 30 +++++++++++++++++++++ src/actions/delegate/index.tsx | 9 +++++-- src/api/delegation.ts | 35 +++++++++++++++++++++++++ 4 files changed, 92 insertions(+), 2 deletions(-) create mode 100644 src/actions/delegate/ChooseChain.tsx create mode 100644 src/actions/delegate/ChooseDelegate.tsx diff --git a/src/actions/delegate/ChooseChain.tsx b/src/actions/delegate/ChooseChain.tsx new file mode 100644 index 0000000..c6e4727 --- /dev/null +++ b/src/actions/delegate/ChooseChain.tsx @@ -0,0 +1,20 @@ +import { Link } from "react-router-dom" + +const SUPPORTED_CHAINS = ["polkadot", "kusama"] + +export const ChooseChain = () => { + return ( +
+

Choose chain

+ {SUPPORTED_CHAINS.map((c) => ( + +
+

+ {c[0].toUpperCase() + c.slice(1)} +

+
+ + ))} +
+ ) +} diff --git a/src/actions/delegate/ChooseDelegate.tsx b/src/actions/delegate/ChooseDelegate.tsx new file mode 100644 index 0000000..f3f3687 --- /dev/null +++ b/src/actions/delegate/ChooseDelegate.tsx @@ -0,0 +1,30 @@ +import { Link } from "react-router-dom" + +const SUPPORTED_DELEGATES: Array<{ address: string; name: string }> = [ + { + name: "BIRDO", + address: "13EyMuuDHwtq5RD6w3psCJ9WvJFZzDDion6Fd2FVAqxz1g7K", + }, + { + name: "ChaosDAO", + address: "12s37eSMQPEN5cuVyBxk2UypUHntwumqBHy7sJkoKpZ1v3HV", + }, +] + +export const ChooseDelegate = () => { + return ( +
+

Choose delegate

+ {SUPPORTED_DELEGATES.map(({ address, name }) => ( + +
+

{name}

+
+ Address:
{address}
+
+
+ + ))} +
+ ) +} diff --git a/src/actions/delegate/index.tsx b/src/actions/delegate/index.tsx index 736a820..349d30c 100644 --- a/src/actions/delegate/index.tsx +++ b/src/actions/delegate/index.tsx @@ -1,10 +1,15 @@ -import { Route, Routes } from "react-router-dom" +import { Route, Routes, Navigate } from "react-router-dom" import { DelegateAction } from "./DelegateAction" +import { ChooseDelegate } from "./ChooseDelegate" +import { ChooseChain } from "./ChooseChain" export default function Delegate() { return ( - } /> + } /> + } /> + } /> + } /> ) } diff --git a/src/api/delegation.ts b/src/api/delegation.ts index c348c0f..83cc13d 100644 --- a/src/api/delegation.ts +++ b/src/api/delegation.ts @@ -20,6 +20,41 @@ interface Delegating { conviction: VotingConviction } +export const getTimeLock = async ( + conviction: 0 | 1 | 2 | 3 | 4 | 5 | 6, +): Promise => { + if (conviction === 0) return "No lock" + const [blockTimeSeconds, lockedBlocks] = await Promise.all([ + paseoApi.constants.Babe.ExpectedBlockTime(), + paseoApi.constants.ConvictionVoting.VoteLockingPeriod(), + ]).then(([milis, locked]) => [Number(milis / 1000n), locked]) + console.log(lockedBlocks) + const hoursToUnlock = Math.ceil( + (blockTimeSeconds * lockedBlocks * 2 ** (conviction - 1)) / 60 / 60, + ) + const hoursToPrint = hoursToUnlock % 24 + const daysToPrint = ((hoursToUnlock - hoursToPrint) / 24) % 7 + const weeksToPrint = + (hoursToUnlock - hoursToPrint - daysToPrint * 24) / 24 / 7 + let returnStr = "" + let started = false + if (weeksToPrint) { + started = true + returnStr += `${weeksToPrint} weeks` + } + if (daysToPrint) { + if (started) returnStr += `, ` + else started = true + returnStr += `${daysToPrint} days` + } + if (hoursToPrint) { + if (started) returnStr += `, ` + else started = true + returnStr += `${hoursToPrint} hours` + } + return returnStr +} + export const getTracks = async (): Promise> => Object.fromEntries( (await api.constants.Referenda.Tracks()).map(([trackId, { name }]) => [ From 99ce15a02373c3bc92f7bec2f7643c35e48bc727 Mon Sep 17 00:00:00 2001 From: Carlo Sala Date: Tue, 20 Aug 2024 20:33:13 +0200 Subject: [PATCH 4/7] validate chain --- src/actions/delegate/ChooseChain.tsx | 3 +-- src/actions/delegate/ChooseDelegate.tsx | 33 +++++++++++++++++++------ src/actions/delegate/DelegateAction.tsx | 20 ++++----------- src/actions/delegate/delegate.ts | 6 ++--- src/actions/delegate/utils.ts | 13 ++++++++++ 5 files changed, 46 insertions(+), 29 deletions(-) create mode 100644 src/actions/delegate/utils.ts diff --git a/src/actions/delegate/ChooseChain.tsx b/src/actions/delegate/ChooseChain.tsx index c6e4727..7747679 100644 --- a/src/actions/delegate/ChooseChain.tsx +++ b/src/actions/delegate/ChooseChain.tsx @@ -1,6 +1,5 @@ import { Link } from "react-router-dom" - -const SUPPORTED_CHAINS = ["polkadot", "kusama"] +import { SUPPORTED_CHAINS } from "./utils" export const ChooseChain = () => { return ( diff --git a/src/actions/delegate/ChooseDelegate.tsx b/src/actions/delegate/ChooseDelegate.tsx index f3f3687..8be9eb5 100644 --- a/src/actions/delegate/ChooseDelegate.tsx +++ b/src/actions/delegate/ChooseDelegate.tsx @@ -1,4 +1,7 @@ +import { useStateObservable } from "@react-rxjs/core" import { Link } from "react-router-dom" +import { routeChain$ } from "./delegate" +import { isChainValid } from "./utils" const SUPPORTED_DELEGATES: Array<{ address: string; name: string }> = [ { @@ -12,19 +15,33 @@ const SUPPORTED_DELEGATES: Array<{ address: string; name: string }> = [ ] export const ChooseDelegate = () => { + const chainData = useStateObservable(routeChain$) return (
-

Choose delegate

- {SUPPORTED_DELEGATES.map(({ address, name }) => ( - + {isChainValid(chainData ?? "") ? ( + <> +

Choose delegate

+ {SUPPORTED_DELEGATES.map(({ address, name }) => ( + +
+

{name}

+
+ Address:
{address}
+
+
+ + ))} + + ) : ( + +

Chain not supported.

-

{name}

-
- Address:
{address}
-
+

+ Click here to choose chain +

- ))} + )}
) } diff --git a/src/actions/delegate/DelegateAction.tsx b/src/actions/delegate/DelegateAction.tsx index e232dd2..d614aef 100644 --- a/src/actions/delegate/DelegateAction.tsx +++ b/src/actions/delegate/DelegateAction.tsx @@ -5,18 +5,8 @@ import { SUSPENSE, useStateObservable, } from "@react-rxjs/core" -import { routeChain$, delegateAccount$ } from "./delegate" -import { - combineLatest, - concat, - defer, - EMPTY, - from, - map, - startWith, - switchMap, - take, -} from "rxjs" +import { routeChain$, routeDelegateAccount$ } from "./delegate" +import { combineLatest, concat, defer, EMPTY, from, map, take } from "rxjs" import { createSignal, switchMapSuspended } from "@react-rxjs/utils" import { getOptimalAmount, getTracks } from "@/api/delegation" import { SS58String } from "polkadot-api" @@ -32,7 +22,7 @@ const optimalAmount$ = state((account: SS58String) => from(getOptimalAmount(account)), ) const amount$ = state( - combineLatest(routeChain$, delegateAccount$, selectedAccount$).pipe( + combineLatest([routeChain$, routeDelegateAccount$, selectedAccount$]).pipe( switchMapSuspended(([, , account]) => { if (!account) return EMPTY return concat( @@ -83,7 +73,7 @@ const [convictionInput$, onConvictionInputChanges] = createSignal< >() const conviction$: StateObservable<0 | 1 | 2 | 3 | 4 | 5 | 6 | SUSPENSE> = state( - combineLatest(routeChain$, delegateAccount$, selectedAccount$).pipe( + combineLatest([routeChain$, routeDelegateAccount$, selectedAccount$]).pipe( switchMapSuspended(([, , account]) => { if (!account) return EMPTY return concat( @@ -133,7 +123,7 @@ const SelectTracks: React.FC = () => { export const DelegateAction = () => { const chainData = useStateObservable(routeChain$) - const delegateAccount = useStateObservable(delegateAccount$) + const delegateAccount = useStateObservable(routeDelegateAccount$) const [selectedFrameworks, setSelectedFrameworks] = useState([ "react", "angular", diff --git a/src/actions/delegate/delegate.ts b/src/actions/delegate/delegate.ts index 695bd8f..11b982f 100644 --- a/src/actions/delegate/delegate.ts +++ b/src/actions/delegate/delegate.ts @@ -9,14 +9,12 @@ export const routeChain$ = state( routeMatch$(PATTERN_CHAIN).pipe( map((routeData) => routeData?.params?.chain ?? null), ), - null, ) routeChain$.subscribe() -export const delegateAccount$ = state( +export const routeDelegateAccount$ = state( routeMatch$(PATTERN_ACCOUNT).pipe( map((routeData) => routeData?.params?.account ?? null), ), - null, ) -delegateAccount$.subscribe() +routeDelegateAccount$.subscribe() diff --git a/src/actions/delegate/utils.ts b/src/actions/delegate/utils.ts new file mode 100644 index 0000000..05e542e --- /dev/null +++ b/src/actions/delegate/utils.ts @@ -0,0 +1,13 @@ +import { getSs58AddressInfo } from "polkadot-api" + +export const SUPPORTED_CHAINS = ["polkadot", "kusama"] + +export const isChainValid = (chain: string) => SUPPORTED_CHAINS.includes(chain) + +export const isAddressValid = (addr: string) => { + try { + return getSs58AddressInfo(addr).isValid + } catch { + return false + } +} From cf4a04f2abe19ef5926299db01a0373628cfd353 Mon Sep 17 00:00:00 2001 From: Carlo Sala Date: Wed, 21 Aug 2024 11:18:54 +0200 Subject: [PATCH 5/7] get identity name --- src/api/delegation.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/api/delegation.ts b/src/api/delegation.ts index 83cc13d..a8af3b3 100644 --- a/src/api/delegation.ts +++ b/src/api/delegation.ts @@ -1,5 +1,5 @@ -import { SS58String } from "polkadot-api" -import { polkadotApi as api } from "./" +import { Binary, SS58String } from "polkadot-api" +import { polkadotApi as api, polkadotPeopleApi } from "./" import { MultiAddress, VotingConviction } from "@polkadot-api/descriptors" export const getOptimalAmount = async ( @@ -96,6 +96,12 @@ const getTrackInfo = async ( ) } +export const getAddressName = async (addr: string): Promise => { + const id = await polkadotPeopleApi.query.Identity.IdentityOf.getValue(addr) + if (id == null || id[0].info.display.value == null) return addr + return id[0].info.display.value.asText() +} + export const delegate = async ( from: SS58String, target: SS58String, From 95e8318263f8e209bf0490386e018615b3b04192 Mon Sep 17 00:00:00 2001 From: Josep M Sobrepere Date: Wed, 21 Aug 2024 11:28:44 +0200 Subject: [PATCH 6/7] WiP --- src/actions/delegate/DelegateAction.tsx | 235 ++++++++++++++++++------ src/actions/delegate/FeesAndSubmit.tsx | 184 +++++++++++++++++++ src/api/delegation.ts | 79 ++++---- src/components/multi-select.tsx | 17 +- src/lib/utils.ts | 88 +++++++++ 5 files changed, 492 insertions(+), 111 deletions(-) create mode 100644 src/actions/delegate/FeesAndSubmit.tsx diff --git a/src/actions/delegate/DelegateAction.tsx b/src/actions/delegate/DelegateAction.tsx index e232dd2..2c333e8 100644 --- a/src/actions/delegate/DelegateAction.tsx +++ b/src/actions/delegate/DelegateAction.tsx @@ -13,18 +13,27 @@ import { EMPTY, from, map, - startWith, + of, switchMap, take, } from "rxjs" import { createSignal, switchMapSuspended } from "@react-rxjs/utils" -import { getOptimalAmount, getTracks } from "@/api/delegation" +import { + delegate, + getMaxDelegation, + getOptimalAmount, + getTimeLocks, + getTrackInfo, + getTracks, +} from "@/api/delegation" import { SS58String } from "polkadot-api" import { selectedAccount$ } from "@/services/accounts" import { TokenInput } from "@/components/TokenInput" import { VotingConviction } from "@polkadot-api/descriptors" import { MultiSelect } from "@/components/multi-select" -import { useState } from "react" +import { FeesAndSubmit } from "./FeesAndSubmit" +import { shortStr } from "@/lib/utils" +import { Button } from "@/components/ui/button" const [amountInput$, onAmountChange] = createSignal() @@ -32,7 +41,7 @@ const optimalAmount$ = state((account: SS58String) => from(getOptimalAmount(account)), ) const amount$ = state( - combineLatest(routeChain$, delegateAccount$, selectedAccount$).pipe( + combineLatest([routeChain$, delegateAccount$, selectedAccount$]).pipe( switchMapSuspended(([, , account]) => { if (!account) return EMPTY return concat( @@ -46,17 +55,34 @@ const amount$ = state( ), ) +const maxDelegation$ = selectedAccount$.pipeState( + switchMap((account) => (account ? getMaxDelegation(account.address) : EMPTY)), +) + const AmountInput: React.FC = () => { const amount = useStateObservable(amount$) + const freeBalance = useStateObservable(maxDelegation$) return ( - + <> +

Amount to delegate:

+
+ + +
+ ) } @@ -70,14 +96,6 @@ const convictionVotes: Array = [ "Locked6x", ] -const frameworksList = [ - { value: "react", label: "React" }, - { value: "angular", label: "Angular" }, - { value: "vue", label: "Vue" }, - { value: "svelte", label: "Svelte" }, - { value: "ember", label: "Ember" }, -] - const [convictionInput$, onConvictionInputChanges] = createSignal< 0 | 1 | 2 | 3 | 4 | 5 | 6 >() @@ -97,26 +115,29 @@ const conviction$: StateObservable<0 | 1 | 2 | 3 | 4 | 5 | 6 | SUSPENSE> = ), ) +const convictions$ = state(defer(getTimeLocks)) const ConvictionInput: React.FC = () => { + const convictions = useStateObservable(convictions$) const conviction = useStateObservable(conviction$) return ( <> - {Array(7) - .fill(null) - .map((_, idx) => ( - - ))} +

Conviction:

+ {convictions.map((convictionLabel, idx) => ( + + ))} ) } @@ -126,43 +147,139 @@ const tracks$ = state( map((x) => Object.entries(x).map(([value, label]) => ({ value, label }))), ), ) +const [selectedTrackInput$, onChangeSelectedTrack] = + createSignal>() const SelectTracks: React.FC = () => { const tracks = useStateObservable(tracks$) + return ( + <> +

Tracks to delegate:

+ x.value)} + placeholder="Select tracks" + variant="inverted" + animation={2} + maxCount={3} + /> + + ) +} + +const delegateInput$ = state( + combineLatest([ + selectedAccount$, + delegateAccount$, + conviction$.pipe(map((x) => (x === SUSPENSE ? null : x))), + amount$.pipe(map((x) => (x === SUSPENSE ? null : x))), + concat( + tracks$.pipe( + map((x) => x.map((y) => y.value)), + take(1), + ), + selectedTrackInput$, + ).pipe(map((x) => x.map((y) => parseInt(y, 10)))), + ]).pipe( + map(([selectedAccount, delegateAccount, conviction, amount, tracks]) => { + return !selectedAccount || + !delegateAccount || + conviction == null || + amount == null + ? null + : ([ + selectedAccount.address, + delegateAccount, + conviction, + amount, + tracks, + ] as const) + }), + switchMap((x) => { + if (x === null) return of(null) + const [from, target, conviction, amount, tracks] = x + return concat( + of(null), + delegate(from, target, convictionVotes[conviction], amount, tracks), + ) + }), + ), + null, +) + +const Delegate: React.FC = () => { + const tx = useStateObservable(delegateInput$) + const selectedAccount = useStateObservable(selectedAccount$)! + return ( + + Delegate + + ) +} + +const warnings$ = selectedAccount$.pipeState( + switchMap((account) => (account ? getTrackInfo(account.address) : of({}))), + map((record) => { + const undelegations: Record = {} + const votesRemoved: Array = [] + Object.entries(record).forEach(([trackId, action]) => { + if (action.type === "Casting") { + votesRemoved.push(...action.referendums) + } else { + const arr = undelegations[action.target] ?? [] + arr.push(Number(trackId)) + undelegations[action.target] = arr + } + }) + + Object.values(undelegations).forEach((x) => x.sort((a, b) => a - b)) + votesRemoved.sort((a, b) => a - b) + + return { undelegations, votesRemoved } + }), +) + +const Warnings: React.FC = () => { + const { undelegations, votesRemoved } = useStateObservable(warnings$) + return ( + <> + {Object.entries(undelegations).map(([address, tracks]) => ( +
+ You will stop delegating to {shortStr(4, address)} on the following + tracks: {tracks.join(", ")}. +
+ ))} + {votesRemoved.length > 0 ? ( +
+ Your votes on the following referendas will be removed:{" "} + {votesRemoved.join(", ")}. +
+ ) : null} + + ) } export const DelegateAction = () => { const chainData = useStateObservable(routeChain$) const delegateAccount = useStateObservable(delegateAccount$) - const [selectedFrameworks, setSelectedFrameworks] = useState([ - "react", - "angular", - ]) - return (
-

Delegate

+

+ Delegate on {chainData} to {delegateAccount} +

-

H2 INFO

-
- Chain:
{chainData ?? "NOT DEFINED"}
-
-
- Delegate Account: -
{delegateAccount ?? "NOT DEFINED"}
-
Loading...
}> - + + +
diff --git a/src/actions/delegate/FeesAndSubmit.tsx b/src/actions/delegate/FeesAndSubmit.tsx new file mode 100644 index 0000000..fd66f56 --- /dev/null +++ b/src/actions/delegate/FeesAndSubmit.tsx @@ -0,0 +1,184 @@ +import { + Dialog, + DialogContent, + DialogDescription, + DialogTitle, + DialogTrigger, +} from "@/components/ui/dialog" +import { Button } from "@/components/ui/button" +import { PolkadotSigner, Transaction } from "polkadot-api" +import React, { + MutableRefObject, + PropsWithChildren, + useEffect, + useRef, + useState, +} from "react" +import { cn, formatCurrency, shortStr } from "@/lib/utils" +import { InjectedPolkadotAccount } from "polkadot-api/pjs-signer" + +const FormattedToken: React.FC<{ + ticker: string + decimals: number + value: bigint | null +}> = ({ ticker, decimals, value }) => { + return ( + <> + {value === null + ? "Loading..." + : formatCurrency(value, decimals, { + nDecimals: 4, + }) + + " " + + ticker} + + ) +} + +const SubmitDialog: React.FC< + PropsWithChildren<{ + signer: PolkadotSigner + signSubmitAndWatch: MutableRefObject< + Transaction["signSubmitAndWatch"] | undefined + > + }> +> = ({ signer, signSubmitAndWatch, children }) => { + const [dialogText, setDialogText] = useState() + const [openDialog, setOpenDialog] = useState(false) + return ( + + + + + + {children} + {dialogText} + + + ) +} + +export const FeesAndSubmit: React.FC< + PropsWithChildren<{ + txCall: Transaction | null + account: InjectedPolkadotAccount + decimals: number + ticker: string + }> +> = ({ decimals, ticker, account, txCall, children }) => { + const [fees, setFees] = useState() + const signSubmitAndWatch = + useRef["signSubmitAndWatch"]>() + + useEffect(() => { + if (!txCall) return + let token: any = setTimeout(() => { + signSubmitAndWatch.current = txCall.signSubmitAndWatch + txCall.getEstimatedFees(account.address).then((fees) => { + if (token) setFees(fees) + }) + }, 50) + + return () => { + signSubmitAndWatch.current = undefined + clearTimeout(token) + token = null + } + }, [txCall]) + + return ( + <> +
    +
  • + + Estimated fees + + + {fees ? ( + + ) : ( + txCall && "Loading" + )} + +
  • +
+ + {children} + + + ) +} diff --git a/src/api/delegation.ts b/src/api/delegation.ts index 83cc13d..f6a7a2b 100644 --- a/src/api/delegation.ts +++ b/src/api/delegation.ts @@ -1,4 +1,4 @@ -import { SS58String } from "polkadot-api" +import { Enum, SS58String } from "polkadot-api" import { polkadotApi as api } from "./" import { MultiAddress, VotingConviction } from "@polkadot-api/descriptors" @@ -20,39 +20,41 @@ interface Delegating { conviction: VotingConviction } -export const getTimeLock = async ( - conviction: 0 | 1 | 2 | 3 | 4 | 5 | 6, -): Promise => { - if (conviction === 0) return "No lock" +export const getTimeLocks = async (): Promise => { const [blockTimeSeconds, lockedBlocks] = await Promise.all([ - paseoApi.constants.Babe.ExpectedBlockTime(), - paseoApi.constants.ConvictionVoting.VoteLockingPeriod(), + api.constants.Babe.ExpectedBlockTime(), + api.constants.ConvictionVoting.VoteLockingPeriod(), ]).then(([milis, locked]) => [Number(milis / 1000n), locked]) - console.log(lockedBlocks) - const hoursToUnlock = Math.ceil( - (blockTimeSeconds * lockedBlocks * 2 ** (conviction - 1)) / 60 / 60, - ) - const hoursToPrint = hoursToUnlock % 24 - const daysToPrint = ((hoursToUnlock - hoursToPrint) / 24) % 7 - const weeksToPrint = - (hoursToUnlock - hoursToPrint - daysToPrint * 24) / 24 / 7 - let returnStr = "" - let started = false - if (weeksToPrint) { - started = true - returnStr += `${weeksToPrint} weeks` - } - if (daysToPrint) { - if (started) returnStr += `, ` - else started = true - returnStr += `${daysToPrint} days` - } - if (hoursToPrint) { - if (started) returnStr += `, ` - else started = true - returnStr += `${hoursToPrint} hours` - } - return returnStr + + return Array(7) + .fill(null) + .map((_, conviction) => { + if (conviction === 0) return "No lock" + const hoursToUnlock = Math.ceil( + (blockTimeSeconds * lockedBlocks * 2 ** (conviction - 1)) / 60 / 60, + ) + const hoursToPrint = hoursToUnlock % 24 + const daysToPrint = ((hoursToUnlock - hoursToPrint) / 24) % 7 + const weeksToPrint = + (hoursToUnlock - hoursToPrint - daysToPrint * 24) / 24 / 7 + let returnStr = "" + let started = false + if (weeksToPrint) { + started = true + returnStr += `${weeksToPrint} week${weeksToPrint > 1 ? "s" : ""}` + } + if (daysToPrint) { + if (started) returnStr += `, ` + else started = true + returnStr += `${daysToPrint} days` + } + if (hoursToPrint) { + if (started) returnStr += `, ` + else started = true + returnStr += `${hoursToPrint} hours` + } + return returnStr + }) } export const getTracks = async (): Promise> => @@ -66,7 +68,7 @@ export const getTracks = async (): Promise> => ]), ) -const getTrackInfo = async ( +export const getTrackInfo = async ( address: SS58String, ): Promise> => { const convictionVoting = @@ -99,7 +101,7 @@ const getTrackInfo = async ( export const delegate = async ( from: SS58String, target: SS58String, - conviction: VotingConviction, + conviction: VotingConviction["type"], amount: bigint, tracks: Array, ) => { @@ -117,7 +119,7 @@ export const delegate = async ( if ( trackInfo.type === "Delegating" && trackInfo.target === target && - conviction.type === trackInfo.conviction.type && + conviction === trackInfo.conviction.type && amount === trackInfo.amount ) return @@ -142,7 +144,7 @@ export const delegate = async ( txs.push( api.tx.ConvictionVoting.delegate({ class: trackId, - conviction, + conviction: Enum(conviction), to: MultiAddress.Id(target), balance: amount, }), @@ -153,3 +155,8 @@ export const delegate = async ( calls: txs.map((tx) => tx.decodedCall), }) } + +export const getMaxDelegation = async (from: SS58String) => { + const { data: account } = await api.query.System.Account.getValue(from) + return account.free + account.reserved +} diff --git a/src/components/multi-select.tsx b/src/components/multi-select.tsx index ca6fabc..4a73deb 100644 --- a/src/components/multi-select.tsx +++ b/src/components/multi-select.tsx @@ -1,12 +1,6 @@ import * as React from "react" import { cva, type VariantProps } from "class-variance-authority" -import { - CheckIcon, - XCircle, - ChevronDown, - XIcon, - WandSparkles, -} from "lucide-react" +import { CheckIcon, XCircle, ChevronDown, XIcon } from "lucide-react" import { cn } from "@/lib/utils" import { Separator } from "@/components/ui/separator" @@ -366,15 +360,6 @@ export const MultiSelect = React.forwardRef< - {animation > 0 && selectedValues.length > 0 && ( - setIsAnimating(!isAnimating)} - /> - )} ) }, diff --git a/src/lib/utils.ts b/src/lib/utils.ts index d084cca..64921c0 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -4,3 +4,91 @@ import { twMerge } from "tailwind-merge" export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)) } + +export const decimalSeparatorDisplay = "." +export const decimalSeparatorsInput = [".", ","] +export const decimalSeparatorRegex = ",|." + +export const getDecimalSeparator = (inputString: string) => { + const parts = new RegExp( + `^(-)?(\\d*)(${decimalSeparatorRegex})?((\\d+))?$`, + ).exec(inputString) + + return parts ? parts[3] : null +} + +export type FormatCurrencyOptions = { + nDecimals: number + padToDecimals: boolean + decimalSeparator: string +} + +const defaultOptions: FormatCurrencyOptions = { + nDecimals: Infinity, + padToDecimals: true, + decimalSeparator: decimalSeparatorDisplay, +} + +export const formatCurrency = ( + value: bigint | null, + precision: number, + options: Partial = {}, +): string => { + const { nDecimals, padToDecimals, decimalSeparator } = { + ...defaultOptions, + ...options, + } + if (value === null) return "" + const precisionMultiplier = 10n ** BigInt(precision) + if (nDecimals < precision) { + value = value / 10n ** BigInt(precision - (nDecimals + 1)) + const rounded = Math.abs(Number(value % 10n)) > 4 + const rounding = rounded ? (value < 0 ? -1n : 1n) : 0n + value = value / 10n + rounding + value *= 10n ** BigInt(precision - nDecimals) + } + const isNegative = value < 0n + const absValue = isNegative ? value * -1n : value + let intPartStr = (absValue / precisionMultiplier).toString() + if (isNegative) intPartStr = "-" + intPartStr + const decimalPart = absValue % precisionMultiplier + + if ( + nDecimals === 0 || + (nDecimals === Infinity && decimalPart === 0n) || + (padToDecimals === false && decimalPart === 0n) + ) + return intPartStr + + let newDecimalPart = decimalPart + .toString() + .padStart(precision, "0") + .replace(/00*$/, "") + + if (nDecimals !== Infinity && padToDecimals === true) { + newDecimalPart = newDecimalPart.padEnd(nDecimals, "0") + } + + return intPartStr + decimalSeparator + newDecimalPart +} + +type BigNumber = { + value: bigint + precision: bigint +} + +export const divideBigInt = ( + numerator: BigNumber, + denominator: BigNumber, + targetPrecision?: bigint, +) => { + const precision = targetPrecision ?? numerator.precision + return ( + (10n ** precision * (numerator.value * 10n ** denominator.precision)) / + denominator.value / + 10n ** numerator.precision + ) +} + +export const shortStr = (nChars: number, str: string) => + str.slice(0, nChars) + "..." + str.slice(-nChars) From 4ee494ebb4336cedcfefecc72cdcb1fea2263842 Mon Sep 17 00:00:00 2001 From: Carlo Sala Date: Wed, 21 Aug 2024 11:49:50 +0200 Subject: [PATCH 7/7] fix stuff --- src/actions/delegate/DelegateAction.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/actions/delegate/DelegateAction.tsx b/src/actions/delegate/DelegateAction.tsx index a67cf5d..787292b 100644 --- a/src/actions/delegate/DelegateAction.tsx +++ b/src/actions/delegate/DelegateAction.tsx @@ -5,7 +5,7 @@ import { SUSPENSE, useStateObservable, } from "@react-rxjs/core" -import { routeChain$, delegateAccount$ } from "./delegate" +import { routeChain$, routeDelegateAccount$ } from "./delegate" import { combineLatest, concat, @@ -41,7 +41,7 @@ const optimalAmount$ = state((account: SS58String) => from(getOptimalAmount(account)), ) const amount$ = state( - combineLatest([routeChain$, delegateAccount$, selectedAccount$]).pipe( + combineLatest([routeChain$, routeDelegateAccount$, selectedAccount$]).pipe( switchMapSuspended(([, , account]) => { if (!account) return EMPTY return concat( @@ -171,7 +171,7 @@ const SelectTracks: React.FC = () => { const delegateInput$ = state( combineLatest([ selectedAccount$, - delegateAccount$, + routeDelegateAccount$, conviction$.pipe(map((x) => (x === SUSPENSE ? null : x))), amount$.pipe(map((x) => (x === SUSPENSE ? null : x))), concat( @@ -267,7 +267,7 @@ const Warnings: React.FC = () => { export const DelegateAction = () => { const chainData = useStateObservable(routeChain$) - const delegateAccount = useStateObservable(delegateAccount$) + const delegateAccount = useStateObservable(routeDelegateAccount$) return (