From 9acdd3479402a79db1ff311baa484abce80b8033 Mon Sep 17 00:00:00 2001 From: Anirudh Ramchandran Date: Tue, 13 Aug 2024 11:19:25 -0600 Subject: [PATCH 01/61] Anirud/front end UI changes (#21) * change font and app name * remove dropdown from theme toggle button * add shadow effects on hover * fix :@import must precede all other statements * create and use common theme class for navbar * add help sidebar component : - opens and closes on clicking help icon on navbar - inital jsx for component * break down model selection component into multiple components * add more common themes * update help component * Add more on hover effects for buttons - on hover change button color from grey to white * add TT font * add model name * more fixes * more fixes to chatui - break long texts - some theme providers * add menu bar shadcnn component * shadcnn menu bar component * send model name to chatui component * make navbar vertical in chat ui mode * add breadcumbs links on chat ui page * ensure mode name is being sent to chat page for display * Ui color fixes for main page footer * make default theme as dark mode * clean up * fix help sidebar to appear on whole page * update package lock json to fix: - ETIMEDOUT errors --------- Co-authored-by: Tom Stesco --- app/frontend/package-lock.json | 2255 ++++++++++------- app/frontend/package.json | 4 +- app/frontend/src/api/modelsDeployedApis.ts | 9 +- .../src/assets/tt_line_graphics_1.png | Bin 0 -> 73254 bytes app/frontend/src/components/ChatComponent.tsx | 98 +- .../src/components/DarkModeToggle.tsx | 59 +- .../src/components/DeployModelStep.tsx | 32 + app/frontend/src/components/FirstStepForm.tsx | 136 + app/frontend/src/components/HelpIcon.tsx | 8 +- .../src/components/ModelsDeployedTable.tsx | 4 +- app/frontend/src/components/NavBar.tsx | 182 +- .../src/components/SecondStepForm.tsx | 131 + .../src/components/SelectionSteps.tsx | 510 +--- app/frontend/src/components/SideBar.tsx | 84 + app/frontend/src/components/StepperFooter.tsx | 45 + .../src/components/StepperFormActions.tsx | 73 + app/frontend/src/components/WeightForm.tsx | 143 ++ .../src/components/ui/aspect-ratio.tsx | 5 + app/frontend/src/components/ui/breadcrumb.tsx | 118 + app/frontend/src/components/ui/button.tsx | 15 +- app/frontend/src/components/ui/menubar.tsx | 234 ++ app/frontend/src/fonts/Akkurat-Mono.OTF | Bin 0 -> 20516 bytes app/frontend/src/index.css | 7 + app/frontend/src/pages/HomePage.tsx | 4 - app/frontend/src/providers/ThemeProvider.tsx | 7 +- app/frontend/src/theme/commonThemeClasses.tsx | 64 + app/frontend/tailwind.config.js | 2 + 27 files changed, 2648 insertions(+), 1581 deletions(-) create mode 100644 app/frontend/src/assets/tt_line_graphics_1.png create mode 100644 app/frontend/src/components/DeployModelStep.tsx create mode 100644 app/frontend/src/components/FirstStepForm.tsx create mode 100644 app/frontend/src/components/SecondStepForm.tsx create mode 100644 app/frontend/src/components/SideBar.tsx create mode 100644 app/frontend/src/components/StepperFooter.tsx create mode 100644 app/frontend/src/components/StepperFormActions.tsx create mode 100644 app/frontend/src/components/WeightForm.tsx create mode 100644 app/frontend/src/components/ui/aspect-ratio.tsx create mode 100644 app/frontend/src/components/ui/breadcrumb.tsx create mode 100644 app/frontend/src/components/ui/menubar.tsx create mode 100644 app/frontend/src/fonts/Akkurat-Mono.OTF create mode 100644 app/frontend/src/theme/commonThemeClasses.tsx diff --git a/app/frontend/package-lock.json b/app/frontend/package-lock.json index bbccd811..3a4c6ccc 100644 --- a/app/frontend/package-lock.json +++ b/app/frontend/package-lock.json @@ -9,18 +9,20 @@ "version": "0.0.0", "dependencies": { "@hookform/resolvers": "^3.3.4", + "@radix-ui/react-aspect-ratio": "^1.1.0", "@radix-ui/react-collapsible": "^1.0.3", "@radix-ui/react-dialog": "^1.0.5", "@radix-ui/react-dropdown-menu": "^2.0.6", "@radix-ui/react-icons": "^1.3.0", "@radix-ui/react-label": "^2.0.2", + "@radix-ui/react-menubar": "^1.1.1", "@radix-ui/react-navigation-menu": "^1.1.4", "@radix-ui/react-popover": "^1.0.7", "@radix-ui/react-progress": "^1.0.3", "@radix-ui/react-scroll-area": "^1.0.5", "@radix-ui/react-select": "^2.0.0", "@radix-ui/react-separator": "^1.0.3", - "@radix-ui/react-slot": "^1.0.2", + "@radix-ui/react-slot": "^1.1.0", "@radix-ui/react-tooltip": "^1.0.7", "@tanstack/react-query": "^5.35.1", "axios": "^1.6.8", @@ -70,9 +72,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.5.tgz", - "integrity": "sha512-Nms86NXrsaeU9vbBJKni6gXiEXZ4CVpYVzEjDH9Sb8vmZ3UljyA1GSOJl/6LGPO8EHLuSF9H+IxNXHPX8QHJ4g==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.8.tgz", + "integrity": "sha512-5F7SDGs1T72ZczbRwbGO9lQi0NLjQxzl6i4lJxLxfW9U5UluCSyEJeniWvnhl3/euNiqQVbo8zruhsDfid0esA==", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -99,9 +101,9 @@ "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==" }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", - "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", "cpu": [ "ppc64" ], @@ -115,9 +117,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz", - "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", "cpu": [ "arm" ], @@ -131,9 +133,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", - "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", "cpu": [ "arm64" ], @@ -147,9 +149,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz", - "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", "cpu": [ "x64" ], @@ -163,9 +165,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", - "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", "cpu": [ "arm64" ], @@ -179,9 +181,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", - "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", "cpu": [ "x64" ], @@ -195,9 +197,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", - "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", "cpu": [ "arm64" ], @@ -211,9 +213,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", - "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", "cpu": [ "x64" ], @@ -227,9 +229,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", - "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", "cpu": [ "arm" ], @@ -243,9 +245,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", - "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", "cpu": [ "arm64" ], @@ -259,9 +261,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", - "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", "cpu": [ "ia32" ], @@ -275,9 +277,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", - "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", "cpu": [ "loong64" ], @@ -291,9 +293,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", - "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", "cpu": [ "mips64el" ], @@ -307,9 +309,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", - "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", "cpu": [ "ppc64" ], @@ -323,9 +325,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", - "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", "cpu": [ "riscv64" ], @@ -339,9 +341,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", - "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", "cpu": [ "s390x" ], @@ -355,9 +357,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", - "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", "cpu": [ "x64" ], @@ -371,9 +373,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", - "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", "cpu": [ "x64" ], @@ -387,9 +389,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", - "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", "cpu": [ "x64" ], @@ -403,9 +405,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", - "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", "cpu": [ "x64" ], @@ -419,9 +421,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", - "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", "cpu": [ "arm64" ], @@ -435,9 +437,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", - "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", "cpu": [ "ia32" ], @@ -451,9 +453,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", - "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", "cpu": [ "x64" ], @@ -482,9 +484,9 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", - "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", + "version": "4.11.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", + "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", "dev": true, "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" @@ -545,26 +547,26 @@ } }, "node_modules/@floating-ui/core": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.1.tgz", - "integrity": "sha512-42UH54oPZHPdRHdw6BgoBD6cg/eVTmVrFcgeRDM3jbO7uxSoipVcmcIGFcA5jmOHO5apcyvBhkSKES3fQJnu7A==", + "version": "1.6.5", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.5.tgz", + "integrity": "sha512-8GrTWmoFhm5BsMZOTHeGD2/0FLKLQQHvO/ZmQga4tKempYRLz8aqJGqXVuQgisnMObq2YZ2SgkwctN1LOOxcqA==", "dependencies": { - "@floating-ui/utils": "^0.2.0" + "@floating-ui/utils": "^0.2.5" } }, "node_modules/@floating-ui/dom": { - "version": "1.6.4", - "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.4.tgz", - "integrity": "sha512-0G8R+zOvQsAG1pg2Q99P21jiqxqGBW1iRe/iXHsBRBxnpXKFI8QwbB4x5KmYLggNO5m34IQgOIu9SCRfR/WWiQ==", + "version": "1.6.8", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.8.tgz", + "integrity": "sha512-kx62rP19VZ767Q653wsP1XZCGIirkE09E0QUGNYTM/ttbbQHqcGPdSfWFxUyyNLc/W6aoJRBajOSXhP6GXjC0Q==", "dependencies": { - "@floating-ui/core": "^1.0.0", - "@floating-ui/utils": "^0.2.0" + "@floating-ui/core": "^1.6.0", + "@floating-ui/utils": "^0.2.5" } }, "node_modules/@floating-ui/react-dom": { - "version": "2.0.9", - "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.0.9.tgz", - "integrity": "sha512-q0umO0+LQK4+p6aGyvzASqKbKOJcAHJ7ycE9CuUvfx3s9zTHWmGJTPOIlM/hmSBfUfg/XfY5YhLBLR/LHwShQQ==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.1.tgz", + "integrity": "sha512-4h84MJt3CHrtG18mGsXuLCHMrug49d7DFkU0RMIyshRveBeyV2hmV/pDaF2Uxtu8kgq5r46llp5E5FQiR0K2Yg==", "dependencies": { "@floating-ui/dom": "^1.0.0" }, @@ -574,14 +576,14 @@ } }, "node_modules/@floating-ui/utils": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.2.tgz", - "integrity": "sha512-J4yDIIthosAsRZ5CPYP/jQvUAQtlZTTD/4suA08/FEnlxqW3sKS9iAhgsa9VYLZ6vDHn/ixJgIqRQPotoBjxIw==" + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.5.tgz", + "integrity": "sha512-sTcG+QZ6fdEUObICavU+aB3Mp8HY4n14wYHdxK4fXjPmv3PXZZeY5RaguJmGyeH/CJQhX3fqKUtS4qc1LoHwhQ==" }, "node_modules/@hookform/resolvers": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-3.3.4.tgz", - "integrity": "sha512-o5cgpGOuJYrd+iMKvkttOclgwRW86EsWJZZRC23prf0uU2i48Htq4PuT73AVb9ionFyZrwYEITuOFGF+BydEtQ==", + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-3.9.0.tgz", + "integrity": "sha512-bU0Gr4EepJ/EQsH/IwEzYLsT/PEj5C0ynLQ4m+GSHS+xKH4TfSelhluTgOaoc4kA5s7eCsQbM4wvZLzELmWzUg==", "peerDependencies": { "react-hook-form": "^7.0.0" } @@ -590,6 +592,7 @@ "version": "0.11.14", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "deprecated": "Use @eslint/config-array instead", "dev": true, "dependencies": { "@humanwhocodes/object-schema": "^2.0.2", @@ -639,6 +642,7 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead", "dev": true }, "node_modules/@isaacs/cliui": { @@ -712,9 +716,9 @@ } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.25", @@ -767,34 +771,49 @@ } }, "node_modules/@radix-ui/number": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.0.1.tgz", - "integrity": "sha512-T5gIdVO2mmPW3NNhjNgEP3cqMXjXL9UbO0BzWcXfvdBs+BohbQxvd/K5hSVKmn9/lbTdsQVKbUcP5WLCwvUbBg==", - "dependencies": { - "@babel/runtime": "^7.13.10" - } + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.0.tgz", + "integrity": "sha512-V3gRzhVNU1ldS5XhAPTom1fOIo4ccrjjJgmE+LI2h/WaFpHmx0MQApT+KZHnx8abG6Avtfcz4WoEciMnpFT3HQ==" }, "node_modules/@radix-ui/primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.0.1.tgz", - "integrity": "sha512-yQ8oGX2GVsEYMWGxcovu1uGWPCxV5BFfeeYxqPmuAzUyLT9qmaMXSAhXpb0WrspIeqYzdJpkh2vHModJPgRIaw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.0.tgz", + "integrity": "sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==" + }, + "node_modules/@radix-ui/react-arrow": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.0.tgz", + "integrity": "sha512-FmlW1rCg7hBpEBwFbjHwCW6AmWLQM6g/v0Sn8XbP9NvmSZ2San1FpQeyPtufzOMSIx7Y4dzjlHoifhp+7NkZhw==", "dependencies": { - "@babel/runtime": "^7.13.10" + "@radix-ui/react-primitive": "2.0.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } } }, - "node_modules/@radix-ui/react-arrow": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.0.3.tgz", - "integrity": "sha512-wSP+pHsB/jQRaL6voubsQ/ZlrGBHHrOjmBnr19hxYgtS0WvAFwZhK2WP/YY5yF9uKECCEEDGxuLxq1NBK51wFA==", + "node_modules/@radix-ui/react-aspect-ratio": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-aspect-ratio/-/react-aspect-ratio-1.1.0.tgz", + "integrity": "sha512-dP87DM/Y7jFlPgUZTlhx6FF5CEzOiaxp2rBCKlaXlpH5Ip/9Fg5zZ9lDOQ5o/MOfUlf36eak14zoWYpgcgGoOg==", "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-primitive": "1.0.3" + "@radix-ui/react-primitive": "2.0.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { @@ -806,25 +825,24 @@ } }, "node_modules/@radix-ui/react-collapsible": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.0.3.tgz", - "integrity": "sha512-UBmVDkmR6IvDsloHVN+3rtx4Mi5TFvylYXpluuv0f37dtaz3H99bp8No0LGXRigVpl3UAT4l9j6bIchh42S/Gg==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/primitive": "1.0.1", - "@radix-ui/react-compose-refs": "1.0.1", - "@radix-ui/react-context": "1.0.1", - "@radix-ui/react-id": "1.0.1", - "@radix-ui/react-presence": "1.0.1", - "@radix-ui/react-primitive": "1.0.3", - "@radix-ui/react-use-controllable-state": "1.0.1", - "@radix-ui/react-use-layout-effect": "1.0.1" + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.1.0.tgz", + "integrity": "sha512-zQY7Epa8sTL0mq4ajSJpjgn2YmCgyrG7RsQgLp3C0LQVkG7+Tf6Pv1CeNWZLyqMjhdPkBa5Lx7wYBeSu7uCSTA==", + "dependencies": { + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-presence": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-controllable-state": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { @@ -836,21 +854,20 @@ } }, "node_modules/@radix-ui/react-collection": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.0.3.tgz", - "integrity": "sha512-3SzW+0PW7yBBoQlT8wNcGtaxaD0XSu0uLUFgrtHY08Acx05TaHaOmVLR73c0j/cqpDy53KBMO7s0dx2wmOIDIA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.0.tgz", + "integrity": "sha512-GZsZslMJEyo1VKm5L1ZJY8tGDxZNPAoUeQUIbKeJfoi7Q4kmig5AsgLMYYuyYbfjd8fBmFORAIwYAkXMnXZgZw==", "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-compose-refs": "1.0.1", - "@radix-ui/react-context": "1.0.1", - "@radix-ui/react-primitive": "1.0.3", - "@radix-ui/react-slot": "1.0.2" + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-slot": "1.1.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { @@ -862,15 +879,12 @@ } }, "node_modules/@radix-ui/react-compose-refs": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.0.1.tgz", - "integrity": "sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw==", - "dependencies": { - "@babel/runtime": "^7.13.10" - }, + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.0.tgz", + "integrity": "sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw==", "peerDependencies": { "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { @@ -879,15 +893,12 @@ } }, "node_modules/@radix-ui/react-context": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.0.1.tgz", - "integrity": "sha512-ebbrdFoYTcuZ0v4wG5tedGnp9tzcV8awzsxYph7gXUyvnNLuTIcCk1q17JEbnVhXAKG9oX3KtchwiMIAYp9NLg==", - "dependencies": { - "@babel/runtime": "^7.13.10" - }, + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.0.tgz", + "integrity": "sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==", "peerDependencies": { "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { @@ -896,31 +907,30 @@ } }, "node_modules/@radix-ui/react-dialog": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.0.5.tgz", - "integrity": "sha512-GjWJX/AUpB703eEBanuBnIWdIXg6NvJFCXcNlSZk4xdszCdhrJgBoUd1cGk67vFO+WdA2pfI/plOpqz/5GUP6Q==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/primitive": "1.0.1", - "@radix-ui/react-compose-refs": "1.0.1", - "@radix-ui/react-context": "1.0.1", - "@radix-ui/react-dismissable-layer": "1.0.5", - "@radix-ui/react-focus-guards": "1.0.1", - "@radix-ui/react-focus-scope": "1.0.4", - "@radix-ui/react-id": "1.0.1", - "@radix-ui/react-portal": "1.0.4", - "@radix-ui/react-presence": "1.0.1", - "@radix-ui/react-primitive": "1.0.3", - "@radix-ui/react-slot": "1.0.2", - "@radix-ui/react-use-controllable-state": "1.0.1", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.1.tgz", + "integrity": "sha512-zysS+iU4YP3STKNS6USvFVqI4qqx8EpiwmT5TuCApVEBca+eRCbONi4EgzfNSuVnOXvC5UPHHMjs8RXO6DH9Bg==", + "dependencies": { + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-dismissable-layer": "1.1.0", + "@radix-ui/react-focus-guards": "1.1.0", + "@radix-ui/react-focus-scope": "1.1.0", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-portal": "1.1.1", + "@radix-ui/react-presence": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-slot": "1.1.0", + "@radix-ui/react-use-controllable-state": "1.1.0", "aria-hidden": "^1.1.1", - "react-remove-scroll": "2.5.5" + "react-remove-scroll": "2.5.7" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { @@ -932,15 +942,12 @@ } }, "node_modules/@radix-ui/react-direction": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.0.1.tgz", - "integrity": "sha512-RXcvnXgyvYvBEOhCBuddKecVkoMiI10Jcm5cTI7abJRAHYfFxeu+FBQs/DvdxSYucxR5mna0dNsL6QFlds5TMA==", - "dependencies": { - "@babel/runtime": "^7.13.10" - }, + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.0.tgz", + "integrity": "sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg==", "peerDependencies": { "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { @@ -949,22 +956,21 @@ } }, "node_modules/@radix-ui/react-dismissable-layer": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.0.5.tgz", - "integrity": "sha512-aJeDjQhywg9LBu2t/At58hCvr7pEm0o2Ke1x33B+MhjNmmZ17sy4KImo0KPLgsnc/zN7GPdce8Cnn0SWvwZO7g==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.0.tgz", + "integrity": "sha512-/UovfmmXGptwGcBQawLzvn2jOfM0t4z3/uKffoBlj724+n3FvBbZ7M0aaBOmkp6pqFYpO4yx8tSVJjx3Fl2jig==", "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/primitive": "1.0.1", - "@radix-ui/react-compose-refs": "1.0.1", - "@radix-ui/react-primitive": "1.0.3", - "@radix-ui/react-use-callback-ref": "1.0.1", - "@radix-ui/react-use-escape-keydown": "1.0.3" + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-escape-keydown": "1.1.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { @@ -976,24 +982,23 @@ } }, "node_modules/@radix-ui/react-dropdown-menu": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.0.6.tgz", - "integrity": "sha512-i6TuFOoWmLWq+M/eCLGd/bQ2HfAX1RJgvrBQ6AQLmzfvsLdefxbWu8G9zczcPFfcSPehz9GcpF6K9QYreFV8hA==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.1.1.tgz", + "integrity": "sha512-y8E+x9fBq9qvteD2Zwa4397pUVhYsh9iq44b5RD5qu1GMJWBCBuVg1hMyItbc6+zH00TxGRqd9Iot4wzf3OoBQ==", "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/primitive": "1.0.1", - "@radix-ui/react-compose-refs": "1.0.1", - "@radix-ui/react-context": "1.0.1", - "@radix-ui/react-id": "1.0.1", - "@radix-ui/react-menu": "2.0.6", - "@radix-ui/react-primitive": "1.0.3", - "@radix-ui/react-use-controllable-state": "1.0.1" + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-menu": "2.1.1", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-controllable-state": "1.1.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { @@ -1005,15 +1010,12 @@ } }, "node_modules/@radix-ui/react-focus-guards": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.0.1.tgz", - "integrity": "sha512-Rect2dWbQ8waGzhMavsIbmSVCgYxkXLxxR3ZvCX79JOglzdEy4JXMb98lq4hPxUbLr77nP0UOGf4rcMU+s1pUA==", - "dependencies": { - "@babel/runtime": "^7.13.10" - }, + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.0.tgz", + "integrity": "sha512-w6XZNUPVv6xCpZUqb/yN9DL6auvpGX3C/ee6Hdi16v2UUy25HV2Q5bcflsiDyT/g5RwbPQ/GIT1vLkeRb+ITBw==", "peerDependencies": { "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { @@ -1022,20 +1024,19 @@ } }, "node_modules/@radix-ui/react-focus-scope": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.0.4.tgz", - "integrity": "sha512-sL04Mgvf+FmyvZeYfNu1EPAaaxD+aw7cYeIB9L9Fvq8+urhltTRaEo5ysKOpHuKPclsZcSUMKlN05x4u+CINpA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.0.tgz", + "integrity": "sha512-200UD8zylvEyL8Bx+z76RJnASR2gRMuxlgFCPAe/Q/679a/r0eK3MBVYMb7vZODZcffZBdob1EGnky78xmVvcA==", "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-compose-refs": "1.0.1", - "@radix-ui/react-primitive": "1.0.3", - "@radix-ui/react-use-callback-ref": "1.0.1" + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-callback-ref": "1.1.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { @@ -1055,16 +1056,15 @@ } }, "node_modules/@radix-ui/react-id": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.0.1.tgz", - "integrity": "sha512-tI7sT/kqYp8p96yGWY1OAnLHrqDgzHefRBKQ2YAkBS5ja7QLcZ9Z/uY7bEjPUatf8RomoXM8/1sMj1IJaE5UzQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.0.tgz", + "integrity": "sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==", "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-use-layout-effect": "1.0.1" + "@radix-ui/react-use-layout-effect": "1.1.0" }, "peerDependencies": { "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { @@ -1073,18 +1073,17 @@ } }, "node_modules/@radix-ui/react-label": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-label/-/react-label-2.0.2.tgz", - "integrity": "sha512-N5ehvlM7qoTLx7nWPodsPYPgMzA5WM8zZChQg8nyFJKnDO5WHdba1vv5/H6IO5LtJMfD2Q3wh1qHFGNtK0w3bQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-label/-/react-label-2.1.0.tgz", + "integrity": "sha512-peLblDlFw/ngk3UWq0VnYaOLy6agTZZ+MUO/WhVfm14vJGML+xH4FAl2XQGLqdefjNb7ApRg6Yn7U42ZhmYXdw==", "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-primitive": "1.0.3" + "@radix-ui/react-primitive": "2.0.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { @@ -1096,35 +1095,34 @@ } }, "node_modules/@radix-ui/react-menu": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.0.6.tgz", - "integrity": "sha512-BVkFLS+bUC8HcImkRKPSiVumA1VPOOEC5WBMiT+QAVsPzW1FJzI9KnqgGxVDPBcql5xXrHkD3JOVoXWEXD8SYA==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/primitive": "1.0.1", - "@radix-ui/react-collection": "1.0.3", - "@radix-ui/react-compose-refs": "1.0.1", - "@radix-ui/react-context": "1.0.1", - "@radix-ui/react-direction": "1.0.1", - "@radix-ui/react-dismissable-layer": "1.0.5", - "@radix-ui/react-focus-guards": "1.0.1", - "@radix-ui/react-focus-scope": "1.0.4", - "@radix-ui/react-id": "1.0.1", - "@radix-ui/react-popper": "1.1.3", - "@radix-ui/react-portal": "1.0.4", - "@radix-ui/react-presence": "1.0.1", - "@radix-ui/react-primitive": "1.0.3", - "@radix-ui/react-roving-focus": "1.0.4", - "@radix-ui/react-slot": "1.0.2", - "@radix-ui/react-use-callback-ref": "1.0.1", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.1.1.tgz", + "integrity": "sha512-oa3mXRRVjHi6DZu/ghuzdylyjaMXLymx83irM7hTxutQbD+7IhPKdMdRHD26Rm+kHRrWcrUkkRPv5pd47a2xFQ==", + "dependencies": { + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-collection": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-direction": "1.1.0", + "@radix-ui/react-dismissable-layer": "1.1.0", + "@radix-ui/react-focus-guards": "1.1.0", + "@radix-ui/react-focus-scope": "1.1.0", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-popper": "1.2.0", + "@radix-ui/react-portal": "1.1.1", + "@radix-ui/react-presence": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-roving-focus": "1.1.0", + "@radix-ui/react-slot": "1.1.0", + "@radix-ui/react-use-callback-ref": "1.1.0", "aria-hidden": "^1.1.1", - "react-remove-scroll": "2.5.5" + "react-remove-scroll": "2.5.7" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { @@ -1135,32 +1133,27 @@ } } }, - "node_modules/@radix-ui/react-navigation-menu": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@radix-ui/react-navigation-menu/-/react-navigation-menu-1.1.4.tgz", - "integrity": "sha512-Cc+seCS3PmWmjI51ufGG7zp1cAAIRqHVw7C9LOA2TZ+R4hG6rDvHcTqIsEEFLmZO3zNVH72jOOE7kKNy8W+RtA==", + "node_modules/@radix-ui/react-menubar": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-menubar/-/react-menubar-1.1.1.tgz", + "integrity": "sha512-V05Hryq/BE2m+rs8d5eLfrS0jmSWSDHEbG7jEyLA5D5J9jTvWj/o3v3xDN9YsOlH6QIkJgiaNDaP+S4T1rdykw==", "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/primitive": "1.0.1", - "@radix-ui/react-collection": "1.0.3", - "@radix-ui/react-compose-refs": "1.0.1", - "@radix-ui/react-context": "1.0.1", - "@radix-ui/react-direction": "1.0.1", - "@radix-ui/react-dismissable-layer": "1.0.5", - "@radix-ui/react-id": "1.0.1", - "@radix-ui/react-presence": "1.0.1", - "@radix-ui/react-primitive": "1.0.3", - "@radix-ui/react-use-callback-ref": "1.0.1", - "@radix-ui/react-use-controllable-state": "1.0.1", - "@radix-ui/react-use-layout-effect": "1.0.1", - "@radix-ui/react-use-previous": "1.0.1", - "@radix-ui/react-visually-hidden": "1.0.3" + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-collection": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-direction": "1.1.0", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-menu": "2.1.1", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-roving-focus": "1.1.0", + "@radix-ui/react-use-controllable-state": "1.1.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { @@ -1171,33 +1164,31 @@ } } }, - "node_modules/@radix-ui/react-popover": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.0.7.tgz", - "integrity": "sha512-shtvVnlsxT6faMnK/a7n0wptwBD23xc1Z5mdrtKLwVEfsEMXodS0r5s0/g5P0hX//EKYZS2sxUjqfzlg52ZSnQ==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/primitive": "1.0.1", - "@radix-ui/react-compose-refs": "1.0.1", - "@radix-ui/react-context": "1.0.1", - "@radix-ui/react-dismissable-layer": "1.0.5", - "@radix-ui/react-focus-guards": "1.0.1", - "@radix-ui/react-focus-scope": "1.0.4", - "@radix-ui/react-id": "1.0.1", - "@radix-ui/react-popper": "1.1.3", - "@radix-ui/react-portal": "1.0.4", - "@radix-ui/react-presence": "1.0.1", - "@radix-ui/react-primitive": "1.0.3", - "@radix-ui/react-slot": "1.0.2", - "@radix-ui/react-use-controllable-state": "1.0.1", - "aria-hidden": "^1.1.1", - "react-remove-scroll": "2.5.5" + "node_modules/@radix-ui/react-navigation-menu": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-navigation-menu/-/react-navigation-menu-1.2.0.tgz", + "integrity": "sha512-OQ8tcwAOR0DhPlSY3e4VMXeHiol7la4PPdJWhhwJiJA+NLX0SaCaonOkRnI3gCDHoZ7Fo7bb/G6q25fRM2Y+3Q==", + "dependencies": { + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-collection": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-direction": "1.1.0", + "@radix-ui/react-dismissable-layer": "1.1.0", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-presence": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-controllable-state": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0", + "@radix-ui/react-use-previous": "1.1.0", + "@radix-ui/react-visually-hidden": "1.1.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { @@ -1208,28 +1199,32 @@ } } }, - "node_modules/@radix-ui/react-popper": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.1.3.tgz", - "integrity": "sha512-cKpopj/5RHZWjrbF2846jBNacjQVwkP068DfmgrNJXpvVWrOvlAmE9xSiy5OqeE+Gi8D9fP+oDhUnPqNMY8/5w==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@floating-ui/react-dom": "^2.0.0", - "@radix-ui/react-arrow": "1.0.3", - "@radix-ui/react-compose-refs": "1.0.1", - "@radix-ui/react-context": "1.0.1", - "@radix-ui/react-primitive": "1.0.3", - "@radix-ui/react-use-callback-ref": "1.0.1", - "@radix-ui/react-use-layout-effect": "1.0.1", - "@radix-ui/react-use-rect": "1.0.1", - "@radix-ui/react-use-size": "1.0.1", - "@radix-ui/rect": "1.0.1" + "node_modules/@radix-ui/react-popover": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.1.1.tgz", + "integrity": "sha512-3y1A3isulwnWhvTTwmIreiB8CF4L+qRjZnK1wYLO7pplddzXKby/GnZ2M7OZY3qgnl6p9AodUIHRYGXNah8Y7g==", + "dependencies": { + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-dismissable-layer": "1.1.0", + "@radix-ui/react-focus-guards": "1.1.0", + "@radix-ui/react-focus-scope": "1.1.0", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-popper": "1.2.0", + "@radix-ui/react-portal": "1.1.1", + "@radix-ui/react-presence": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-slot": "1.1.0", + "@radix-ui/react-use-controllable-state": "1.1.0", + "aria-hidden": "^1.1.1", + "react-remove-scroll": "2.5.7" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { @@ -1240,19 +1235,50 @@ } } }, - "node_modules/@radix-ui/react-portal": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.0.4.tgz", - "integrity": "sha512-Qki+C/EuGUVCQTOTD5vzJzJuMUlewbzuKyUy+/iHM2uwGiru9gZeBJtHAPKAEkB5KWGi9mP/CHKcY0wt1aW45Q==", + "node_modules/@radix-ui/react-popper": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.0.tgz", + "integrity": "sha512-ZnRMshKF43aBxVWPWvbj21+7TQCvhuULWJ4gNIKYpRlQt5xGRhLx66tMp8pya2UkGHTSlhpXwmjqltDYHhw7Vg==", "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-primitive": "1.0.3" + "@floating-ui/react-dom": "^2.0.0", + "@radix-ui/react-arrow": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0", + "@radix-ui/react-use-rect": "1.1.0", + "@radix-ui/react-use-size": "1.1.0", + "@radix-ui/rect": "1.1.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-portal": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.1.tgz", + "integrity": "sha512-A3UtLk85UtqhzFqtoC8Q0KvR2GbXF3mtPgACSazajqq6A41mEQgo53iPzY4i6BwDxlIFqWIhiQ2G729n+2aw/g==", + "dependencies": { + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { @@ -1264,19 +1290,18 @@ } }, "node_modules/@radix-ui/react-presence": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.0.1.tgz", - "integrity": "sha512-UXLW4UAbIY5ZjcvzjfRFo5gxva8QirC9hF7wRE4U5gz+TP0DbRk+//qyuAQ1McDxBt1xNMBTaciFGvEmJvAZCg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.0.tgz", + "integrity": "sha512-Gq6wuRN/asf9H/E/VzdKoUtT8GC9PQc9z40/vEr0VCJ4u5XvvhWIrSsCB6vD2/cH7ugTdSfYq9fLJCcM00acrQ==", "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-compose-refs": "1.0.1", - "@radix-ui/react-use-layout-effect": "1.0.1" + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { @@ -1288,18 +1313,17 @@ } }, "node_modules/@radix-ui/react-primitive": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-1.0.3.tgz", - "integrity": "sha512-yi58uVyoAcK/Nq1inRY56ZSjKypBNKTa/1mcL8qdl6oJeEaDbOldlzrGn7P6Q3Id5d+SYNGc5AJgc4vGhjs5+g==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.0.tgz", + "integrity": "sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw==", "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-slot": "1.0.2" + "@radix-ui/react-slot": "1.1.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { @@ -1311,19 +1335,18 @@ } }, "node_modules/@radix-ui/react-progress": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-progress/-/react-progress-1.0.3.tgz", - "integrity": "sha512-5G6Om/tYSxjSeEdrb1VfKkfZfn/1IlPWd731h2RfPuSbIfNUgfqAwbKfJCg/PP6nuUCTrYzalwHSpSinoWoCag==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-progress/-/react-progress-1.1.0.tgz", + "integrity": "sha512-aSzvnYpP725CROcxAOEBVZZSIQVQdHgBr2QQFKySsaD14u8dNT0batuXI+AAGDdAHfXH8rbnHmjYFqVJ21KkRg==", "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-context": "1.0.1", - "@radix-ui/react-primitive": "1.0.3" + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-primitive": "2.0.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { @@ -1335,26 +1358,25 @@ } }, "node_modules/@radix-ui/react-roving-focus": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.0.4.tgz", - "integrity": "sha512-2mUg5Mgcu001VkGy+FfzZyzbmuUWzgWkj3rvv4yu+mLw03+mTzbxZHvfcGyFp2b8EkQeMkpRQ5FiA2Vr2O6TeQ==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/primitive": "1.0.1", - "@radix-ui/react-collection": "1.0.3", - "@radix-ui/react-compose-refs": "1.0.1", - "@radix-ui/react-context": "1.0.1", - "@radix-ui/react-direction": "1.0.1", - "@radix-ui/react-id": "1.0.1", - "@radix-ui/react-primitive": "1.0.3", - "@radix-ui/react-use-callback-ref": "1.0.1", - "@radix-ui/react-use-controllable-state": "1.0.1" + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.0.tgz", + "integrity": "sha512-EA6AMGeq9AEeQDeSH0aZgG198qkfHSbvWTf1HvoDmOB5bBG/qTxjYMWUKMnYiV6J/iP/J8MEFSuB2zRU2n7ODA==", + "dependencies": { + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-collection": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-direction": "1.1.0", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-controllable-state": "1.1.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { @@ -1366,26 +1388,25 @@ } }, "node_modules/@radix-ui/react-scroll-area": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@radix-ui/react-scroll-area/-/react-scroll-area-1.0.5.tgz", - "integrity": "sha512-b6PAgH4GQf9QEn8zbT2XUHpW5z8BzqEc7Kl11TwDrvuTrxlkcjTD5qa/bxgKr+nmuXKu4L/W5UZ4mlP/VG/5Gw==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/number": "1.0.1", - "@radix-ui/primitive": "1.0.1", - "@radix-ui/react-compose-refs": "1.0.1", - "@radix-ui/react-context": "1.0.1", - "@radix-ui/react-direction": "1.0.1", - "@radix-ui/react-presence": "1.0.1", - "@radix-ui/react-primitive": "1.0.3", - "@radix-ui/react-use-callback-ref": "1.0.1", - "@radix-ui/react-use-layout-effect": "1.0.1" + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-scroll-area/-/react-scroll-area-1.1.0.tgz", + "integrity": "sha512-9ArIZ9HWhsrfqS765h+GZuLoxaRHD/j0ZWOWilsCvYTpYJp8XwCqNG7Dt9Nu/TItKOdgLGkOPCodQvDc+UMwYg==", + "dependencies": { + "@radix-ui/number": "1.1.0", + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-direction": "1.1.0", + "@radix-ui/react-presence": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { @@ -1397,38 +1418,37 @@ } }, "node_modules/@radix-ui/react-select": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.0.0.tgz", - "integrity": "sha512-RH5b7af4oHtkcHS7pG6Sgv5rk5Wxa7XI8W5gvB1N/yiuDGZxko1ynvOiVhFM7Cis2A8zxF9bTOUVbRDzPepe6w==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/number": "1.0.1", - "@radix-ui/primitive": "1.0.1", - "@radix-ui/react-collection": "1.0.3", - "@radix-ui/react-compose-refs": "1.0.1", - "@radix-ui/react-context": "1.0.1", - "@radix-ui/react-direction": "1.0.1", - "@radix-ui/react-dismissable-layer": "1.0.5", - "@radix-ui/react-focus-guards": "1.0.1", - "@radix-ui/react-focus-scope": "1.0.4", - "@radix-ui/react-id": "1.0.1", - "@radix-ui/react-popper": "1.1.3", - "@radix-ui/react-portal": "1.0.4", - "@radix-ui/react-primitive": "1.0.3", - "@radix-ui/react-slot": "1.0.2", - "@radix-ui/react-use-callback-ref": "1.0.1", - "@radix-ui/react-use-controllable-state": "1.0.1", - "@radix-ui/react-use-layout-effect": "1.0.1", - "@radix-ui/react-use-previous": "1.0.1", - "@radix-ui/react-visually-hidden": "1.0.3", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.1.1.tgz", + "integrity": "sha512-8iRDfyLtzxlprOo9IicnzvpsO1wNCkuwzzCM+Z5Rb5tNOpCdMvcc2AkzX0Fz+Tz9v6NJ5B/7EEgyZveo4FBRfQ==", + "dependencies": { + "@radix-ui/number": "1.1.0", + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-collection": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-direction": "1.1.0", + "@radix-ui/react-dismissable-layer": "1.1.0", + "@radix-ui/react-focus-guards": "1.1.0", + "@radix-ui/react-focus-scope": "1.1.0", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-popper": "1.2.0", + "@radix-ui/react-portal": "1.1.1", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-slot": "1.1.0", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-controllable-state": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0", + "@radix-ui/react-use-previous": "1.1.0", + "@radix-ui/react-visually-hidden": "1.1.0", "aria-hidden": "^1.1.1", - "react-remove-scroll": "2.5.5" + "react-remove-scroll": "2.5.7" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { @@ -1440,18 +1460,17 @@ } }, "node_modules/@radix-ui/react-separator": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-separator/-/react-separator-1.0.3.tgz", - "integrity": "sha512-itYmTy/kokS21aiV5+Z56MZB54KrhPgn6eHDKkFeOLR34HMN2s8PaN47qZZAGnvupcjxHaFZnW4pQEh0BvvVuw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-separator/-/react-separator-1.1.0.tgz", + "integrity": "sha512-3uBAs+egzvJBDZAzvb/n4NxxOYpnspmWxO2u5NbZ8Y6FM/NdrGSF9bop3Cf6F6C71z1rTSn8KV0Fo2ZVd79lGA==", "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-primitive": "1.0.3" + "@radix-ui/react-primitive": "2.0.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { @@ -1463,16 +1482,15 @@ } }, "node_modules/@radix-ui/react-slot": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.2.tgz", - "integrity": "sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.0.tgz", + "integrity": "sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==", "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-compose-refs": "1.0.1" + "@radix-ui/react-compose-refs": "1.1.0" }, "peerDependencies": { "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { @@ -1481,29 +1499,28 @@ } }, "node_modules/@radix-ui/react-tooltip": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.0.7.tgz", - "integrity": "sha512-lPh5iKNFVQ/jav/j6ZrWq3blfDJ0OH9R6FlNUHPMqdLuQ9vwDgFsRxvl8b7Asuy5c8xmoojHUxKHQSOAvMHxyw==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/primitive": "1.0.1", - "@radix-ui/react-compose-refs": "1.0.1", - "@radix-ui/react-context": "1.0.1", - "@radix-ui/react-dismissable-layer": "1.0.5", - "@radix-ui/react-id": "1.0.1", - "@radix-ui/react-popper": "1.1.3", - "@radix-ui/react-portal": "1.0.4", - "@radix-ui/react-presence": "1.0.1", - "@radix-ui/react-primitive": "1.0.3", - "@radix-ui/react-slot": "1.0.2", - "@radix-ui/react-use-controllable-state": "1.0.1", - "@radix-ui/react-visually-hidden": "1.0.3" + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.1.2.tgz", + "integrity": "sha512-9XRsLwe6Yb9B/tlnYCPVUd/TFS4J7HuOZW345DCeC6vKIxQGMZdx21RK4VoZauPD5frgkXTYVS5y90L+3YBn4w==", + "dependencies": { + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-dismissable-layer": "1.1.0", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-popper": "1.2.0", + "@radix-ui/react-portal": "1.1.1", + "@radix-ui/react-presence": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-slot": "1.1.0", + "@radix-ui/react-use-controllable-state": "1.1.0", + "@radix-ui/react-visually-hidden": "1.1.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { @@ -1515,15 +1532,12 @@ } }, "node_modules/@radix-ui/react-use-callback-ref": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.0.1.tgz", - "integrity": "sha512-D94LjX4Sp0xJFVaoQOd3OO9k7tpBYNOXdVhkltUbGv2Qb9OXdrg/CpsjlZv7ia14Sylv398LswWBVVu5nqKzAQ==", - "dependencies": { - "@babel/runtime": "^7.13.10" - }, + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz", + "integrity": "sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==", "peerDependencies": { "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { @@ -1532,16 +1546,15 @@ } }, "node_modules/@radix-ui/react-use-controllable-state": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.0.1.tgz", - "integrity": "sha512-Svl5GY5FQeN758fWKrjM6Qb7asvXeiZltlT4U2gVfl8Gx5UAv2sMR0LWo8yhsIZh2oQ0eFdZ59aoOOMV7b47VA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.1.0.tgz", + "integrity": "sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==", "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-use-callback-ref": "1.0.1" + "@radix-ui/react-use-callback-ref": "1.1.0" }, "peerDependencies": { "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { @@ -1550,16 +1563,15 @@ } }, "node_modules/@radix-ui/react-use-escape-keydown": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.0.3.tgz", - "integrity": "sha512-vyL82j40hcFicA+M4Ex7hVkB9vHgSse1ZWomAqV2Je3RleKGO5iM8KMOEtfoSB0PnIelMd2lATjTGMYqN5ylTg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.0.tgz", + "integrity": "sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw==", "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-use-callback-ref": "1.0.1" + "@radix-ui/react-use-callback-ref": "1.1.0" }, "peerDependencies": { "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { @@ -1568,15 +1580,12 @@ } }, "node_modules/@radix-ui/react-use-layout-effect": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.0.1.tgz", - "integrity": "sha512-v/5RegiJWYdoCvMnITBkNNx6bCj20fiaJnWtRkU18yITptraXjffz5Qbn05uOiQnOvi+dbkznkoaMltz1GnszQ==", - "dependencies": { - "@babel/runtime": "^7.13.10" - }, + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz", + "integrity": "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==", "peerDependencies": { "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { @@ -1585,15 +1594,12 @@ } }, "node_modules/@radix-ui/react-use-previous": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.0.1.tgz", - "integrity": "sha512-cV5La9DPwiQ7S0gf/0qiD6YgNqM5Fk97Kdrlc5yBcrF3jyEZQwm7vYFqMo4IfeHgJXsRaMvLABFtd0OVEmZhDw==", - "dependencies": { - "@babel/runtime": "^7.13.10" - }, + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.0.tgz", + "integrity": "sha512-Z/e78qg2YFnnXcW88A4JmTtm4ADckLno6F7OXotmkQfeuCVaKuYzqAATPhVzl3delXE7CxIV8shofPn3jPc5Og==", "peerDependencies": { "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { @@ -1602,16 +1608,15 @@ } }, "node_modules/@radix-ui/react-use-rect": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.0.1.tgz", - "integrity": "sha512-Cq5DLuSiuYVKNU8orzJMbl15TXilTnJKUCltMVQg53BQOF1/C5toAaGrowkgksdBQ9H+SRL23g0HDmg9tvmxXw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.0.tgz", + "integrity": "sha512-0Fmkebhr6PiseyZlYAOtLS+nb7jLmpqTrJyv61Pe68MKYW6OWdRE2kI70TaYY27u7H0lajqM3hSMMLFq18Z7nQ==", "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/rect": "1.0.1" + "@radix-ui/rect": "1.1.0" }, "peerDependencies": { "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { @@ -1620,16 +1625,15 @@ } }, "node_modules/@radix-ui/react-use-size": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.0.1.tgz", - "integrity": "sha512-ibay+VqrgcaI6veAojjofPATwledXiSmX+C0KrBk/xgpX9rBzPV3OsfwlhQdUOFbh+LKQorLYT+xTXW9V8yd0g==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.0.tgz", + "integrity": "sha512-XW3/vWuIXHa+2Uwcc2ABSfcCledmXhhQPlGbfcRXbiUQI5Icjcg19BGCZVKKInYbvUCut/ufbbLLPFC5cbb1hw==", "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-use-layout-effect": "1.0.1" + "@radix-ui/react-use-layout-effect": "1.1.0" }, "peerDependencies": { "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { @@ -1638,18 +1642,17 @@ } }, "node_modules/@radix-ui/react-visually-hidden": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.0.3.tgz", - "integrity": "sha512-D4w41yN5YRKtu464TLnByKzMDG/JlMPHtfZgQAu9v6mNakUqGUI9vUrfQKz8NK41VMm/xbZbh76NUTVtIYqOMA==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.1.0.tgz", + "integrity": "sha512-N8MDZqtgCgG5S3aV60INAB475osJousYpZ4cTJ2cFbMpdHS5Y6loLTH8LPtkj2QN0x93J30HT/M3qJXM0+lyeQ==", "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-primitive": "1.0.3" + "@radix-ui/react-primitive": "2.0.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { @@ -1661,25 +1664,22 @@ } }, "node_modules/@radix-ui/rect": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.0.1.tgz", - "integrity": "sha512-fyrgCaedtvMg9NK3en0pnOYJdtfwxUcNolezkNPUsoX57X8oQk+NkqcvzHXD2uKNij6GXmWU9NDru2IWjrO4BQ==", - "dependencies": { - "@babel/runtime": "^7.13.10" - } + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.0.tgz", + "integrity": "sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg==" }, "node_modules/@remix-run/router": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.16.0.tgz", - "integrity": "sha512-Quz1KOffeEf/zwkCBM3kBtH4ZoZ+pT3xIXBG4PPW/XFtDP7EGhtTiC2+gpL9GnR7+Qdet5Oa6cYSvwKYg6kN9Q==", + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.18.0.tgz", + "integrity": "sha512-L3jkqmqoSVBVKHfpGZmLrex0lxR5SucGA0sUfFzGctehw+S/ggL9L/0NnC5mw6P8HUWpFZ3nQw3cRApjjWx9Sw==", "engines": { "node": ">=14.0.0" } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.17.2.tgz", - "integrity": "sha512-NM0jFxY8bB8QLkoKxIQeObCaDlJKewVlIEkuyYKm5An1tdVZ966w2+MPQ2l8LBZLjR+SgyV+nRkTIunzOYBMLQ==", + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.19.0.tgz", + "integrity": "sha512-JlPfZ/C7yn5S5p0yKk7uhHTTnFlvTgLetl2VxqE518QgyM7C9bSfFTYvB/Q/ftkq0RIPY4ySxTz+/wKJ/dXC0w==", "cpu": [ "arm" ], @@ -1690,9 +1690,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.17.2.tgz", - "integrity": "sha512-yeX/Usk7daNIVwkq2uGoq2BYJKZY1JfyLTaHO/jaiSwi/lsf8fTFoQW/n6IdAsx5tx+iotu2zCJwz8MxI6D/Bw==", + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.19.0.tgz", + "integrity": "sha512-RDxUSY8D1tWYfn00DDi5myxKgOk6RvWPxhmWexcICt/MEC6yEMr4HNCu1sXXYLw8iAsg0D44NuU+qNq7zVWCrw==", "cpu": [ "arm64" ], @@ -1703,9 +1703,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.17.2.tgz", - "integrity": "sha512-kcMLpE6uCwls023+kknm71ug7MZOrtXo+y5p/tsg6jltpDtgQY1Eq5sGfHcQfb+lfuKwhBmEURDga9N0ol4YPw==", + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.19.0.tgz", + "integrity": "sha512-emvKHL4B15x6nlNTBMtIaC9tLPRpeA5jMvRLXVbl/W9Ie7HhkrE7KQjvgS9uxgatL1HmHWDXk5TTS4IaNJxbAA==", "cpu": [ "arm64" ], @@ -1716,9 +1716,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.17.2.tgz", - "integrity": "sha512-AtKwD0VEx0zWkL0ZjixEkp5tbNLzX+FCqGG1SvOu993HnSz4qDI6S4kGzubrEJAljpVkhRSlg5bzpV//E6ysTQ==", + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.19.0.tgz", + "integrity": "sha512-fO28cWA1dC57qCd+D0rfLC4VPbh6EOJXrreBmFLWPGI9dpMlER2YwSPZzSGfq11XgcEpPukPTfEVFtw2q2nYJg==", "cpu": [ "x64" ], @@ -1729,9 +1729,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.17.2.tgz", - "integrity": "sha512-3reX2fUHqN7sffBNqmEyMQVj/CKhIHZd4y631duy0hZqI8Qoqf6lTtmAKvJFYa6bhU95B1D0WgzHkmTg33In0A==", + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.19.0.tgz", + "integrity": "sha512-2Rn36Ubxdv32NUcfm0wB1tgKqkQuft00PtM23VqLuCUR4N5jcNWDoV5iBC9jeGdgS38WK66ElncprqgMUOyomw==", "cpu": [ "arm" ], @@ -1742,9 +1742,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.17.2.tgz", - "integrity": "sha512-uSqpsp91mheRgw96xtyAGP9FW5ChctTFEoXP0r5FAzj/3ZRv3Uxjtc7taRQSaQM/q85KEKjKsZuiZM3GyUivRg==", + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.19.0.tgz", + "integrity": "sha512-gJuzIVdq/X1ZA2bHeCGCISe0VWqCoNT8BvkQ+BfsixXwTOndhtLUpOg0A1Fcx/+eA6ei6rMBzlOz4JzmiDw7JQ==", "cpu": [ "arm" ], @@ -1755,9 +1755,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.17.2.tgz", - "integrity": "sha512-EMMPHkiCRtE8Wdk3Qhtciq6BndLtstqZIroHiiGzB3C5LDJmIZcSzVtLRbwuXuUft1Cnv+9fxuDtDxz3k3EW2A==", + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.19.0.tgz", + "integrity": "sha512-0EkX2HYPkSADo9cfeGFoQ7R0/wTKb7q6DdwI4Yn/ULFE1wuRRCHybxpl2goQrx4c/yzK3I8OlgtBu4xvted0ug==", "cpu": [ "arm64" ], @@ -1768,9 +1768,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.17.2.tgz", - "integrity": "sha512-NMPylUUZ1i0z/xJUIx6VUhISZDRT+uTWpBcjdv0/zkp7b/bQDF+NfnfdzuTiB1G6HTodgoFa93hp0O1xl+/UbA==", + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.19.0.tgz", + "integrity": "sha512-GlIQRj9px52ISomIOEUq/IojLZqzkvRpdP3cLgIE1wUWaiU5Takwlzpz002q0Nxxr1y2ZgxC2obWxjr13lvxNQ==", "cpu": [ "arm64" ], @@ -1781,9 +1781,9 @@ ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.17.2.tgz", - "integrity": "sha512-T19My13y8uYXPw/L/k0JYaX1fJKFT/PWdXiHr8mTbXWxjVF1t+8Xl31DgBBvEKclw+1b00Chg0hxE2O7bTG7GQ==", + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.19.0.tgz", + "integrity": "sha512-N6cFJzssruDLUOKfEKeovCKiHcdwVYOT1Hs6dovDQ61+Y9n3Ek4zXvtghPPelt6U0AH4aDGnDLb83uiJMkWYzQ==", "cpu": [ "ppc64" ], @@ -1794,9 +1794,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.17.2.tgz", - "integrity": "sha512-BOaNfthf3X3fOWAB+IJ9kxTgPmMqPPH5f5k2DcCsRrBIbWnaJCgX2ll77dV1TdSy9SaXTR5iDXRL8n7AnoP5cg==", + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.19.0.tgz", + "integrity": "sha512-2DnD3mkS2uuam/alF+I7M84koGwvn3ZVD7uG+LEWpyzo/bq8+kKnus2EVCkcvh6PlNB8QPNFOz6fWd5N8o1CYg==", "cpu": [ "riscv64" ], @@ -1807,9 +1807,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.17.2.tgz", - "integrity": "sha512-W0UP/x7bnn3xN2eYMql2T/+wpASLE5SjObXILTMPUBDB/Fg/FxC+gX4nvCfPBCbNhz51C+HcqQp2qQ4u25ok6g==", + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.19.0.tgz", + "integrity": "sha512-D6pkaF7OpE7lzlTOFCB2m3Ngzu2ykw40Nka9WmKGUOTS3xcIieHe82slQlNq69sVB04ch73thKYIWz/Ian8DUA==", "cpu": [ "s390x" ], @@ -1820,9 +1820,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.17.2.tgz", - "integrity": "sha512-Hy7pLwByUOuyaFC6mAr7m+oMC+V7qyifzs/nW2OJfC8H4hbCzOX07Ov0VFk/zP3kBsELWNFi7rJtgbKYsav9QQ==", + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.19.0.tgz", + "integrity": "sha512-HBndjQLP8OsdJNSxpNIN0einbDmRFg9+UQeZV1eiYupIRuZsDEoeGU43NQsS34Pp166DtwQOnpcbV/zQxM+rWA==", "cpu": [ "x64" ], @@ -1833,9 +1833,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.17.2.tgz", - "integrity": "sha512-h1+yTWeYbRdAyJ/jMiVw0l6fOOm/0D1vNLui9iPuqgRGnXA0u21gAqOyB5iHjlM9MMfNOm9RHCQ7zLIzT0x11Q==", + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.19.0.tgz", + "integrity": "sha512-HxfbvfCKJe/RMYJJn0a12eiOI9OOtAUF4G6ozrFUK95BNyoJaSiBjIOHjZskTUffUrB84IPKkFG9H9nEvJGW6A==", "cpu": [ "x64" ], @@ -1846,9 +1846,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.17.2.tgz", - "integrity": "sha512-tmdtXMfKAjy5+IQsVtDiCfqbynAQE/TQRpWdVataHmhMb9DCoJxp9vLcCBjEQWMiUYxO1QprH/HbY9ragCEFLA==", + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.19.0.tgz", + "integrity": "sha512-HxDMKIhmcguGTiP5TsLNolwBUK3nGGUEoV/BO9ldUBoMLBssvh4J0X8pf11i1fTV7WShWItB1bKAKjX4RQeYmg==", "cpu": [ "arm64" ], @@ -1859,9 +1859,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.17.2.tgz", - "integrity": "sha512-7II/QCSTAHuE5vdZaQEwJq2ZACkBpQDOmQsE6D6XUbnBHW8IAhm4eTufL6msLJorzrHDFv3CF8oCA/hSIRuZeQ==", + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.19.0.tgz", + "integrity": "sha512-xItlIAZZaiG/u0wooGzRsx11rokP4qyc/79LkAOdznGRAbOFc+SfEdfUOszG1odsHNgwippUJavag/+W/Etc6Q==", "cpu": [ "ia32" ], @@ -1872,9 +1872,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.17.2.tgz", - "integrity": "sha512-TGGO7v7qOq4CYmSBVEYpI1Y5xDuCEnbVC5Vth8mOsW0gDSzxNrVERPc790IGHsrT2dQSimgMr9Ub3Y1Jci5/8w==", + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.19.0.tgz", + "integrity": "sha512-xNo5fV5ycvCCKqiZcpB65VMR11NJB+StnxHz20jdqRAktfdfzhgjTiJ2doTDQE/7dqGaV5I7ZGqKpgph6lCIag==", "cpu": [ "x64" ], @@ -1885,14 +1885,14 @@ ] }, "node_modules/@swc/core": { - "version": "1.4.17", - "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.4.17.tgz", - "integrity": "sha512-tq+mdWvodMBNBBZbwFIMTVGYHe9N7zvEaycVVjfvAx20k1XozHbHhRv+9pEVFJjwRxLdXmtvFZd3QZHRAOpoNQ==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.7.0.tgz", + "integrity": "sha512-d4vMzH6ICllDwlPuhset2h8gu/USHdbyfJim+2hQEdxC0UONtfpmu38XBgNqRjStrji1Q5M10jfeUZL3cu1i8g==", "dev": true, "hasInstallScript": true, "dependencies": { - "@swc/counter": "^0.1.2", - "@swc/types": "^0.1.5" + "@swc/counter": "^0.1.3", + "@swc/types": "^0.1.9" }, "engines": { "node": ">=10" @@ -1902,19 +1902,19 @@ "url": "https://opencollective.com/swc" }, "optionalDependencies": { - "@swc/core-darwin-arm64": "1.4.17", - "@swc/core-darwin-x64": "1.4.17", - "@swc/core-linux-arm-gnueabihf": "1.4.17", - "@swc/core-linux-arm64-gnu": "1.4.17", - "@swc/core-linux-arm64-musl": "1.4.17", - "@swc/core-linux-x64-gnu": "1.4.17", - "@swc/core-linux-x64-musl": "1.4.17", - "@swc/core-win32-arm64-msvc": "1.4.17", - "@swc/core-win32-ia32-msvc": "1.4.17", - "@swc/core-win32-x64-msvc": "1.4.17" + "@swc/core-darwin-arm64": "1.7.0", + "@swc/core-darwin-x64": "1.7.0", + "@swc/core-linux-arm-gnueabihf": "1.7.0", + "@swc/core-linux-arm64-gnu": "1.7.0", + "@swc/core-linux-arm64-musl": "1.7.0", + "@swc/core-linux-x64-gnu": "1.7.0", + "@swc/core-linux-x64-musl": "1.7.0", + "@swc/core-win32-arm64-msvc": "1.7.0", + "@swc/core-win32-ia32-msvc": "1.7.0", + "@swc/core-win32-x64-msvc": "1.7.0" }, "peerDependencies": { - "@swc/helpers": "^0.5.0" + "@swc/helpers": "*" }, "peerDependenciesMeta": { "@swc/helpers": { @@ -1923,9 +1923,9 @@ } }, "node_modules/@swc/core-darwin-arm64": { - "version": "1.4.17", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.4.17.tgz", - "integrity": "sha512-HVl+W4LezoqHBAYg2JCqR+s9ife9yPfgWSj37iIawLWzOmuuJ7jVdIB7Ee2B75bEisSEKyxRlTl6Y1Oq3owBgw==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.7.0.tgz", + "integrity": "sha512-2ylhM7f0HwUwLrFYZAe/dse8PCbPsYcJS3Dt7Q8NT3PUn7vy6QOMxNcOPPuDrnmaXqQQO3oxdmRapguTxaat9g==", "cpu": [ "arm64" ], @@ -1939,9 +1939,9 @@ } }, "node_modules/@swc/core-darwin-x64": { - "version": "1.4.17", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.4.17.tgz", - "integrity": "sha512-WYRO9Fdzq4S/he8zjW5I95G1zcvyd9yyD3Tgi4/ic84P5XDlSMpBDpBLbr/dCPjmSg7aUXxNQqKqGkl6dQxYlA==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.7.0.tgz", + "integrity": "sha512-SgVnN4gT1Rb9YfTkp4FCUITqSs7Yj0uB2SUciu5CV3HuGvS5YXCUzh+KrwpLFtx8NIgivISKcNnb41mJi98X8Q==", "cpu": [ "x64" ], @@ -1955,9 +1955,9 @@ } }, "node_modules/@swc/core-linux-arm-gnueabihf": { - "version": "1.4.17", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.4.17.tgz", - "integrity": "sha512-cgbvpWOvtMH0XFjvwppUCR+Y+nf6QPaGu6AQ5hqCP+5Lv2zO5PG0RfasC4zBIjF53xgwEaaWmGP5/361P30X8Q==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.7.0.tgz", + "integrity": "sha512-+Z9Dayart1iKJQEJJ9N/KS4z5EdXJE3WPFikY0jonKTo4Dd8RuyVz5yLvqcIMeVdz/SwximATaL6iJXw7hZS9A==", "cpu": [ "arm" ], @@ -1971,9 +1971,9 @@ } }, "node_modules/@swc/core-linux-arm64-gnu": { - "version": "1.4.17", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.4.17.tgz", - "integrity": "sha512-l7zHgaIY24cF9dyQ/FOWbmZDsEj2a9gRFbmgx2u19e3FzOPuOnaopFj0fRYXXKCmtdx+anD750iBIYnTR+pq/Q==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.7.0.tgz", + "integrity": "sha512-UnLrCiZ1EI4shznJn0xP6DLgsXUSwtfsdgHhGYCrvbgVBBve3S9iFgVFEB3SPl7Q/TdowNbrN4zHU0oChfiNfw==", "cpu": [ "arm64" ], @@ -1987,9 +1987,9 @@ } }, "node_modules/@swc/core-linux-arm64-musl": { - "version": "1.4.17", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.4.17.tgz", - "integrity": "sha512-qhH4gr9gAlVk8MBtzXbzTP3BJyqbAfUOATGkyUtohh85fPXQYuzVlbExix3FZXTwFHNidGHY8C+ocscI7uDaYw==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.7.0.tgz", + "integrity": "sha512-H724UANA+ptsfwKRr9mnaDa9cb5fw0oFysiGKTgb3DMYcgk3Od0jMTnXVPFSVpo7FlmyxeC9K8ueUPBOoOK6XA==", "cpu": [ "arm64" ], @@ -2003,9 +2003,9 @@ } }, "node_modules/@swc/core-linux-x64-gnu": { - "version": "1.4.17", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.4.17.tgz", - "integrity": "sha512-vRDFATL1oN5oZMImkwbgSHEkp8xG1ofEASBypze01W1Tqto8t+yo6gsp69wzCZBlxldsvPpvFZW55Jq0Rn+UnA==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.7.0.tgz", + "integrity": "sha512-SY3HA0K0Dpqt1HIfMLGpwL4hd4UaL2xHP5oZXPlRQPhUDZrbb4PbI3ZJnh66c63eL4ZR8EJ+HRFI0Alx5p69Zw==", "cpu": [ "x64" ], @@ -2019,9 +2019,9 @@ } }, "node_modules/@swc/core-linux-x64-musl": { - "version": "1.4.17", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.4.17.tgz", - "integrity": "sha512-zQNPXAXn3nmPqv54JVEN8k2JMEcMTQ6veVuU0p5O+A7KscJq+AGle/7ZQXzpXSfUCXlLMX4wvd+rwfGhh3J4cw==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.7.0.tgz", + "integrity": "sha512-cEJ2ebtV1v/5Ilb55E05J6F5SrHKQWzUttIhR5Mkayyo+yvPslcpByuFC3D+J7X1ebziTOBpWuMpUdjLfh3SMQ==", "cpu": [ "x64" ], @@ -2035,9 +2035,9 @@ } }, "node_modules/@swc/core-win32-arm64-msvc": { - "version": "1.4.17", - "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.4.17.tgz", - "integrity": "sha512-z86n7EhOwyzxwm+DLE5NoLkxCTme2lq7QZlDjbQyfCxOt6isWz8rkW5QowTX8w9Rdmk34ncrjSLvnHOeLY17+w==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.7.0.tgz", + "integrity": "sha512-ecQOOmzEssz+m0pR4xDYCGuvn3E/l0nQ3tk5jp1NA1lsAy4bMV0YbYCHjptYvWL/UjhIerIp3IlCJ8x5DodSog==", "cpu": [ "arm64" ], @@ -2051,9 +2051,9 @@ } }, "node_modules/@swc/core-win32-ia32-msvc": { - "version": "1.4.17", - "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.4.17.tgz", - "integrity": "sha512-JBwuSTJIgiJJX6wtr4wmXbfvOswHFj223AumUrK544QV69k60FJ9q2adPW9Csk+a8wm1hLxq4HKa2K334UHJ/g==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.7.0.tgz", + "integrity": "sha512-gz81seZkRn3zMnVOc7L5k6F4vQC82gIxmHiL+GedK+A37XI/X26AASU3zxvORnqQbwQYXQ+AEVckxBmFlz3v2g==", "cpu": [ "ia32" ], @@ -2067,9 +2067,9 @@ } }, "node_modules/@swc/core-win32-x64-msvc": { - "version": "1.4.17", - "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.4.17.tgz", - "integrity": "sha512-jFkOnGQamtVDBm3MF5Kq1lgW8vx4Rm1UvJWRUfg+0gx7Uc3Jp3QMFeMNw/rDNQYRDYPG3yunCC+2463ycd5+dg==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.7.0.tgz", + "integrity": "sha512-b5Fd1xEOw9uqBpj2lqsaR4Iq9UhiL84hNDcEsi6DQA7Y1l85waQAslTbS0E4/pJ1PISAs0jW0zIGLco1eaWBOg==", "cpu": [ "x64" ], @@ -2089,29 +2089,29 @@ "dev": true }, "node_modules/@swc/types": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.6.tgz", - "integrity": "sha512-/JLo/l2JsT/LRd80C3HfbmVpxOAJ11FO2RCEslFrgzLltoP9j8XIbsyDcfCt2WWyX+CM96rBoNM+IToAkFOugg==", + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.12.tgz", + "integrity": "sha512-wBJA+SdtkbFhHjTMYH+dEH1y4VpfGdAc2Kw/LK09i9bXd/K6j6PkDcFCEzb6iVfZMkPRrl/q0e3toqTAJdkIVA==", "dev": true, "dependencies": { "@swc/counter": "^0.1.3" } }, "node_modules/@tanstack/query-core": { - "version": "5.35.1", - "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.35.1.tgz", - "integrity": "sha512-0Dnpybqb8+ps6WgqBnqFEC+1F/xLvUosRAq+wiGisTgolOZzqZfkE2995dEXmhuzINiTM7/a6xSGznU0NIvBkw==", + "version": "5.51.9", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.51.9.tgz", + "integrity": "sha512-HsAwaY5J19MD18ykZDS3aVVh+bAt0i7m6uQlFC2b77DLV9djo+xEN7MWQAQQTR8IM+7r/zbozTQ7P0xr0bHuew==", "funding": { "type": "github", "url": "https://github.com/sponsors/tannerlinsley" } }, "node_modules/@tanstack/react-query": { - "version": "5.35.1", - "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.35.1.tgz", - "integrity": "sha512-i2T7m2ffQdNqlX3pO+uMsnQ0H4a59Ens2GxtlMsRiOvdSB4SfYmHb27MnvFV8rGmtWRaa4gPli0/rpDoSS5LbQ==", + "version": "5.51.11", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.51.11.tgz", + "integrity": "sha512-4Kq2x0XpDlpvSnaLG+8pHNH60zEc3mBvb3B2tOMDjcPCi/o+Du3p/9qpPLwJOTliVxxPJAP27fuIhLrsRdCr7A==", "dependencies": { - "@tanstack/query-core": "5.35.1" + "@tanstack/query-core": "5.51.9" }, "funding": { "type": "github", @@ -2135,16 +2135,10 @@ "@types/unist": "^2" } }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true - }, "node_modules/@types/node": { - "version": "20.12.8", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.8.tgz", - "integrity": "sha512-NU0rJLJnshZWdE/097cdCBbyW1h4hEg0xpovcoAQYHl8dnEyp/NAOiE45pvc+Bd1Dt+2r94v2eGFpQJ4R7g+2w==", + "version": "20.14.11", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.11.tgz", + "integrity": "sha512-kprQpL8MMeszbz6ojB5/tU8PLN4kesnN8Gjzw349rDlNgsSzg90lAVj3llK99Dh7JON+t9AuscPPFW6mPbTnSA==", "dev": true, "dependencies": { "undici-types": "~5.26.4" @@ -2157,9 +2151,9 @@ "devOptional": true }, "node_modules/@types/react": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.1.tgz", - "integrity": "sha512-V0kuGBX3+prX+DQ/7r2qsv1NsdfnCLnTgnRJ1pYnxykBhGMz+qj+box5lq7XsO5mtZsBqpjwwTu/7wszPfMBcw==", + "version": "18.3.3", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.3.tgz", + "integrity": "sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==", "devOptional": true, "dependencies": { "@types/prop-types": "*", @@ -2175,12 +2169,6 @@ "@types/react": "*" } }, - "node_modules/@types/semver": { - "version": "7.5.8", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", - "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", - "dev": true - }, "node_modules/@types/stylis": { "version": "4.2.5", "resolved": "https://registry.npmjs.org/@types/stylis/-/stylis-4.2.5.tgz", @@ -2192,21 +2180,19 @@ "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.8.0.tgz", - "integrity": "sha512-gFTT+ezJmkwutUPmB0skOj3GZJtlEGnlssems4AjkVweUPGj7jRwwqg0Hhg7++kPGJqKtTYx+R05Ftww372aIg==", + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.17.0.tgz", + "integrity": "sha512-pyiDhEuLM3PuANxH7uNYan1AaFs5XE0zw1hq69JBvGvE7gSuEoQl1ydtEe/XQeoC3GQxLXyOVa5kNOATgM638A==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.8.0", - "@typescript-eslint/type-utils": "7.8.0", - "@typescript-eslint/utils": "7.8.0", - "@typescript-eslint/visitor-keys": "7.8.0", - "debug": "^4.3.4", + "@typescript-eslint/scope-manager": "7.17.0", + "@typescript-eslint/type-utils": "7.17.0", + "@typescript-eslint/utils": "7.17.0", + "@typescript-eslint/visitor-keys": "7.17.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", - "semver": "^7.6.0", "ts-api-utils": "^1.3.0" }, "engines": { @@ -2227,15 +2213,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.8.0.tgz", - "integrity": "sha512-KgKQly1pv0l4ltcftP59uQZCi4HUYswCLbTqVZEJu7uLX8CTLyswqMLqLN+2QFz4jCptqWVV4SB7vdxcH2+0kQ==", + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.17.0.tgz", + "integrity": "sha512-puiYfGeg5Ydop8eusb/Hy1k7QmOU6X3nvsqCgzrB2K4qMavK//21+PzNE8qeECgNOIoertJPUC1SpegHDI515A==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "7.8.0", - "@typescript-eslint/types": "7.8.0", - "@typescript-eslint/typescript-estree": "7.8.0", - "@typescript-eslint/visitor-keys": "7.8.0", + "@typescript-eslint/scope-manager": "7.17.0", + "@typescript-eslint/types": "7.17.0", + "@typescript-eslint/typescript-estree": "7.17.0", + "@typescript-eslint/visitor-keys": "7.17.0", "debug": "^4.3.4" }, "engines": { @@ -2255,13 +2241,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.8.0.tgz", - "integrity": "sha512-viEmZ1LmwsGcnr85gIq+FCYI7nO90DVbE37/ll51hjv9aG+YZMb4WDE2fyWpUR4O/UrhGRpYXK/XajcGTk2B8g==", + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.17.0.tgz", + "integrity": "sha512-0P2jTTqyxWp9HiKLu/Vemr2Rg1Xb5B7uHItdVZ6iAenXmPo4SZ86yOPCJwMqpCyaMiEHTNqizHfsbmCFT1x9SA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.8.0", - "@typescript-eslint/visitor-keys": "7.8.0" + "@typescript-eslint/types": "7.17.0", + "@typescript-eslint/visitor-keys": "7.17.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -2272,13 +2258,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.8.0.tgz", - "integrity": "sha512-H70R3AefQDQpz9mGv13Uhi121FNMh+WEaRqcXTX09YEDky21km4dV1ZXJIp8QjXc4ZaVkXVdohvWDzbnbHDS+A==", + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.17.0.tgz", + "integrity": "sha512-XD3aaBt+orgkM/7Cei0XNEm1vwUxQ958AOLALzPlbPqb8C1G8PZK85tND7Jpe69Wualri81PLU+Zc48GVKIMMA==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "7.8.0", - "@typescript-eslint/utils": "7.8.0", + "@typescript-eslint/typescript-estree": "7.17.0", + "@typescript-eslint/utils": "7.17.0", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, @@ -2299,9 +2285,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.8.0.tgz", - "integrity": "sha512-wf0peJ+ZGlcH+2ZS23aJbOv+ztjeeP8uQ9GgwMJGVLx/Nj9CJt17GWgWWoSmoRVKAX2X+7fzEnAjxdvK2gqCLw==", + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.17.0.tgz", + "integrity": "sha512-a29Ir0EbyKTKHnZWbNsrc/gqfIBqYPwj3F2M+jWE/9bqfEHg0AMtXzkbUkOG6QgEScxh2+Pz9OXe11jHDnHR7A==", "dev": true, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -2312,13 +2298,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.8.0.tgz", - "integrity": "sha512-5pfUCOwK5yjPaJQNy44prjCwtr981dO8Qo9J9PwYXZ0MosgAbfEMB008dJ5sNo3+/BN6ytBPuSvXUg9SAqB0dg==", + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.17.0.tgz", + "integrity": "sha512-72I3TGq93t2GoSBWI093wmKo0n6/b7O4j9o8U+f65TVD0FS6bI2180X5eGEr8MA8PhKMvYe9myZJquUT2JkCZw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.8.0", - "@typescript-eslint/visitor-keys": "7.8.0", + "@typescript-eslint/types": "7.17.0", + "@typescript-eslint/visitor-keys": "7.17.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -2340,18 +2326,15 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.8.0.tgz", - "integrity": "sha512-L0yFqOCflVqXxiZyXrDr80lnahQfSOfc9ELAAZ75sqicqp2i36kEZZGuUymHNFoYOqxRT05up760b4iGsl02nQ==", + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.17.0.tgz", + "integrity": "sha512-r+JFlm5NdB+JXc7aWWZ3fKSm1gn0pkswEwIYsrGPdsT2GjsRATAKXiNtp3vgAAO1xZhX8alIOEQnNMl3kbTgJw==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.15", - "@types/semver": "^7.5.8", - "@typescript-eslint/scope-manager": "7.8.0", - "@typescript-eslint/types": "7.8.0", - "@typescript-eslint/typescript-estree": "7.8.0", - "semver": "^7.6.0" + "@typescript-eslint/scope-manager": "7.17.0", + "@typescript-eslint/types": "7.17.0", + "@typescript-eslint/typescript-estree": "7.17.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -2365,12 +2348,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.8.0.tgz", - "integrity": "sha512-q4/gibTNBQNA0lGyYQCmWRS5D15n8rXh4QjK3KV+MBPlTYHpfBUT3D3PaPR/HeNiI9W6R7FvlkcGhNyAoP+caA==", + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.17.0.tgz", + "integrity": "sha512-RVGC9UhPOCsfCdI9pU++K4nD7to+jTcMIbXTSOcrLqUEW6gF2pU1UUbYJKc9cvcRSK1UDeMJ7pdMxf4bhMpV/A==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.8.0", + "@typescript-eslint/types": "7.17.0", "eslint-visitor-keys": "^3.4.3" }, "engines": { @@ -2388,21 +2371,21 @@ "dev": true }, "node_modules/@vitejs/plugin-react-swc": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-react-swc/-/plugin-react-swc-3.6.0.tgz", - "integrity": "sha512-XFRbsGgpGxGzEV5i5+vRiro1bwcIaZDIdBRP16qwm+jP68ue/S8FJTBEgOeojtVDYrbSua3XFp71kC8VJE6v+g==", + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react-swc/-/plugin-react-swc-3.7.0.tgz", + "integrity": "sha512-yrknSb3Dci6svCd/qhHqhFPDSw0QtjumcqdKMoNNzmOl5lMXTTiqzjWtG4Qask2HdvvzaNgSunbQGet8/GrKdA==", "dev": true, "dependencies": { - "@swc/core": "^1.3.107" + "@swc/core": "^1.5.7" }, "peerDependencies": { "vite": "^4 || ^5" } }, "node_modules/acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -2549,9 +2532,9 @@ } }, "node_modules/axios": { - "version": "1.6.8", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.8.tgz", - "integrity": "sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==", + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.2.tgz", + "integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==", "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", @@ -2583,20 +2566,20 @@ } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" } }, "node_modules/browserslist": { - "version": "4.23.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", - "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", + "version": "4.23.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.2.tgz", + "integrity": "sha512-qkqSyistMYdxAcw+CzbZwlBy8AGmS/eEWs+sEV5TnLRGDOL+C5M2EnH6tlZyg0YoAxGJAFKh61En9BR941GnHA==", "dev": true, "funding": [ { @@ -2613,10 +2596,10 @@ } ], "dependencies": { - "caniuse-lite": "^1.0.30001587", - "electron-to-chromium": "^1.4.668", + "caniuse-lite": "^1.0.30001640", + "electron-to-chromium": "^1.4.820", "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.13" + "update-browserslist-db": "^1.1.0" }, "bin": { "browserslist": "cli.js" @@ -2651,9 +2634,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001615", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001615.tgz", - "integrity": "sha512-1IpazM5G3r38meiae0bHRnPhz+CBQ3ZLqbQMtrg+AsTPKAXgW38JNsXkyZ+v8waCsDmPq87lmfun5Q2AGysNEQ==", + "version": "1.0.30001643", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001643.tgz", + "integrity": "sha512-ERgWGNleEilSrHM6iUz/zJNSQTP8Mr21wDWpdgvRwcTXGAq6jMtOUPP4dqFPTdKqZ2wKTdtB+uucZ3MRpAUSmg==", "dev": true, "funding": [ { @@ -2713,78 +2696,425 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/class-variance-authority": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.0.tgz", + "integrity": "sha512-jFI8IQw4hczaL4ALINxqLEXQbWcNjoSkloa4IaufXCJr6QawJyw7tuRysRsrE8w2p/4gGaxKIt/hX3qz/IbD1A==", + "dependencies": { + "clsx": "2.0.0" + }, + "funding": { + "url": "https://joebell.co.uk" + } + }, + "node_modules/class-variance-authority/node_modules/clsx": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz", + "integrity": "sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==", + "engines": { + "node": ">=6" + } + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/cmdk": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/cmdk/-/cmdk-1.0.0.tgz", + "integrity": "sha512-gDzVf0a09TvoJ5jnuPvygTB77+XdOSwEmJ88L6XPFPlv7T3RxbP9jgenfylrAMD0+Le1aO0nVjQUzl2g+vjz5Q==", + "dependencies": { + "@radix-ui/react-dialog": "1.0.5", + "@radix-ui/react-primitive": "1.0.3" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/cmdk/node_modules/@radix-ui/primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.0.1.tgz", + "integrity": "sha512-yQ8oGX2GVsEYMWGxcovu1uGWPCxV5BFfeeYxqPmuAzUyLT9qmaMXSAhXpb0WrspIeqYzdJpkh2vHModJPgRIaw==", + "dependencies": { + "@babel/runtime": "^7.13.10" + } + }, + "node_modules/cmdk/node_modules/@radix-ui/react-compose-refs": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.0.1.tgz", + "integrity": "sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw==", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/cmdk/node_modules/@radix-ui/react-context": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.0.1.tgz", + "integrity": "sha512-ebbrdFoYTcuZ0v4wG5tedGnp9tzcV8awzsxYph7gXUyvnNLuTIcCk1q17JEbnVhXAKG9oX3KtchwiMIAYp9NLg==", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/cmdk/node_modules/@radix-ui/react-dialog": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.0.5.tgz", + "integrity": "sha512-GjWJX/AUpB703eEBanuBnIWdIXg6NvJFCXcNlSZk4xdszCdhrJgBoUd1cGk67vFO+WdA2pfI/plOpqz/5GUP6Q==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-dismissable-layer": "1.0.5", + "@radix-ui/react-focus-guards": "1.0.1", + "@radix-ui/react-focus-scope": "1.0.4", + "@radix-ui/react-id": "1.0.1", + "@radix-ui/react-portal": "1.0.4", + "@radix-ui/react-presence": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-slot": "1.0.2", + "@radix-ui/react-use-controllable-state": "1.0.1", + "aria-hidden": "^1.1.1", + "react-remove-scroll": "2.5.5" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/cmdk/node_modules/@radix-ui/react-dismissable-layer": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.0.5.tgz", + "integrity": "sha512-aJeDjQhywg9LBu2t/At58hCvr7pEm0o2Ke1x33B+MhjNmmZ17sy4KImo0KPLgsnc/zN7GPdce8Cnn0SWvwZO7g==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-use-callback-ref": "1.0.1", + "@radix-ui/react-use-escape-keydown": "1.0.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/cmdk/node_modules/@radix-ui/react-focus-guards": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.0.1.tgz", + "integrity": "sha512-Rect2dWbQ8waGzhMavsIbmSVCgYxkXLxxR3ZvCX79JOglzdEy4JXMb98lq4hPxUbLr77nP0UOGf4rcMU+s1pUA==", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/cmdk/node_modules/@radix-ui/react-focus-scope": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.0.4.tgz", + "integrity": "sha512-sL04Mgvf+FmyvZeYfNu1EPAaaxD+aw7cYeIB9L9Fvq8+urhltTRaEo5ysKOpHuKPclsZcSUMKlN05x4u+CINpA==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-use-callback-ref": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/cmdk/node_modules/@radix-ui/react-id": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.0.1.tgz", + "integrity": "sha512-tI7sT/kqYp8p96yGWY1OAnLHrqDgzHefRBKQ2YAkBS5ja7QLcZ9Z/uY7bEjPUatf8RomoXM8/1sMj1IJaE5UzQ==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-layout-effect": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/cmdk/node_modules/@radix-ui/react-portal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.0.4.tgz", + "integrity": "sha512-Qki+C/EuGUVCQTOTD5vzJzJuMUlewbzuKyUy+/iHM2uwGiru9gZeBJtHAPKAEkB5KWGi9mP/CHKcY0wt1aW45Q==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-primitive": "1.0.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/cmdk/node_modules/@radix-ui/react-presence": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.0.1.tgz", + "integrity": "sha512-UXLW4UAbIY5ZjcvzjfRFo5gxva8QirC9hF7wRE4U5gz+TP0DbRk+//qyuAQ1McDxBt1xNMBTaciFGvEmJvAZCg==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-use-layout-effect": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/cmdk/node_modules/@radix-ui/react-primitive": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-1.0.3.tgz", + "integrity": "sha512-yi58uVyoAcK/Nq1inRY56ZSjKypBNKTa/1mcL8qdl6oJeEaDbOldlzrGn7P6Q3Id5d+SYNGc5AJgc4vGhjs5+g==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-slot": "1.0.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/cmdk/node_modules/@radix-ui/react-slot": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.2.tgz", + "integrity": "sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg==", "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.1" }, - "funding": { - "url": "https://paulmillr.com/funding/" + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" }, - "optionalDependencies": { - "fsevents": "~2.3.2" + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/chokidar/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "node_modules/cmdk/node_modules/@radix-ui/react-use-callback-ref": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.0.1.tgz", + "integrity": "sha512-D94LjX4Sp0xJFVaoQOd3OO9k7tpBYNOXdVhkltUbGv2Qb9OXdrg/CpsjlZv7ia14Sylv398LswWBVVu5nqKzAQ==", "dependencies": { - "is-glob": "^4.0.1" + "@babel/runtime": "^7.13.10" }, - "engines": { - "node": ">= 6" + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/class-variance-authority": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.0.tgz", - "integrity": "sha512-jFI8IQw4hczaL4ALINxqLEXQbWcNjoSkloa4IaufXCJr6QawJyw7tuRysRsrE8w2p/4gGaxKIt/hX3qz/IbD1A==", + "node_modules/cmdk/node_modules/@radix-ui/react-use-controllable-state": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.0.1.tgz", + "integrity": "sha512-Svl5GY5FQeN758fWKrjM6Qb7asvXeiZltlT4U2gVfl8Gx5UAv2sMR0LWo8yhsIZh2oQ0eFdZ59aoOOMV7b47VA==", "dependencies": { - "clsx": "2.0.0" + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-callback-ref": "1.0.1" }, - "funding": { - "url": "https://joebell.co.uk" + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/class-variance-authority/node_modules/clsx": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz", - "integrity": "sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==", - "engines": { - "node": ">=6" + "node_modules/cmdk/node_modules/@radix-ui/react-use-escape-keydown": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.0.3.tgz", + "integrity": "sha512-vyL82j40hcFicA+M4Ex7hVkB9vHgSse1ZWomAqV2Je3RleKGO5iM8KMOEtfoSB0PnIelMd2lATjTGMYqN5ylTg==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-callback-ref": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/clsx": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", - "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", - "engines": { - "node": ">=6" + "node_modules/cmdk/node_modules/@radix-ui/react-use-layout-effect": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.0.1.tgz", + "integrity": "sha512-v/5RegiJWYdoCvMnITBkNNx6bCj20fiaJnWtRkU18yITptraXjffz5Qbn05uOiQnOvi+dbkznkoaMltz1GnszQ==", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/cmdk": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/cmdk/-/cmdk-1.0.0.tgz", - "integrity": "sha512-gDzVf0a09TvoJ5jnuPvygTB77+XdOSwEmJ88L6XPFPlv7T3RxbP9jgenfylrAMD0+Le1aO0nVjQUzl2g+vjz5Q==", + "node_modules/cmdk/node_modules/react-remove-scroll": { + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.5.tgz", + "integrity": "sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw==", "dependencies": { - "@radix-ui/react-dialog": "1.0.5", - "@radix-ui/react-primitive": "1.0.3" + "react-remove-scroll-bar": "^2.3.3", + "react-style-singleton": "^2.2.1", + "tslib": "^2.1.0", + "use-callback-ref": "^1.3.0", + "use-sidecar": "^1.1.2" + }, + "engines": { + "node": ">=10" }, "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, "node_modules/color-convert": { @@ -2885,9 +3215,9 @@ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" }, "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", "dev": true, "dependencies": { "ms": "2.1.2" @@ -2960,9 +3290,9 @@ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" }, "node_modules/electron-to-chromium": { - "version": "1.4.755", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.755.tgz", - "integrity": "sha512-9nop+3jZxSHIxe1EzEUcjDXzK+3qOv3fY5w0sE88nIZUntbv1aXWmoxGWlklX5XSO4txCpLssWkUSh8RQPovBg==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.0.tgz", + "integrity": "sha512-Vb3xHHYnLseK8vlMJQKJYXJ++t4u1/qJ3vykuVrVjvdiOEhYyT1AuP4x03G8EnPmYvYOhe9T+dADTmthjRQMkA==", "dev": true }, "node_modules/emoji-regex": { @@ -2971,9 +3301,9 @@ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" }, "node_modules/esbuild": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", - "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", "dev": true, "hasInstallScript": true, "bin": { @@ -2983,29 +3313,29 @@ "node": ">=12" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.20.2", - "@esbuild/android-arm": "0.20.2", - "@esbuild/android-arm64": "0.20.2", - "@esbuild/android-x64": "0.20.2", - "@esbuild/darwin-arm64": "0.20.2", - "@esbuild/darwin-x64": "0.20.2", - "@esbuild/freebsd-arm64": "0.20.2", - "@esbuild/freebsd-x64": "0.20.2", - "@esbuild/linux-arm": "0.20.2", - "@esbuild/linux-arm64": "0.20.2", - "@esbuild/linux-ia32": "0.20.2", - "@esbuild/linux-loong64": "0.20.2", - "@esbuild/linux-mips64el": "0.20.2", - "@esbuild/linux-ppc64": "0.20.2", - "@esbuild/linux-riscv64": "0.20.2", - "@esbuild/linux-s390x": "0.20.2", - "@esbuild/linux-x64": "0.20.2", - "@esbuild/netbsd-x64": "0.20.2", - "@esbuild/openbsd-x64": "0.20.2", - "@esbuild/sunos-x64": "0.20.2", - "@esbuild/win32-arm64": "0.20.2", - "@esbuild/win32-ia32": "0.20.2", - "@esbuild/win32-x64": "0.20.2" + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" } }, "node_modules/escalade": { @@ -3097,9 +3427,9 @@ } }, "node_modules/eslint-plugin-react-refresh": { - "version": "0.4.6", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.6.tgz", - "integrity": "sha512-NjGXdm7zgcKRkKMua34qVO9doI7VOxZ6ancSvBELJSSoX97jyndXcSoa8XBh69JoB31dNz3EEzlMcizZl7LaMA==", + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.9.tgz", + "integrity": "sha512-QK49YrBAo5CLNLseZ7sZgvgTy21E6NEw22eZqc4teZfH8pxV3yXc9XXOYfUI6JNpw7mfHNkAeWtBxrTyykB6HA==", "dev": true, "peerDependencies": { "eslint": ">=7" @@ -3173,9 +3503,9 @@ } }, "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", "dev": true, "dependencies": { "estraverse": "^5.1.0" @@ -3291,9 +3621,9 @@ } }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -3357,9 +3687,9 @@ } }, "node_modules/foreground-child": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", - "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.2.1.tgz", + "integrity": "sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==", "dependencies": { "cross-spawn": "^7.0.0", "signal-exit": "^4.0.1" @@ -3406,9 +3736,9 @@ } }, "node_modules/framer-motion": { - "version": "11.1.9", - "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-11.1.9.tgz", - "integrity": "sha512-flECDIPV4QDNcOrDafVFiIazp8X01HFpzc01eDKJsdNH/wrATcYydJSH9JbPWMS8UD5lZlw+J1sK8LG2kICgqw==", + "version": "11.3.12", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-11.3.12.tgz", + "integrity": "sha512-ulc8EHFZpKIj+NAyJv+alLUEUIXZKOQnE+JHkGjfoIcxbZwV+CSvfOoACaOpAW4nVznFMF2y3r+ViUtPtP4qiw==", "dependencies": { "tslib": "^2.4.0" }, @@ -3468,6 +3798,7 @@ "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, "dependencies": { "fs.realpath": "^1.0.0", @@ -3657,6 +3988,7 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", "dev": true, "dependencies": { "once": "^1.3.0", @@ -3711,11 +4043,14 @@ } }, "node_modules/is-core-module": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", - "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.0.tgz", + "integrity": "sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA==", "dependencies": { - "hasown": "^2.0.0" + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -3789,15 +4124,12 @@ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, "node_modules/jackspeak": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", - "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", "dependencies": { "@isaacs/cliui": "^8.0.2" }, - "engines": { - "node": ">=14" - }, "funding": { "url": "https://github.com/sponsors/isaacs" }, @@ -3806,9 +4138,9 @@ } }, "node_modules/jiti": { - "version": "1.21.0", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.0.tgz", - "integrity": "sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==", + "version": "1.21.6", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz", + "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==", "bin": { "jiti": "bin/jiti.js" } @@ -3929,16 +4261,9 @@ } }, "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==" }, "node_modules/lucide-react": { "version": "0.378.0", @@ -3957,11 +4282,11 @@ } }, "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", + "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", "dependencies": { - "braces": "^3.0.2", + "braces": "^3.0.3", "picomatch": "^2.3.1" }, "engines": { @@ -3996,9 +4321,9 @@ } }, "node_modules/minimatch": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", - "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -4010,9 +4335,9 @@ } }, "node_modules/minipass": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", - "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", "engines": { "node": ">=16 || 14 >=14.17" } @@ -4057,9 +4382,9 @@ "dev": true }, "node_modules/node-releases": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", "dev": true }, "node_modules/normalize-path": { @@ -4151,6 +4476,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/package-json-from-dist": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", + "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==" + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -4212,28 +4542,20 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, "node_modules/path-scurry": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.2.tgz", - "integrity": "sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": ">=16 || 14 >=14.18" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/path-scurry/node_modules/lru-cache": { - "version": "10.2.2", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.2.tgz", - "integrity": "sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==", - "engines": { - "node": "14 || >=16.14" - } - }, "node_modules/path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", @@ -4244,9 +4566,9 @@ } }, "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==" }, "node_modules/picomatch": { "version": "2.3.1", @@ -4276,9 +4598,9 @@ } }, "node_modules/postcss": { - "version": "8.4.38", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", - "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", + "version": "8.4.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz", + "integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==", "funding": [ { "type": "opencollective", @@ -4295,7 +4617,7 @@ ], "dependencies": { "nanoid": "^3.3.7", - "picocolors": "^1.0.0", + "picocolors": "^1.0.1", "source-map-js": "^1.2.0" }, "engines": { @@ -4371,9 +4693,9 @@ } }, "node_modules/postcss-load-config/node_modules/lilconfig": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.1.tgz", - "integrity": "sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz", + "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==", "engines": { "node": ">=14" }, @@ -4382,27 +4704,33 @@ } }, "node_modules/postcss-nested": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz", - "integrity": "sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", + "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "dependencies": { - "postcss-selector-parser": "^6.0.11" + "postcss-selector-parser": "^6.1.1" }, "engines": { "node": ">=12.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, "peerDependencies": { "postcss": "^8.2.14" } }, "node_modules/postcss-selector-parser": { - "version": "6.0.16", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.16.tgz", - "integrity": "sha512-A0RVJrX+IUkVZbW3ClroRWurercFhieevHB38sr2+l9eUClMqome3LmEmnhlNy+5Mr2EYN6B2Kaw9wYdd+VHiw==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.1.tgz", + "integrity": "sha512-b4dlw/9V8A71rLIDsSwVmak9z2DuBUB7CA1/wSdelNEzqsjoSPeADTWNO09lpH49Diy3/JIZ2bSPB1dI3LJCHg==", "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -4519,9 +4847,9 @@ } }, "node_modules/react-hook-form": { - "version": "7.51.4", - "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.51.4.tgz", - "integrity": "sha512-V14i8SEkh+V1gs6YtD0hdHYnoL4tp/HX/A45wWQN15CYr9bFRmmRdYStSO5L65lCCZRF+kYiSKhm9alqbcdiVA==", + "version": "7.52.1", + "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.52.1.tgz", + "integrity": "sha512-uNKIhaoICJ5KQALYZ4TOaOLElyM+xipord+Ha3crEFhTntdLvWZqVY49Wqd/0GiVCA/f9NjemLeiNPjG7Hpurg==", "engines": { "node": ">=12.22.0" }, @@ -4530,7 +4858,7 @@ "url": "https://opencollective.com/react-hook-form" }, "peerDependencies": { - "react": "^16.8.0 || ^17 || ^18" + "react": "^16.8.0 || ^17 || ^18 || ^19" } }, "node_modules/react-hot-toast": { @@ -4549,11 +4877,11 @@ } }, "node_modules/react-remove-scroll": { - "version": "2.5.5", - "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.5.tgz", - "integrity": "sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw==", + "version": "2.5.7", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.7.tgz", + "integrity": "sha512-FnrTWO4L7/Bhhf3CYBNArEG/yROV0tKmTv7/3h9QCFvH6sndeFf1wPqOcbFVu5VAulS5dV1wGT3GZZ/1GawqiA==", "dependencies": { - "react-remove-scroll-bar": "^2.3.3", + "react-remove-scroll-bar": "^2.3.4", "react-style-singleton": "^2.2.1", "tslib": "^2.1.0", "use-callback-ref": "^1.3.0", @@ -4594,11 +4922,11 @@ } }, "node_modules/react-router": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.23.0.tgz", - "integrity": "sha512-wPMZ8S2TuPadH0sF5irFGjkNLIcRvOSaEe7v+JER8508dyJumm6XZB1u5kztlX0RVq6AzRVndzqcUh6sFIauzA==", + "version": "6.25.1", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.25.1.tgz", + "integrity": "sha512-u8ELFr5Z6g02nUtpPAggP73Jigj1mRePSwhS/2nkTrlPU5yEkH1vYzWNyvSnSzeeE2DNqWdH+P8OhIh9wuXhTw==", "dependencies": { - "@remix-run/router": "1.16.0" + "@remix-run/router": "1.18.0" }, "engines": { "node": ">=14.0.0" @@ -4608,12 +4936,12 @@ } }, "node_modules/react-router-dom": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.23.0.tgz", - "integrity": "sha512-Q9YaSYvubwgbal2c9DJKfx6hTNoBp3iJDsl+Duva/DwxoJH+OTXkxGpql4iUK2sla/8z4RpjAm6EWx1qUDuopQ==", + "version": "6.25.1", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.25.1.tgz", + "integrity": "sha512-0tUDpbFvk35iv+N89dWNrJp+afLgd+y4VtorJZuOCXK0kkCWjEvb3vTJM++SYvMEpbVwXKf3FjeVveVEb6JpDQ==", "dependencies": { - "@remix-run/router": "1.16.0", - "react-router": "6.23.0" + "@remix-run/router": "1.18.0", + "react-router": "6.25.1" }, "engines": { "node": ">=14.0.0" @@ -4744,6 +5072,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", "dev": true, "dependencies": { "glob": "^7.1.3" @@ -4756,9 +5085,9 @@ } }, "node_modules/rollup": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.17.2.tgz", - "integrity": "sha512-/9ClTJPByC0U4zNLowV1tMBe8yMEAxewtR3cUNX5BoEpGH3dQEWpJLr6CLp0fPdYRF/fzVOgvDb1zXuakwF5kQ==", + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.19.0.tgz", + "integrity": "sha512-5r7EYSQIowHsK4eTZ0Y81qpZuJz+MUuYeqmmYmRMl1nwhdmbiYqt5jwzf6u7wyOzJgYqtCRMtVRKOtHANBz7rA==", "dev": true, "dependencies": { "@types/estree": "1.0.5" @@ -4771,22 +5100,22 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.17.2", - "@rollup/rollup-android-arm64": "4.17.2", - "@rollup/rollup-darwin-arm64": "4.17.2", - "@rollup/rollup-darwin-x64": "4.17.2", - "@rollup/rollup-linux-arm-gnueabihf": "4.17.2", - "@rollup/rollup-linux-arm-musleabihf": "4.17.2", - "@rollup/rollup-linux-arm64-gnu": "4.17.2", - "@rollup/rollup-linux-arm64-musl": "4.17.2", - "@rollup/rollup-linux-powerpc64le-gnu": "4.17.2", - "@rollup/rollup-linux-riscv64-gnu": "4.17.2", - "@rollup/rollup-linux-s390x-gnu": "4.17.2", - "@rollup/rollup-linux-x64-gnu": "4.17.2", - "@rollup/rollup-linux-x64-musl": "4.17.2", - "@rollup/rollup-win32-arm64-msvc": "4.17.2", - "@rollup/rollup-win32-ia32-msvc": "4.17.2", - "@rollup/rollup-win32-x64-msvc": "4.17.2", + "@rollup/rollup-android-arm-eabi": "4.19.0", + "@rollup/rollup-android-arm64": "4.19.0", + "@rollup/rollup-darwin-arm64": "4.19.0", + "@rollup/rollup-darwin-x64": "4.19.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.19.0", + "@rollup/rollup-linux-arm-musleabihf": "4.19.0", + "@rollup/rollup-linux-arm64-gnu": "4.19.0", + "@rollup/rollup-linux-arm64-musl": "4.19.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.19.0", + "@rollup/rollup-linux-riscv64-gnu": "4.19.0", + "@rollup/rollup-linux-s390x-gnu": "4.19.0", + "@rollup/rollup-linux-x64-gnu": "4.19.0", + "@rollup/rollup-linux-x64-musl": "4.19.0", + "@rollup/rollup-win32-arm64-msvc": "4.19.0", + "@rollup/rollup-win32-ia32-msvc": "4.19.0", + "@rollup/rollup-win32-x64-msvc": "4.19.0", "fsevents": "~2.3.2" } }, @@ -4821,13 +5150,10 @@ } }, "node_modules/semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, "bin": { "semver": "bin/semver.js" }, @@ -4992,9 +5318,9 @@ } }, "node_modules/styled-components": { - "version": "6.1.11", - "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.1.11.tgz", - "integrity": "sha512-Ui0jXPzbp1phYij90h12ksljKGqF8ncGx+pjrNPsSPhbUUjWT2tD1FwGo2LF6USCnbrsIhNngDfodhxbegfEOA==", + "version": "6.1.12", + "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.1.12.tgz", + "integrity": "sha512-n/O4PzRPhbYI0k1vKKayfti3C/IGcPf+DqcrOB7O/ab9x4u/zjqraneT5N45+sIe87cxrCApXM8Bna7NYxwoTA==", "dependencies": { "@emotion/is-prop-valid": "1.2.2", "@emotion/unitless": "0.8.1", @@ -5018,6 +5344,38 @@ "react-dom": ">= 16.8.0" } }, + "node_modules/styled-components/node_modules/postcss": { + "version": "8.4.38", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", + "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.0", + "source-map-js": "^1.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/styled-components/node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + }, "node_modules/stylis": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.2.tgz", @@ -5045,22 +5403,20 @@ } }, "node_modules/sucrase/node_modules/glob": { - "version": "10.3.12", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.12.tgz", - "integrity": "sha512-TCNv8vJ+xz4QiqTpfOJA7HvYv+tNIRHKfUWw/q+v2jdgN4ebz+KY9tGx5J4rHP0o84mNP+ApH66HRX8us3Khqg==", + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", "dependencies": { "foreground-child": "^3.1.0", - "jackspeak": "^2.3.6", - "minimatch": "^9.0.1", - "minipass": "^7.0.4", - "path-scurry": "^1.10.2" + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, "funding": { "url": "https://github.com/sponsors/isaacs" } @@ -5089,21 +5445,18 @@ } }, "node_modules/tailwind-merge": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.3.0.tgz", - "integrity": "sha512-vkYrLpIP+lgR0tQCG6AP7zZXCTLc1Lnv/CCRT3BqJ9CZ3ui2++GPaGb1x/ILsINIMSYqqvrpqjUFsMNLlW99EA==", - "dependencies": { - "@babel/runtime": "^7.24.1" - }, + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.4.0.tgz", + "integrity": "sha512-49AwoOQNKdqKPd9CViyH5wJoSKsCDjUlzL8DxuGp3P1FsGY36NJDAa18jLZcaHAUUuTj+JB8IAo8zWgBNvBF7A==", "funding": { "type": "github", "url": "https://github.com/sponsors/dcastil" } }, "node_modules/tailwindcss": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.3.tgz", - "integrity": "sha512-U7sxQk/n397Bmx4JHbJx/iSOOv5G+II3f1kpLpY2QeUv5DcPdcTsYLlusZfq1NthHS1c1cZoyFmmkex1rzke0A==", + "version": "3.4.6", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.6.tgz", + "integrity": "sha512-1uRHzPB+Vzu57ocybfZ4jh5Q3SdlH7XW23J5sQoM9LhE9eIOlzxer/3XPSsycvih3rboRsvt0QCmzSrqyOYUIA==", "dependencies": { "@alloc/quick-lru": "^5.2.0", "arg": "^5.0.2", @@ -5198,9 +5551,9 @@ "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==" }, "node_modules/tslib": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/type-check": { "version": "0.4.0", @@ -5227,9 +5580,9 @@ } }, "node_modules/typescript": { - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", - "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", + "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -5246,9 +5599,9 @@ "dev": true }, "node_modules/update-browserslist-db": { - "version": "1.0.14", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.14.tgz", - "integrity": "sha512-JixKH8GR2pWYshIPUg/NujK3JO7JiqEEUiNArE86NQyrgUuZeTlZQN3xuS/yiV5Kb48ev9K6RqNkaJjXsdg7Jw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", + "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", "dev": true, "funding": [ { @@ -5266,7 +5619,7 @@ ], "dependencies": { "escalade": "^3.1.2", - "picocolors": "^1.0.0" + "picocolors": "^1.0.1" }, "bin": { "update-browserslist-db": "cli.js" @@ -5343,13 +5696,13 @@ } }, "node_modules/vite": { - "version": "5.2.11", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.11.tgz", - "integrity": "sha512-HndV31LWW05i1BLPMUCE1B9E9GFbOu1MbenhS58FuK6owSO5qHm7GiCotrNY1YE5rMeQSFBGmT5ZaLEjFizgiQ==", + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.4.tgz", + "integrity": "sha512-Cw+7zL3ZG9/NZBB8C+8QbQZmR54GwqIz+WMI4b3JgdYJvX+ny9AjJXqkGQlDXSXRP9rP0B4tbciRMOVEKulVOA==", "dev": true, "dependencies": { - "esbuild": "^0.20.1", - "postcss": "^8.4.38", + "esbuild": "^0.21.3", + "postcss": "^8.4.39", "rollup": "^4.13.0" }, "bin": { @@ -5521,16 +5874,10 @@ "node": ">=0.4" } }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, "node_modules/yaml": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.2.tgz", - "integrity": "sha512-B3VqDZ+JAg1nZpaEmWtTXUlBneoGx6CPM9b0TENK6aoSu5t73dItudwdgmi6tHlIZZId4dZ9skcAQ2UbcyAeVA==", + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.5.tgz", + "integrity": "sha512-aBx2bnqDzVOyNKfsysjA2ms5ZlnjSAW2eG3/L5G/CSujfjLJTJsEw1bGw8kCf04KodQWk1pxlGnZ56CRxiawmg==", "bin": { "yaml": "bin.mjs" }, @@ -5551,9 +5898,9 @@ } }, "node_modules/zod": { - "version": "3.23.6", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.6.tgz", - "integrity": "sha512-RTHJlZhsRbuA8Hmp/iNL7jnfc4nZishjsanDAfEY1QpDQZCahUp3xDzl+zfweE9BklxMUcgBgS1b7Lvie/ZVwA==", + "version": "3.23.8", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz", + "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==", "funding": { "url": "https://github.com/sponsors/colinhacks" } diff --git a/app/frontend/package.json b/app/frontend/package.json index d2fd9bf9..8e8ffc02 100644 --- a/app/frontend/package.json +++ b/app/frontend/package.json @@ -11,18 +11,20 @@ }, "dependencies": { "@hookform/resolvers": "^3.3.4", + "@radix-ui/react-aspect-ratio": "^1.1.0", "@radix-ui/react-collapsible": "^1.0.3", "@radix-ui/react-dialog": "^1.0.5", "@radix-ui/react-dropdown-menu": "^2.0.6", "@radix-ui/react-icons": "^1.3.0", "@radix-ui/react-label": "^2.0.2", + "@radix-ui/react-menubar": "^1.1.1", "@radix-ui/react-navigation-menu": "^1.1.4", "@radix-ui/react-popover": "^1.0.7", "@radix-ui/react-progress": "^1.0.3", "@radix-ui/react-scroll-area": "^1.0.5", "@radix-ui/react-select": "^2.0.0", "@radix-ui/react-separator": "^1.0.3", - "@radix-ui/react-slot": "^1.0.2", + "@radix-ui/react-slot": "^1.1.0", "@radix-ui/react-tooltip": "^1.0.7", "@tanstack/react-query": "^5.35.1", "axios": "^1.6.8", diff --git a/app/frontend/src/api/modelsDeployedApis.ts b/app/frontend/src/api/modelsDeployedApis.ts index 75c2752e..d6087f04 100644 --- a/app/frontend/src/api/modelsDeployedApis.ts +++ b/app/frontend/src/api/modelsDeployedApis.ts @@ -115,13 +115,16 @@ export const handleRedeploy = (modelName: string): void => { export const handleChatUI = ( modelID: string, + modelName: string, navigate: NavigateFunction ): void => { console.log(`ChatUI button clicked for model: ${modelID}`); - console.log("Opening Chat UI for model"); - customToast.success(`Chat UI for model ${modelID} opened.`); + console.log(`Opening Chat UI for model: ${modelName}`); + customToast.success(`Chat UI for model ${modelID} (${modelName}) opened.`); - navigate("/chat-ui", { state: { containerID: modelID } }); + navigate("/chat-ui", { + state: { containerID: modelID, modelName: modelName }, + }); console.log("Navigated to chat-ui page"); }; diff --git a/app/frontend/src/assets/tt_line_graphics_1.png b/app/frontend/src/assets/tt_line_graphics_1.png new file mode 100644 index 0000000000000000000000000000000000000000..d572ba976773e986dc27c041be41d4f115186016 GIT binary patch literal 73254 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�cbWbH`XLw?=#1RyTzC{i3=bgHGcBXl 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 literal 0 HcmV?d00001 diff --git a/app/frontend/src/components/ChatComponent.tsx b/app/frontend/src/components/ChatComponent.tsx index 080bcdad..0ae779c5 100644 --- a/app/frontend/src/components/ChatComponent.tsx +++ b/app/frontend/src/components/ChatComponent.tsx @@ -4,6 +4,7 @@ import { Button } from "./ui/button"; import { ScrollArea } from "./ui/scroll-area"; import { useLocation } from "react-router-dom"; import { Spinner } from "./ui/spinner"; +import { useTheme } from "../providers/ThemeProvider"; import { Smile, Sun, @@ -15,6 +16,21 @@ import { } from "lucide-react"; import { Textarea } from "./ui/textarea"; import logo from "../assets/tt_logo.svg"; +import { + Breadcrumb, + BreadcrumbEllipsis, + BreadcrumbItem, + BreadcrumbLink, + BreadcrumbList, + BreadcrumbPage, + BreadcrumbSeparator, +} from "./ui/breadcrumb"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, +} from "./ui/dropdown-menu"; interface InferenceRequest { deploy_id: string; @@ -30,18 +46,25 @@ const modelAPIURL = "/models-api/"; const inferenceUrl = `${modelAPIURL}/inference/`; const ChatComponent: React.FC = () => { + const { theme } = useTheme(); const location = useLocation(); const [textInput, setTextInput] = useState(""); const [chatHistory, setChatHistory] = useState([]); - const [modelID, setModelID] = useState(location.state.containerID); + const [modelID, setModelID] = useState(null); + const [modelName, setModelName] = useState(null); const [isStreaming, setIsStreaming] = useState(false); const scrollAreaRef = useRef(null); const bottomRef = useRef(null); const [isScrollButtonVisible, setIsScrollButtonVisible] = useState(false); useEffect(() => { - setModelID(location.state.containerID); - }, [location.state.containerID]); + if (location.state) { + setModelID(location.state.containerID); + setModelName(location.state.modelName); + } + }, [location.state]); + + console.log("Model ID:", modelID, "Model Name:", modelName); const scrollToBottom = () => { if (bottomRef.current) { @@ -75,7 +98,6 @@ const ChatComponent: React.FC = () => { const reader = response.body?.getReader(); - // Add user input to chat history setChatHistory((prevHistory) => [ ...prevHistory, { sender: "user", text: textInput }, @@ -108,7 +130,7 @@ const ChatComponent: React.FC = () => { ]; } }); - scrollToBottom(); // Ensure scroll to bottom while streaming + scrollToBottom(); } } @@ -123,12 +145,10 @@ const ChatComponent: React.FC = () => { if (textInput.trim() === "") return; const inferenceRequest: InferenceRequest = { - deploy_id: modelID, + deploy_id: modelID!, text: textInput, }; - console.log("Inference Request:", inferenceRequest); - // Special case for the predefined question if (textInput === "When will Tenstorrent out sell Nvidia?") { setChatHistory((prevHistory) => [ ...prevHistory, @@ -136,7 +156,7 @@ const ChatComponent: React.FC = () => { { sender: "assistant", text: "2024, that was a silly question." }, ]); setTextInput(""); - scrollToBottom(); // Ensure scroll to bottom after adding special response + scrollToBottom(); return; } @@ -151,8 +171,38 @@ const ChatComponent: React.FC = () => { }; return ( -
- +
+ + + + + + Models Deployed + + + + + + + + Toggle menu + + + Model 1 + Model 2 + Model 3 + + + + + + {modelName} + + +
{chatHistory.length === 0 && (
@@ -171,21 +221,27 @@ const ChatComponent: React.FC = () => { onClick={() => setTextInput("Hello, how are you today?")} > - Hello, how are you today? + + Hello, how are you today? + setTextInput("Can you tell me a joke?")} > - Can you tell me a joke? + + Can you tell me a joke? + setTextInput("What's the weather like?")} > - What's the weather like? + + What's the weather like? + { } > - When will Tenstorrent out sell Nvidia? + + When will Tenstorrent out sell Nvidia? +
@@ -207,7 +265,6 @@ const ChatComponent: React.FC = () => { ref={scrollAreaRef} onScroll={handleScroll} > -

Chat Responses:

{chatHistory.map((message, index) => (
{ }`} >
{message.sender === "user" ? ( { className="w-8 h-8 rounded-full mr-2" /> )} - {message.text} +
{message.text}
))} diff --git a/app/frontend/src/components/DarkModeToggle.tsx b/app/frontend/src/components/DarkModeToggle.tsx index 12204981..ad6b1fd2 100644 --- a/app/frontend/src/components/DarkModeToggle.tsx +++ b/app/frontend/src/components/DarkModeToggle.tsx @@ -1,50 +1,31 @@ import { Moon, Sun } from "lucide-react"; import { Button } from "./ui/button"; -import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuItem, - DropdownMenuTrigger, -} from "./ui/dropdown-menu"; import { useTheme } from "../providers/ThemeProvider"; const ModeToggle = () => { const { setTheme, theme } = useTheme(); + const toggleTheme = () => { + setTheme(theme === "dark" ? "light" : "dark"); + }; + return ( - - - - - - setTheme("light")} - className="dark:text-zinc-200 hover:bg-gray-200 dark:hover:bg-zinc-600 dark:hover:text-white" - > - Light - - setTheme("dark")} - className="dark:text-zinc-200 hover:bg-gray-200 dark:hover:bg-zinc-600 dark:hover:text-white" - > - Dark - - - + ); }; diff --git a/app/frontend/src/components/DeployModelStep.tsx b/app/frontend/src/components/DeployModelStep.tsx new file mode 100644 index 00000000..1e7c4175 --- /dev/null +++ b/app/frontend/src/components/DeployModelStep.tsx @@ -0,0 +1,32 @@ +"use client"; +import { Button } from "./ui/button"; +import { useStepper } from "./ui/stepper"; +import { Weight } from "./SelectionSteps"; +import { StepperFormActions } from "./StepperFormActions"; + +export function DeployModelStep({ + handleDeploy, +}: { + selectedModel: string | null; + selectedWeight: string | null; + customWeight: Weight | null; + handleDeploy: () => Promise; +}) { + const { nextStep } = useStepper(); + + const onDeploy = async () => { + const deploySuccess = await handleDeploy(); + if (deploySuccess) { + nextStep(); + } + }; + + return ( + <> +
+ +
+ {}} /> + + ); +} diff --git a/app/frontend/src/components/FirstStepForm.tsx b/app/frontend/src/components/FirstStepForm.tsx new file mode 100644 index 00000000..2d1a5908 --- /dev/null +++ b/app/frontend/src/components/FirstStepForm.tsx @@ -0,0 +1,136 @@ +"use client"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { useForm } from "react-hook-form"; +import * as z from "zod"; +import axios from "axios"; +import { useEffect, useState } from "react"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "./ui/select"; +import { + Form, + FormControl, + FormField, + FormItem, + FormLabel, + FormMessage, +} from "./ui/form"; +import { useStepper } from "./ui/stepper"; +import { customToast } from "./CustomToaster"; +import { StepperFormActions } from "./StepperFormActions"; +import { Model, getModelsUrl } from "./SelectionSteps"; + +const FirstFormSchema = z.object({ + model: z.string().nonempty("Please select a model."), +}); +export function FirstStepForm({ + setSelectedModel, + setFormError, +}: { + setSelectedModel: (model: string) => void; + setFormError: (hasError: boolean) => void; +}) { + const { nextStep } = useStepper(); + const [isSubmitting, setIsSubmitting] = useState(false); + const [models, setModels] = useState([]); + + useEffect(() => { + console.log("fetching models", getModelsUrl); + const fetchModels = async () => { + try { + const response = await axios.get(getModelsUrl); + console.log("fetched models:", response.data); + setModels(response.data); + } catch (error) { + console.error("Error fetching models:", error); + } + }; + + fetchModels(); + }, []); + + const form = useForm>({ + resolver: zodResolver(FirstFormSchema), + defaultValues: { + model: "", + }, + }); + + useEffect(() => { + setFormError(!!form.formState.errors.model); + }, [form.formState.errors]); + + const onSubmit = async (data: z.infer) => { + setIsSubmitting(true); + try { + const selectedModel = models.find((model) => model.name === data.model); + if (selectedModel) { + setSelectedModel(selectedModel.id); + customToast.success("Model Selected!: " + selectedModel.name); + setFormError(false); + nextStep(); + } else { + customToast.error("Model not found!"); + setFormError(true); + } + } finally { + setIsSubmitting(false); + } + }; + + return ( +
+ { + e.preventDefault(); + form.handleSubmit(onSubmit)(); + }} + className="space-y-10" + > + ( + + + Models + + + + {form.formState.errors.model?.message} + + + )} + /> + {}} + isSubmitting={isSubmitting} + /> + + + ); +} diff --git a/app/frontend/src/components/HelpIcon.tsx b/app/frontend/src/components/HelpIcon.tsx index d5515b01..43f33bbb 100644 --- a/app/frontend/src/components/HelpIcon.tsx +++ b/app/frontend/src/components/HelpIcon.tsx @@ -3,11 +3,15 @@ import { HelpCircle } from "lucide-react"; import { Button } from "./ui/button"; import { useTheme } from "../providers/ThemeProvider"; -const HelpIcon: React.FC = () => { +interface HelpIconProps { + toggleSidebar: () => void; +} + +const HelpIcon: React.FC = ({ toggleSidebar }) => { const { theme } = useTheme(); const handleHelpClick = (): void => { - alert("Add link to help docs!"); + toggleSidebar(); }; const iconColor = theme === "dark" ? "text-zinc-200" : "text-gray-600"; diff --git a/app/frontend/src/components/ModelsDeployedTable.tsx b/app/frontend/src/components/ModelsDeployedTable.tsx index fa58c310..8fc931bf 100644 --- a/app/frontend/src/components/ModelsDeployedTable.tsx +++ b/app/frontend/src/components/ModelsDeployedTable.tsx @@ -199,7 +199,9 @@ export function ModelsDeployedTable() { )} - ) : ( - <> - - {activeStep < steps.length - 1 && ( - - )} - - )} -
- ); -} - -function DeployModelStep({ - handleDeploy, -}: { - selectedModel: string | null; - selectedWeight: string | null; - customWeight: Weight | null; - handleDeploy: () => Promise; -}) { - const { nextStep } = useStepper(); - - const onDeploy = async () => { - const deploySuccess = await handleDeploy(); - if (deploySuccess) { - nextStep(); - } - }; - - return ( - <> -
- -
- {}} /> - - ); -} - -function MyStepperFooter({ - removeDynamicSteps, -}: { - removeDynamicSteps: () => void; -}) { - const { hasCompletedAllSteps, resetSteps } = useStepper(); - - const handleReset = () => { - removeDynamicSteps(); - resetSteps(); - }; - - if (!hasCompletedAllSteps) { - return null; - } - - return ( -
- -
- ); -} diff --git a/app/frontend/src/components/SideBar.tsx b/app/frontend/src/components/SideBar.tsx new file mode 100644 index 00000000..e8725581 --- /dev/null +++ b/app/frontend/src/components/SideBar.tsx @@ -0,0 +1,84 @@ +import React, { useState, forwardRef, useImperativeHandle } from "react"; +import { Link } from "react-router-dom"; +import { Menu, CircleX } from "lucide-react"; +import { Card, CardHeader, CardTitle, CardContent } from "./ui/card"; +import { AspectRatio } from "./ui/aspect-ratio"; +import imagePath from "../assets/tt_line_graphics_1.png"; +import { Button } from "./ui/button"; +import { useTheme } from "../providers/ThemeProvider"; + +const Sidebar = forwardRef((_, ref) => { + const [isOpen, setIsOpen] = useState(false); + const { theme } = useTheme(); + + const toggleSidebar = () => { + setIsOpen(!isOpen); + }; + + useImperativeHandle(ref, () => ({ + toggleSidebar, + })); + + return ( +
+
+
+ + Header Image + +
+

Help

+ +
+
+ +
+ +
+ ); +}); + +export default Sidebar; diff --git a/app/frontend/src/components/StepperFooter.tsx b/app/frontend/src/components/StepperFooter.tsx new file mode 100644 index 00000000..040a9943 --- /dev/null +++ b/app/frontend/src/components/StepperFooter.tsx @@ -0,0 +1,45 @@ +import { useStepper } from "./ui/stepper"; +import { Button } from "./ui/button"; +import { Link } from "react-router-dom"; +import { RefreshCw, Package } from "lucide-react"; + +const StepperFooter = ({ + removeDynamicSteps, +}: { + removeDynamicSteps: () => void; +}) => { + const { hasCompletedAllSteps, resetSteps } = useStepper(); + + const handleReset = () => { + removeDynamicSteps(); + resetSteps(); + }; + + if (!hasCompletedAllSteps) { + return null; + } + + return ( +
+ + + +
+ ); +}; + +export default StepperFooter; diff --git a/app/frontend/src/components/StepperFormActions.tsx b/app/frontend/src/components/StepperFormActions.tsx new file mode 100644 index 00000000..a0303f22 --- /dev/null +++ b/app/frontend/src/components/StepperFormActions.tsx @@ -0,0 +1,73 @@ +"use client"; +import { Button } from "./ui/button"; +import { useStepper } from "./ui/stepper"; + +export function StepperFormActions({ + form, + removeDynamicSteps, + isSubmitting, +}: { + form: any; + removeDynamicSteps: () => void; + isSubmitting?: boolean; +}) { + const { + prevStep, + nextStep, + resetSteps, + isDisabledStep, + hasCompletedAllSteps, + isOptionalStep, + activeStep, + steps, + } = useStepper(); + + const customPrevStep = () => { + const currentStepLabel = steps[activeStep]?.label; + if ( + currentStepLabel === "Custom Step" || + currentStepLabel === "Fine-Tune Step" + ) { + removeDynamicSteps(); + } + removeDynamicSteps(); + prevStep(); + }; + + return ( +
+ {hasCompletedAllSteps ? ( + + ) : ( + <> + + {activeStep < steps.length - 1 && ( + + )} + + )} +
+ ); +} diff --git a/app/frontend/src/components/WeightForm.tsx b/app/frontend/src/components/WeightForm.tsx new file mode 100644 index 00000000..093841dd --- /dev/null +++ b/app/frontend/src/components/WeightForm.tsx @@ -0,0 +1,143 @@ +"use client"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { useForm } from "react-hook-form"; +import * as z from "zod"; +import axios from "axios"; +import { useEffect, useState } from "react"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "./ui/select"; +import { + Form, + FormControl, + FormField, + FormItem, + FormLabel, + FormMessage, +} from "./ui/form"; +import { useStepper } from "./ui/stepper"; +import { customToast } from "./CustomToaster"; +import { StepperFormActions } from "./StepperFormActions"; +import { Weight, getWeightsUrl } from "./SelectionSteps"; + +export function WeightForm({ + selectedModel, + setCustomWeight, + setFormError, +}: { + selectedModel: string | null; + setCustomWeight: (weight: Weight) => void; + setFormError: (hasError: boolean) => void; +}) { + const { nextStep } = useStepper(); + const [weights, setWeights] = useState([]); + const [isSubmitting, setIsSubmitting] = useState(false); + + useEffect(() => { + if (selectedModel) { + console.log("fetching weights", getWeightsUrl(selectedModel)); + const fetchWeights = async () => { + try { + const response = await axios.get( + getWeightsUrl(selectedModel) + ); + console.log("fetched weights:", response.data); + setWeights(response.data); + } catch (error) { + console.error("Error fetching weights:", error); + } + }; + + fetchWeights(); + } + }, [selectedModel]); + + const form = useForm({ + resolver: zodResolver( + z.object({ + weight: z.string().nonempty("Please select a weight file."), + }) + ), + defaultValues: { + weight: "", + }, + }); + + useEffect(() => { + setFormError(!!form.formState.errors.weight); + }, [form.formState.errors]); + + const onSubmit = async (data: { weight: string }) => { + setIsSubmitting(true); + try { + const selectedWeight = weights.find( + (weight) => weight.name === data.weight + ); + if (selectedWeight) { + setCustomWeight(selectedWeight); + customToast.success("Model Weight Selected!"); + setFormError(false); + nextStep(); + } else { + customToast.error("Weight not found!"); + setFormError(true); + } + } finally { + setIsSubmitting(false); + } + }; + + return ( +
+ { + e.preventDefault(); + form.handleSubmit(onSubmit)(); + }} + className="space-y-6" + > + ( + + + Weight + + + {form.formState.errors.weight?.message} + + )} + /> + {}} + isSubmitting={isSubmitting} + /> + + + ); +} diff --git a/app/frontend/src/components/ui/aspect-ratio.tsx b/app/frontend/src/components/ui/aspect-ratio.tsx new file mode 100644 index 00000000..c4abbf37 --- /dev/null +++ b/app/frontend/src/components/ui/aspect-ratio.tsx @@ -0,0 +1,5 @@ +import * as AspectRatioPrimitive from "@radix-ui/react-aspect-ratio" + +const AspectRatio = AspectRatioPrimitive.Root + +export { AspectRatio } diff --git a/app/frontend/src/components/ui/breadcrumb.tsx b/app/frontend/src/components/ui/breadcrumb.tsx new file mode 100644 index 00000000..b487e5ba --- /dev/null +++ b/app/frontend/src/components/ui/breadcrumb.tsx @@ -0,0 +1,118 @@ +import * as React from "react"; +import { Slot } from "@radix-ui/react-slot"; +import { ChevronRight, MoreHorizontal } from "lucide-react"; + +import { cn } from "../../lib/utils"; + +const Breadcrumb = React.forwardRef< + HTMLElement, + React.ComponentPropsWithoutRef<"nav"> & { + separator?: React.ReactNode; + } +>(({ ...props }, ref) =>
); diff --git a/app/frontend/src/providers/ThemeProvider.tsx b/app/frontend/src/providers/ThemeProvider.tsx index 7b9eeb27..c51d00e1 100644 --- a/app/frontend/src/providers/ThemeProvider.tsx +++ b/app/frontend/src/providers/ThemeProvider.tsx @@ -22,7 +22,7 @@ const ThemeProviderContext = createContext(initialState); export function ThemeProvider({ children, - defaultTheme = "system", + defaultTheme = "dark", // Set the default theme to "dark" storageKey = "vite-ui-theme", ...props }: ThemeProviderProps) { @@ -42,10 +42,9 @@ export function ThemeProvider({ : "light"; root.classList.add(systemTheme); - return; + } else { + root.classList.add(theme); } - - root.classList.add(theme); }, [theme]); const value = { diff --git a/app/frontend/src/theme/commonThemeClasses.tsx b/app/frontend/src/theme/commonThemeClasses.tsx new file mode 100644 index 00000000..211b997d --- /dev/null +++ b/app/frontend/src/theme/commonThemeClasses.tsx @@ -0,0 +1,64 @@ +import { useMemo } from "react"; +import { useTheme } from "../providers/ThemeProvider"; + +interface CommonClasses { + textColor: string; + hoverTextColor: string; + activeBorderColor: string; + hoverBackgroundColor: string; +} + +interface TableCommonClasses { + textColor: string; + backgroundColor: string; + borderColor: string; + tableCaptionColor: string; + tableRowBgColor: string; + tableRowFadeBgColor: string; +} + +export default function useCommonClasses(): CommonClasses { + const { theme } = useTheme(); + + return useMemo(() => { + const textColor = theme === "dark" ? "text-zinc-200" : "text-black"; + const hoverTextColor = + theme === "dark" ? "hover:text-zinc-300" : "hover:text-gray-700"; + const activeBorderColor = + theme === "dark" ? "border-zinc-400" : "border-black"; + const hoverBackgroundColor = + theme === "dark" ? "hover:bg-zinc-700" : "hover:bg-gray-300"; + + return { + textColor, + hoverTextColor, + activeBorderColor, + hoverBackgroundColor, + }; + }, [theme]); +} + +export function useTableCommonClasses(): TableCommonClasses { + const { theme } = useTheme(); + + return useMemo(() => { + const textColor = theme === "dark" ? "text-zinc-200" : "text-black"; + const backgroundColor = theme === "dark" ? "bg-zinc-900" : "bg-white"; + const borderColor = + theme === "dark" ? "border-zinc-400" : "border-gray-500"; + const tableCaptionColor = + theme === "dark" ? "text-zinc-400" : "text-gray-500"; + const tableRowBgColor = theme === "dark" ? "bg-zinc-900" : "bg-zinc-200"; + const tableRowFadeBgColor = + theme === "dark" ? "bg-zinc-700" : "bg-zinc-200"; + + return { + textColor, + backgroundColor, + borderColor, + tableCaptionColor, + tableRowBgColor, + tableRowFadeBgColor, + }; + }, [theme]); +} diff --git a/app/frontend/tailwind.config.js b/app/frontend/tailwind.config.js index e94d624d..da1ddca9 100644 --- a/app/frontend/tailwind.config.js +++ b/app/frontend/tailwind.config.js @@ -66,6 +66,8 @@ export default { }, fontFamily: { sans: ["var(--font-sans)", ...fontFamily.sans], + mono: ["Roboto Mono", "monospace"], + tt_a_mono: ["Akkurat-Mono", "Akkurat-Mono"], }, keyframes: { "accordion-down": { From 8579168877cc2c5ddc51c694db79ca8dec575cb9 Mon Sep 17 00:00:00 2001 From: Anirudh Ramchandran Date: Tue, 10 Sep 2024 13:06:59 -0400 Subject: [PATCH 02/61] Anirud/license headers (#25) * update: tenstorrent logo svg file * add: tt customs fonts * update: to use tt fonts * update: for whole app to use tt font * update for specific parts to use rmMono font * fix npm packages: - running npm audit fix * clean up home page and adjust backgound girds * update badge colors * Update tailwind config : - add TT colors * update navbar to use tt colors * make table captions bigger * fixes #16: - Fix dark mode / light mode button colors in models deployed table * add color on scroll bar * adjust nav bar spacing * make stepper footter buttons better * update to add some border * clean up code * update dot grid colors * fix some tailwind classes * add animated deploy models button * update breadcrumps menu in chat ui page * change chatui to use message bubbles * remove any cheeky examples prompts * update enter button in chatui * merge anirud/tt-smi-reset into branding updates * fix any conflicts * revet back * re add reset icon * add TT license * add python script to add lc headers in api/ folder * modify es lint to add lc headers * add ignore pattern for vite env file * modify lc header * more eslint rules for prettier vs code extenstion * update package lock json * fixes to ensure no eslint erors * add tenstorrent license headers to all files * fix more warnings * fix persistant tooltip on navabr * clean up * copy tt buda demos license * fill in help menu sidebar based on the app route/page * update frontend readme * clean up * modify to inlcude bash and docker files * add tt license headers * add Django + Docker Third-Party Dependencies * unsure the dev tenstorrent in docker compose remains uncommented * add node module to generate the license file for all dependencies within front end package json * Anirud/tt smi reset resetconfig (#27) * refactor and add code to reset via the tt-smi reset reset_config.json file * chnage to check if tt device is mounted before perfroming reset * add better spinner --- .gitignore | 1 + LICENSE | 201 + app/api/Dockerfile | 25 +- app/api/add_spdx_header.py | 25 + app/api/api/__init__.py | 4 + app/api/api/asgi.py | 4 + app/api/api/settings.py | 4 + app/api/api/urls.py | 5 + app/api/api/wsgi.py | 4 + app/api/docker_control/__init__.py | 4 + app/api/docker_control/admin.py | 4 + app/api/docker_control/apps.py | 4 + app/api/docker_control/docker_utils.py | 97 +- app/api/docker_control/forms.py | 4 + app/api/docker_control/migrations/__init__.py | 4 + app/api/docker_control/models.py | 4 + app/api/docker_control/serializers.py | 4 + .../docker_control/test_docker_control_api.py | 4 + app/api/docker_control/test_docker_utils.py | 4 + app/api/docker_control/tests.py | 4 + app/api/docker_control/urls.py | 5 + app/api/docker_control/views.py | 69 +- app/api/manage.py | 4 + app/api/model_control/__init__.py | 4 + app/api/model_control/admin.py | 4 + app/api/model_control/apps.py | 4 + app/api/model_control/model_utils.py | 4 + app/api/model_control/models.py | 4 + app/api/model_control/serializers.py | 4 + app/api/model_control/test_e2e.py | 4 + app/api/model_control/test_model_api.py | 4 + app/api/model_control/test_model_utils.py | 4 + app/api/model_control/tests.py | 4 + app/api/model_control/urls.py | 4 + app/api/model_control/views.py | 4 + app/api/shared_config/__init__.py | 4 + app/api/shared_config/backend_config.py | 4 + app/api/shared_config/device_config.py | 4 + app/api/shared_config/logger_config.py | 4 + app/api/shared_config/model_config.py | 4 + app/docker-compose.yml | 12 +- app/frontend/.eslintrc.cjs | 31 +- app/frontend/README.md | 14 + app/frontend/package-lock.json | 2997 +++++++++- app/frontend/package.json | 19 +- app/frontend/postcss.config.js | 4 +- app/frontend/src/App.tsx | 2 + app/frontend/src/api/modelsDeployedApis.ts | 65 +- app/frontend/src/assets/tt_logo.svg | 43 +- app/frontend/src/components/ChatComponent.tsx | 254 +- app/frontend/src/components/CodeBlocks.tsx | 4 +- app/frontend/src/components/CopyableText.tsx | 4 +- app/frontend/src/components/CustomToaster.tsx | 6 +- .../src/components/DarkModeToggle.tsx | 2 + .../src/components/DeployModelStep.tsx | 14 +- app/frontend/src/components/FilesUploader.tsx | 2 + app/frontend/src/components/FirstStepForm.tsx | 3 + app/frontend/src/components/HealthBadge.tsx | 2 + app/frontend/src/components/HelpIcon.tsx | 2 + .../src/components/ModelsDeployedSkeleton.tsx | 26 + .../src/components/ModelsDeployedTable.tsx | 95 +- app/frontend/src/components/NavBar.tsx | 237 +- .../src/components/NoModelsDeployed.tsx | 42 + app/frontend/src/components/ResetIcon.tsx | 305 + .../src/components/SecondStepForm.tsx | 2 + .../src/components/SelectionSteps.tsx | 8 +- app/frontend/src/components/SideBar.tsx | 142 +- app/frontend/src/components/StatusBadge.tsx | 2 + app/frontend/src/components/StepperFooter.tsx | 14 +- .../src/components/StepperFormActions.tsx | 4 +- app/frontend/src/components/UploadDialog.tsx | 2 + app/frontend/src/components/WeightForm.tsx | 8 +- .../magicui/AnimatedDeployButton.tsx | 71 + app/frontend/src/components/ui/accordion.tsx | 56 + app/frontend/src/components/ui/badge.tsx | 15 +- .../src/components/ui/scroll-area.tsx | 10 +- app/frontend/src/components/ui/skeleton.tsx | 15 + app/frontend/src/components/ui/spinner.tsx | 4 +- .../src/fonts/DegularDisplay-Light.otf | Bin 0 -> 77372 bytes .../src/fonts/DegularDisplay-Medium.otf | Bin 0 -> 77512 bytes .../src/fonts/DegularDisplay-Semibold.otf | Bin 0 -> 78648 bytes app/frontend/src/fonts/DegularText-Bold.otf | Bin 0 -> 78700 bytes app/frontend/src/fonts/DegularText-Medium.otf | Bin 0 -> 77788 bytes .../src/fonts/DegularText-MediumItalic.otf | Bin 0 -> 80944 bytes app/frontend/src/fonts/RMMono-Regular.otf | Bin 0 -> 43512 bytes app/frontend/src/fonts/RMMono-SemiBold.otf | Bin 0 -> 44284 bytes app/frontend/src/index.css | 77 +- app/frontend/src/lib/utils.ts | 2 + app/frontend/src/main.tsx | 14 +- app/frontend/src/pages/ChatUIPage.tsx | 2 + app/frontend/src/pages/HomePage.tsx | 4 +- app/frontend/src/pages/ModelsDeployed.tsx | 6 +- app/frontend/src/providers/RefreshContext.tsx | 34 + app/frontend/src/providers/ThemeProvider.tsx | 4 +- app/frontend/src/routes/index.tsx | 22 +- app/frontend/src/theme/commonThemeClasses.tsx | 2 + app/frontend/tailwind.config.js | 93 +- app/frontend/third-party-licenses.txt | 4950 +++++++++++++++++ app/frontend/vite.config.ts | 36 +- startup.sh | 4 + 100 files changed, 9647 insertions(+), 697 deletions(-) create mode 100644 LICENSE create mode 100644 app/api/add_spdx_header.py create mode 100644 app/frontend/src/components/ModelsDeployedSkeleton.tsx create mode 100644 app/frontend/src/components/NoModelsDeployed.tsx create mode 100644 app/frontend/src/components/ResetIcon.tsx create mode 100644 app/frontend/src/components/magicui/AnimatedDeployButton.tsx create mode 100644 app/frontend/src/components/ui/accordion.tsx create mode 100644 app/frontend/src/components/ui/skeleton.tsx create mode 100644 app/frontend/src/fonts/DegularDisplay-Light.otf create mode 100644 app/frontend/src/fonts/DegularDisplay-Medium.otf create mode 100644 app/frontend/src/fonts/DegularDisplay-Semibold.otf create mode 100644 app/frontend/src/fonts/DegularText-Bold.otf create mode 100644 app/frontend/src/fonts/DegularText-Medium.otf create mode 100644 app/frontend/src/fonts/DegularText-MediumItalic.otf create mode 100644 app/frontend/src/fonts/RMMono-Regular.otf create mode 100644 app/frontend/src/fonts/RMMono-SemiBold.otf create mode 100644 app/frontend/src/providers/RefreshContext.tsx create mode 100644 app/frontend/third-party-licenses.txt diff --git a/.gitignore b/.gitignore index faf1926d..93277421 100644 --- a/.gitignore +++ b/.gitignore @@ -37,3 +37,4 @@ db.sqlite3 # unignore !requirements.txt +!app/frontend/third-party-licenses.txt diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..c0d707ec --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Copyright (c) 2024 Tenstorrent AI ULC + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + +------------------------------------------------------------------------------- + +Third-Party Dependencies: + +The following dependencies are utilized by this project but are not explicitly +distributed as part of the software: + +- Django [License available here](https://github.com/django/django/blob/main/LICENSE) +- Docker [License available here](https://github.com/docker/docs/blob/main/LICENSE) +- Third Party Libraries used in Frontend Product [License available here](app/frontend/third-party-licenses.txt) \ No newline at end of file diff --git a/app/api/Dockerfile b/app/api/Dockerfile index 969fd930..afac3518 100644 --- a/app/api/Dockerfile +++ b/app/api/Dockerfile @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + FROM python:3.12.1-slim-bullseye ENV PYTHONUNBUFFERED=1 EXPOSE 8000 @@ -8,10 +12,27 @@ RUN apt-get update && \ procps \ net-tools \ iputils-ping \ - dnsutils && \ + dnsutils && \ rm -rf /var/lib/apt/lists/* +RUN apt-get update && \ + apt-get install -y \ + git \ + curl \ + cargo + +# Install Rust +RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y + +# Add Rust to PATH +ENV PATH="/root/.cargo/bin:${PATH}" + +# Clone and install tt-smi +RUN git clone https://github.com/tenstorrent/tt-smi /tmp/tt-smi && \ + cd /tmp/tt-smi && \ + pip3 install . + WORKDIR /api COPY ./requirements.txt /api RUN pip3 install -r requirements.txt --no-cache-dir -COPY . /api +COPY . /api \ No newline at end of file diff --git a/app/api/add_spdx_header.py b/app/api/add_spdx_header.py new file mode 100644 index 00000000..1afa32bb --- /dev/null +++ b/app/api/add_spdx_header.py @@ -0,0 +1,25 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + +import os + +# SPDX header content +SPDX_HEADER = """# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC +""" + +def add_spdx_header(file_path): + with open(file_path, 'r+') as file: + content = file.read() + if "SPDX-License-Identifier" not in content: + file.seek(0, 0) + file.write(SPDX_HEADER + "\n" + content) + +# Walk through the directory and add the header to all relevant files +for root, dirs, files in os.walk("."): + for file in files: + if file.endswith((".py", "Dockerfile", ".sh")): # Check if the file is Python, Dockerfile, or Bash + file_path = os.path.join(root, file) # Construct the file path + add_spdx_header(file_path) # Pass the file path to the function diff --git a/app/api/api/__init__.py b/app/api/api/__init__.py index e69de29b..4da24a6e 100644 --- a/app/api/api/__init__.py +++ b/app/api/api/__init__.py @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + diff --git a/app/api/api/asgi.py b/app/api/api/asgi.py index 57b0c31a..51260953 100644 --- a/app/api/api/asgi.py +++ b/app/api/api/asgi.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + """ ASGI config for api project. diff --git a/app/api/api/settings.py b/app/api/api/settings.py index 63a5dfb8..275a0fce 100644 --- a/app/api/api/settings.py +++ b/app/api/api/settings.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + """ Django settings for api project. diff --git a/app/api/api/urls.py b/app/api/api/urls.py index 628cc033..8a4e5a1e 100644 --- a/app/api/api/urls.py +++ b/app/api/api/urls.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + """ URL configuration for api project. @@ -22,4 +26,5 @@ path("admin/", admin.site.urls), path("docker/", include("docker_control.urls")), path("models/", include("model_control.urls")), + path('reset_board/', include('docker_control.urls')), ] diff --git a/app/api/api/wsgi.py b/app/api/api/wsgi.py index bfbc45aa..553e8d70 100644 --- a/app/api/api/wsgi.py +++ b/app/api/api/wsgi.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + """ WSGI config for api project. diff --git a/app/api/docker_control/__init__.py b/app/api/docker_control/__init__.py index e69de29b..4da24a6e 100644 --- a/app/api/docker_control/__init__.py +++ b/app/api/docker_control/__init__.py @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + diff --git a/app/api/docker_control/admin.py b/app/api/docker_control/admin.py index 8c38f3f3..2c79060a 100644 --- a/app/api/docker_control/admin.py +++ b/app/api/docker_control/admin.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + from django.contrib import admin # Register your models here. diff --git a/app/api/docker_control/apps.py b/app/api/docker_control/apps.py index ffe5e2a1..995234d9 100644 --- a/app/api/docker_control/apps.py +++ b/app/api/docker_control/apps.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + from django.apps import AppConfig diff --git a/app/api/docker_control/docker_utils.py b/app/api/docker_control/docker_utils.py index 9224a02b..23f26706 100644 --- a/app/api/docker_control/docker_utils.py +++ b/app/api/docker_control/docker_utils.py @@ -1,5 +1,9 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + # docker_control/docker_utils.py -import socket +import socket,os,subprocess import copy from pathlib import Path @@ -11,9 +15,10 @@ from shared_config.model_config import model_implmentations from shared_config.backend_config import backend_config + +CONFIG_PATH = '/root/.config/tenstorrent/reset_config.json' logger = get_logger(__name__) logger.info(f"importing {__name__}") - client = docker.from_env() # docker internal bridge network used for models and applications. @@ -220,3 +225,91 @@ def remove_id_prefix(s): dir_name = remove_id_prefix(weights_id) return weights_dir_path.joinpath(dir_name) + + + +def perform_reset(): + try: + logger.info("Running initial tt-smi command to check device detection.") + + # Initial check to see if Tenstorrent devices are detected + def check_device_detection(): + process = subprocess.Popen( + ['tt-smi'], + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + stdin=subprocess.DEVNULL, # Prevents interactive command-line interface + text=True + ) + output = [] + for line in iter(process.stdout.readline, ''): + logger.info(f"tt-smi output: {line.strip()}") + output.append(line) + if "No Tenstorrent devices detected" in line: + return { + "status": "error", + "message": "No Tenstorrent devices detected! Please check your hardware and try again.", + "output": ''.join(output), + "http_status": 501 # Not Implemented + } + process.stdout.close() + return_code = process.wait() + if return_code != 0: + return { + "status": "error", + "message": f"tt-smi command failed with return code {return_code}.", + "output": ''.join(output), + "http_status": 500 # Internal Server Error + } + return {"status": "success", "output": ''.join(output)} + + # Run the device detection check + detection_result = check_device_detection() + if detection_result.get("status") == "error": + return detection_result + + logger.info("Running tt-smi reset command.") + + def stream_command_output(command): + logger.info(f"Executing command: {' '.join(command)}") + process = subprocess.Popen( + command, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + stdin=subprocess.DEVNULL, # Prevents interactive command-line interface + text=True + ) + output = [] + for line in iter(process.stdout.readline, ''): + logger.info(f"Command output: {line.strip()}") + output.append(line) + process.stdout.close() + return_code = process.wait() + if return_code != 0: + logger.info(f"Command failed with return code {return_code}") + output.append(f"Command failed with return code {return_code}") + return { + "status": "error", + "output": ''.join(output), + "http_status": 500 # Internal Server Error + } + else: + logger.info(f"Command completed successfully with return code {return_code}") + return { + "status": "success", + "output": ''.join(output) + } + + # Step 1: Check if the reset config JSON already exists + if not os.path.exists(CONFIG_PATH): + generate_result = stream_command_output(['tt-smi', '--generate_reset_json']) + if generate_result.get("status") == "error": + return generate_result + + # Step 2: Run the reset using the generated JSON + reset_result = stream_command_output(['tt-smi', '-r', CONFIG_PATH]) + return reset_result or {"status": "error", "output": "No output from reset command"} + + except Exception as e: + logger.exception("Exception occurred during reset operation.") + return {"status": "error", "message": str(e), "output": "An exception occurred during the reset operation.", "http_status": 500} \ No newline at end of file diff --git a/app/api/docker_control/forms.py b/app/api/docker_control/forms.py index 4a4f27b7..d154af1f 100644 --- a/app/api/docker_control/forms.py +++ b/app/api/docker_control/forms.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + # docker_control/forms.py from django import forms from shared_config.model_config import model_implmentations diff --git a/app/api/docker_control/migrations/__init__.py b/app/api/docker_control/migrations/__init__.py index e69de29b..4da24a6e 100644 --- a/app/api/docker_control/migrations/__init__.py +++ b/app/api/docker_control/migrations/__init__.py @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + diff --git a/app/api/docker_control/models.py b/app/api/docker_control/models.py index 71a83623..2d29716d 100644 --- a/app/api/docker_control/models.py +++ b/app/api/docker_control/models.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + from django.db import models # Create your models here. diff --git a/app/api/docker_control/serializers.py b/app/api/docker_control/serializers.py index c237e08e..38533557 100644 --- a/app/api/docker_control/serializers.py +++ b/app/api/docker_control/serializers.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + from pathlib import Path from rest_framework import serializers diff --git a/app/api/docker_control/test_docker_control_api.py b/app/api/docker_control/test_docker_control_api.py index d44a0c55..8e089a59 100644 --- a/app/api/docker_control/test_docker_control_api.py +++ b/app/api/docker_control/test_docker_control_api.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + import json import time diff --git a/app/api/docker_control/test_docker_utils.py b/app/api/docker_control/test_docker_utils.py index 96086757..1d4bfea1 100644 --- a/app/api/docker_control/test_docker_utils.py +++ b/app/api/docker_control/test_docker_utils.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + import json import time diff --git a/app/api/docker_control/tests.py b/app/api/docker_control/tests.py index 7ce503c2..eeaceac6 100644 --- a/app/api/docker_control/tests.py +++ b/app/api/docker_control/tests.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + from django.test import TestCase # Create your tests here. diff --git a/app/api/docker_control/urls.py b/app/api/docker_control/urls.py index 8890de77..c8dc4031 100644 --- a/app/api/docker_control/urls.py +++ b/app/api/docker_control/urls.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + # docker_control/urls.py from django.urls import path from . import views @@ -8,4 +12,5 @@ path("stop/", views.StopView.as_view()), path("status/", views.StatusView.as_view()), path("redeploy/", views.RedeployView.as_view()), + path('reset_board/', views.ResetBoardView.as_view()), ] diff --git a/app/api/docker_control/views.py b/app/api/docker_control/views.py index e04a1cc1..fb37ded6 100644 --- a/app/api/docker_control/views.py +++ b/app/api/docker_control/views.py @@ -1,28 +1,62 @@ -# docker_control/views.py -from django.shortcuts import render +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC -# from django.http import JsonResponse +from django.shortcuts import render +from django.http import StreamingHttpResponse from rest_framework import status from rest_framework.views import APIView from rest_framework.response import Response from .forms import DockerForm -from .docker_utils import run_container, stop_container, get_container_status +from .docker_utils import run_container, stop_container, get_container_status, perform_reset from shared_config.model_config import model_implmentations from .serializers import DeploymentSerializer, StopSerializer +from shared_config.logger_config import get_logger +logger = get_logger(__name__) +logger.info(f"importing {__name__}") class StopView(APIView): def post(self, request, *args, **kwargs): serializer = StopSerializer(data=request.data) if serializer.is_valid(): container_id = request.data.get("container_id") - response = stop_container(container_id) - return Response(response, status=status.HTTP_200_OK) + logger.info(f"Received request to stop container with ID: {container_id}") + + # Stop the container + stop_response = stop_container(container_id) + logger.info(f"Stop response: {stop_response}") + + # Perform reset if the stop was successful + reset_response = None + reset_status = "success" + + if stop_response.get("status") == "success": + reset_response = perform_reset() + logger.info(f"Reset response: {reset_response}") + + if reset_response.get("status") == "error": + error_message = reset_response.get('message', 'An error occurred during reset.') + http_status = reset_response.get("http_status", status.HTTP_500_INTERNAL_SERVER_ERROR) + logger.warning(f"Reset failed: {error_message}") + reset_status = "error" + + # Ensure that we always return a status field + combined_status = "success" if stop_response.get("status") == "success" else "error" + + # Return the response, combining the stop and reset results + response_status = status.HTTP_200_OK if combined_status == "success" else status.HTTP_500_INTERNAL_SERVER_ERROR + logger.info(f"Returning responses: {stop_response}, {reset_response}") + return Response({ + "status": combined_status, + "stop_response": stop_response, + "reset_response": reset_response, + "reset_status": reset_status + }, status=response_status) else: return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) - class ContainersView(APIView): def get(self, request, *args, **kwargs): data = [ @@ -63,3 +97,24 @@ def post(self, request, *args, **kwargs): return Response(response, status=status.HTTP_201_CREATED) else: return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + + +class ResetBoardView(APIView): + def post(self, request, *args, **kwargs): + try: + # Perform the reset + reset_response = perform_reset() + + # Determine the HTTP status based on the reset_response + if reset_response.get("status") == "error": + error_message = reset_response.get('message', 'An error occurred during reset.') + http_status = reset_response.get("http_status", status.HTTP_500_INTERNAL_SERVER_ERROR) + return Response({'status': 'error', 'message': error_message}, status=http_status) + + # If successful, return a 200 OK with the output + output = reset_response.get('output', 'Board reset successfully.') + return StreamingHttpResponse(output, content_type='text/plain', status=status.HTTP_200_OK) + + except Exception as e: + logger.exception("Exception occurred during reset operation.") + return Response({'status': 'error', 'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) \ No newline at end of file diff --git a/app/api/manage.py b/app/api/manage.py index 7fbe8935..87b65d89 100755 --- a/app/api/manage.py +++ b/app/api/manage.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + #!/usr/bin/env python """Django's command-line utility for administrative tasks.""" import os diff --git a/app/api/model_control/__init__.py b/app/api/model_control/__init__.py index e69de29b..4da24a6e 100644 --- a/app/api/model_control/__init__.py +++ b/app/api/model_control/__init__.py @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + diff --git a/app/api/model_control/admin.py b/app/api/model_control/admin.py index 8c38f3f3..2c79060a 100644 --- a/app/api/model_control/admin.py +++ b/app/api/model_control/admin.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + from django.contrib import admin # Register your models here. diff --git a/app/api/model_control/apps.py b/app/api/model_control/apps.py index 7442ab88..b310145a 100644 --- a/app/api/model_control/apps.py +++ b/app/api/model_control/apps.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + from django.apps import AppConfig from shared_config.model_config import model_implmentations diff --git a/app/api/model_control/model_utils.py b/app/api/model_control/model_utils.py index b64508c2..dfc846ed 100644 --- a/app/api/model_control/model_utils.py +++ b/app/api/model_control/model_utils.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + import json import pickle diff --git a/app/api/model_control/models.py b/app/api/model_control/models.py index 71a83623..2d29716d 100644 --- a/app/api/model_control/models.py +++ b/app/api/model_control/models.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + from django.db import models # Create your models here. diff --git a/app/api/model_control/serializers.py b/app/api/model_control/serializers.py index 10cb26a5..ff370d2b 100644 --- a/app/api/model_control/serializers.py +++ b/app/api/model_control/serializers.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + from pathlib import Path from rest_framework import serializers diff --git a/app/api/model_control/test_e2e.py b/app/api/model_control/test_e2e.py index e04bef47..5acf507c 100644 --- a/app/api/model_control/test_e2e.py +++ b/app/api/model_control/test_e2e.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + import json import time import os diff --git a/app/api/model_control/test_model_api.py b/app/api/model_control/test_model_api.py index 204dda95..64976b1c 100644 --- a/app/api/model_control/test_model_api.py +++ b/app/api/model_control/test_model_api.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + import json import time diff --git a/app/api/model_control/test_model_utils.py b/app/api/model_control/test_model_utils.py index c0eaba25..cf9c25b2 100644 --- a/app/api/model_control/test_model_utils.py +++ b/app/api/model_control/test_model_utils.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + import json import time import os diff --git a/app/api/model_control/tests.py b/app/api/model_control/tests.py index 7ce503c2..eeaceac6 100644 --- a/app/api/model_control/tests.py +++ b/app/api/model_control/tests.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + from django.test import TestCase # Create your tests here. diff --git a/app/api/model_control/urls.py b/app/api/model_control/urls.py index 259a13d5..3ff22c59 100644 --- a/app/api/model_control/urls.py +++ b/app/api/model_control/urls.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + # model_control/urls.py from django.urls import path from . import views diff --git a/app/api/model_control/views.py b/app/api/model_control/views.py index 479e1a4f..a247c912 100644 --- a/app/api/model_control/views.py +++ b/app/api/model_control/views.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + # model_control/views.py from pathlib import Path diff --git a/app/api/shared_config/__init__.py b/app/api/shared_config/__init__.py index e69de29b..4da24a6e 100644 --- a/app/api/shared_config/__init__.py +++ b/app/api/shared_config/__init__.py @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + diff --git a/app/api/shared_config/backend_config.py b/app/api/shared_config/backend_config.py index d5057642..6cac97fa 100644 --- a/app/api/shared_config/backend_config.py +++ b/app/api/shared_config/backend_config.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + from dataclasses import dataclass import os from pathlib import Path diff --git a/app/api/shared_config/device_config.py b/app/api/shared_config/device_config.py index 3d0fee4f..1bdd2971 100644 --- a/app/api/shared_config/device_config.py +++ b/app/api/shared_config/device_config.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + from enum import Enum, auto diff --git a/app/api/shared_config/logger_config.py b/app/api/shared_config/logger_config.py index be1a42d7..3f3722b1 100644 --- a/app/api/shared_config/logger_config.py +++ b/app/api/shared_config/logger_config.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + import logging import os from datetime import datetime diff --git a/app/api/shared_config/model_config.py b/app/api/shared_config/model_config.py index b95dd1f7..526712ac 100644 --- a/app/api/shared_config/model_config.py +++ b/app/api/shared_config/model_config.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + import os from dataclasses import dataclass, asdict from typing import Set, Dict, Any diff --git a/app/docker-compose.yml b/app/docker-compose.yml index 90a354b5..31536885 100644 --- a/app/docker-compose.yml +++ b/app/docker-compose.yml @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + services: tt_studio_backend: container_name: tt_studio_backend_api @@ -7,10 +11,10 @@ services: build: ./api # uncomment devices to use Tenstorrent hardware # devices: - # # mount all tenstorrent devices to backend container - # - /dev/tenstorrent:/dev/tenstorrent + # mount all tenstorrent devices to backend container + # - /dev/tenstorrent:/dev/tenstorrent # note that `network_mode: host` does not work on mac OS - networks: + networks: - llm_studio_network ports: - "8000:8000" @@ -40,7 +44,7 @@ services: hostname: tt-studio-frontend image: ghcr.io/tenstorrent/tt-studio/frontend:v0.0.0 build: ./frontend - networks: + networks: - llm_studio_network ports: - "3000:3000" diff --git a/app/frontend/.eslintrc.cjs b/app/frontend/.eslintrc.cjs index d6c95379..464eccb4 100644 --- a/app/frontend/.eslintrc.cjs +++ b/app/frontend/.eslintrc.cjs @@ -1,18 +1,29 @@ module.exports = { root: true, - env: { browser: true, es2020: true }, + env: { browser: true, es2020: true, node: true }, extends: [ - 'eslint:recommended', - 'plugin:@typescript-eslint/recommended', - 'plugin:react-hooks/recommended', + "eslint:recommended", + "plugin:@typescript-eslint/recommended", + "plugin:react-hooks/recommended", + "plugin:prettier/recommended", // Prettier as a plugin ], - ignorePatterns: ['dist', '.eslintrc.cjs'], - parser: '@typescript-eslint/parser', - plugins: ['react-refresh'], + ignorePatterns: ["dist", ".eslintrc.cjs", "vite-env.d.ts","src/components/ui"], + parser: "@typescript-eslint/parser", + plugins: ["react-refresh", "header", "prettier"], rules: { - 'react-refresh/only-export-components': [ - 'warn', + "react-refresh/only-export-components": [ + "warn", { allowConstantExport: true }, ], + "header/header": [ + "error", + "line", + [ + " SPDX-License-Identifier: Apache-2.0", + " SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC", + ], + ], + "prettier/prettier": "error", // Ensures Prettier rules are followed + }, -} +}; diff --git a/app/frontend/README.md b/app/frontend/README.md index 3bc8af12..6a9be167 100644 --- a/app/frontend/README.md +++ b/app/frontend/README.md @@ -90,3 +90,17 @@ Currently, two official plugins are available: - [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh - [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh + + +## Prettier and ESLint Configuration +The project uses Prettier and ESLint with specific VS Code plugins to ensure code quality and consistency. Additionally, these tools are configured to automatically add the Tenstorrent license headers to the files in the project. + +## Auto-Adding License Headers +To ensure that the correct Tenstorrent license headers are added to each file, the project includes configurations for Prettier, ESLint, and specific VS Code plugins. The required SPDX license headers will be added automatically upon saving or formatting the files. + +The license headers should look like this: + +```js +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC +``` diff --git a/app/frontend/package-lock.json b/app/frontend/package-lock.json index 3a4c6ccc..2214b56e 100644 --- a/app/frontend/package-lock.json +++ b/app/frontend/package-lock.json @@ -9,6 +9,7 @@ "version": "0.0.0", "dependencies": { "@hookform/resolvers": "^3.3.4", + "@radix-ui/react-accordion": "^1.2.0", "@radix-ui/react-aspect-ratio": "^1.1.0", "@radix-ui/react-collapsible": "^1.0.3", "@radix-ui/react-dialog": "^1.0.5", @@ -47,13 +48,18 @@ "@types/node": "^20.12.8", "@types/react": "^18.2.66", "@types/react-dom": "^18.2.22", - "@typescript-eslint/eslint-plugin": "^7.2.0", - "@typescript-eslint/parser": "^7.2.0", + "@typescript-eslint/eslint-plugin": "^7.18.0", + "@typescript-eslint/parser": "^7.18.0", "@vitejs/plugin-react-swc": "^3.5.0", "autoprefixer": "^10.4.19", + "daisyui": "^4.12.10", "eslint": "^8.57.0", - "eslint-plugin-react-hooks": "^4.6.0", - "eslint-plugin-react-refresh": "^0.4.6", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-header": "^3.1.1", + "eslint-plugin-prettier": "^5.2.1", + "eslint-plugin-react-hooks": "^4.6.2", + "eslint-plugin-react-refresh": "^0.4.11", + "generate-license-file": "^3.5.1", "postcss": "^8.4.38", "tailwindcss": "^3.4.3", "typescript": "^5.2.2", @@ -71,6 +77,114 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@babel/code-frame": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", + "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.24.7", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", + "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.24.7", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/@babel/runtime": { "version": "7.24.8", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.8.tgz", @@ -82,6 +196,30 @@ "node": ">=6.9.0" } }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "optional": true, + "peer": true, + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "optional": true, + "peer": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, "node_modules/@emotion/is-prop-valid": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.2.tgz", @@ -686,6 +824,12 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, + "node_modules/@isaacs/string-locale-compare": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@isaacs/string-locale-compare/-/string-locale-compare-1.1.0.tgz", + "integrity": "sha512-SQ7Kzhh9+D+ZW9MA0zkYv3VXhIDNx+LzM6EJ+/65I3QY+enU6Itte7E5XX7EWrqLW2FN4n06GWzBnPoC3th2aQ==", + "dev": true + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", @@ -761,168 +905,552 @@ "node": ">= 8" } }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "optional": true, + "node_modules/@npmcli/agent": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/@npmcli/agent/-/agent-2.2.2.tgz", + "integrity": "sha512-OrcNPXdpSl9UX7qPVRWbmWMCSXrcDa2M9DvrbOTj7ao1S4PlqVFYv9/yLKMkrJKZ/V5A/kDBC690or307i26Og==", + "dev": true, + "dependencies": { + "agent-base": "^7.1.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.1", + "lru-cache": "^10.0.1", + "socks-proxy-agent": "^8.0.3" + }, "engines": { - "node": ">=14" + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/@radix-ui/number": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.0.tgz", - "integrity": "sha512-V3gRzhVNU1ldS5XhAPTom1fOIo4ccrjjJgmE+LI2h/WaFpHmx0MQApT+KZHnx8abG6Avtfcz4WoEciMnpFT3HQ==" - }, - "node_modules/@radix-ui/primitive": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.0.tgz", - "integrity": "sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==" - }, - "node_modules/@radix-ui/react-arrow": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.0.tgz", - "integrity": "sha512-FmlW1rCg7hBpEBwFbjHwCW6AmWLQM6g/v0Sn8XbP9NvmSZ2San1FpQeyPtufzOMSIx7Y4dzjlHoifhp+7NkZhw==", + "node_modules/@npmcli/arborist": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/@npmcli/arborist/-/arborist-7.5.4.tgz", + "integrity": "sha512-nWtIc6QwwoUORCRNzKx4ypHqCk3drI+5aeYdMTQQiRCcn4lOOgfQh7WyZobGYTxXPSq1VwV53lkpN/BRlRk08g==", + "dev": true, "dependencies": { - "@radix-ui/react-primitive": "2.0.0" + "@isaacs/string-locale-compare": "^1.1.0", + "@npmcli/fs": "^3.1.1", + "@npmcli/installed-package-contents": "^2.1.0", + "@npmcli/map-workspaces": "^3.0.2", + "@npmcli/metavuln-calculator": "^7.1.1", + "@npmcli/name-from-folder": "^2.0.0", + "@npmcli/node-gyp": "^3.0.0", + "@npmcli/package-json": "^5.1.0", + "@npmcli/query": "^3.1.0", + "@npmcli/redact": "^2.0.0", + "@npmcli/run-script": "^8.1.0", + "bin-links": "^4.0.4", + "cacache": "^18.0.3", + "common-ancestor-path": "^1.0.1", + "hosted-git-info": "^7.0.2", + "json-parse-even-better-errors": "^3.0.2", + "json-stringify-nice": "^1.1.4", + "lru-cache": "^10.2.2", + "minimatch": "^9.0.4", + "nopt": "^7.2.1", + "npm-install-checks": "^6.2.0", + "npm-package-arg": "^11.0.2", + "npm-pick-manifest": "^9.0.1", + "npm-registry-fetch": "^17.0.1", + "pacote": "^18.0.6", + "parse-conflict-json": "^3.0.0", + "proc-log": "^4.2.0", + "proggy": "^2.0.0", + "promise-all-reject-late": "^1.0.0", + "promise-call-limit": "^3.0.1", + "read-package-json-fast": "^3.0.2", + "semver": "^7.3.7", + "ssri": "^10.0.6", + "treeverse": "^3.0.0", + "walk-up-path": "^3.0.1" }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + "bin": { + "arborist": "bin/index.js" }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } + "engines": { + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/@radix-ui/react-aspect-ratio": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-aspect-ratio/-/react-aspect-ratio-1.1.0.tgz", - "integrity": "sha512-dP87DM/Y7jFlPgUZTlhx6FF5CEzOiaxp2rBCKlaXlpH5Ip/9Fg5zZ9lDOQ5o/MOfUlf36eak14zoWYpgcgGoOg==", + "node_modules/@npmcli/fs": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-3.1.1.tgz", + "integrity": "sha512-q9CRWjpHCMIh5sVyefoD1cA7PkvILqCZsnSOEUUivORLjxCO/Irmue2DprETiNgEqktDBZaM1Bi+jrarx1XdCg==", + "dev": true, "dependencies": { - "@radix-ui/react-primitive": "2.0.0" + "semver": "^7.3.5" }, - "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" + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/git": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-5.0.8.tgz", + "integrity": "sha512-liASfw5cqhjNW9UFd+ruwwdEf/lbOAQjLL2XY2dFW/bkJheXDYZgOyul/4gVvEV4BWkTXjYGmDqMw9uegdbJNQ==", + "dev": true, + "dependencies": { + "@npmcli/promise-spawn": "^7.0.0", + "ini": "^4.1.3", + "lru-cache": "^10.0.1", + "npm-pick-manifest": "^9.0.0", + "proc-log": "^4.0.0", + "promise-inflight": "^1.0.1", + "promise-retry": "^2.0.1", + "semver": "^7.3.5", + "which": "^4.0.0" }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } + "engines": { + "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/@radix-ui/react-collapsible": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.1.0.tgz", - "integrity": "sha512-zQY7Epa8sTL0mq4ajSJpjgn2YmCgyrG7RsQgLp3C0LQVkG7+Tf6Pv1CeNWZLyqMjhdPkBa5Lx7wYBeSu7uCSTA==", + "node_modules/@npmcli/git/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "engines": { + "node": ">=16" + } + }, + "node_modules/@npmcli/git/node_modules/which": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", + "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", + "dev": true, "dependencies": { - "@radix-ui/primitive": "1.1.0", - "@radix-ui/react-compose-refs": "1.1.0", - "@radix-ui/react-context": "1.1.0", - "@radix-ui/react-id": "1.1.0", - "@radix-ui/react-presence": "1.1.0", - "@radix-ui/react-primitive": "2.0.0", - "@radix-ui/react-use-controllable-state": "1.1.0", - "@radix-ui/react-use-layout-effect": "1.1.0" + "isexe": "^3.1.1" }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + "bin": { + "node-which": "bin/which.js" }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } + "engines": { + "node": "^16.13.0 || >=18.0.0" } }, - "node_modules/@radix-ui/react-collection": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.0.tgz", - "integrity": "sha512-GZsZslMJEyo1VKm5L1ZJY8tGDxZNPAoUeQUIbKeJfoi7Q4kmig5AsgLMYYuyYbfjd8fBmFORAIwYAkXMnXZgZw==", + "node_modules/@npmcli/installed-package-contents": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-2.1.0.tgz", + "integrity": "sha512-c8UuGLeZpm69BryRykLuKRyKFZYJsZSCT4aVY5ds4omyZqJ172ApzgfKJ5eV/r3HgLdUYgFVe54KSFVjKoe27w==", + "dev": true, "dependencies": { - "@radix-ui/react-compose-refs": "1.1.0", - "@radix-ui/react-context": "1.1.0", - "@radix-ui/react-primitive": "2.0.0", - "@radix-ui/react-slot": "1.1.0" + "npm-bundled": "^3.0.0", + "npm-normalize-package-bin": "^3.0.0" }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + "bin": { + "installed-package-contents": "bin/index.js" }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/@radix-ui/react-compose-refs": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.0.tgz", - "integrity": "sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw==", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + "node_modules/@npmcli/map-workspaces": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@npmcli/map-workspaces/-/map-workspaces-3.0.6.tgz", + "integrity": "sha512-tkYs0OYnzQm6iIRdfy+LcLBjcKuQCeE5YLb8KnrIlutJfheNaPvPpgoFEyEFgbjzl5PLZ3IA/BWAwRU0eHuQDA==", + "dev": true, + "dependencies": { + "@npmcli/name-from-folder": "^2.0.0", + "glob": "^10.2.2", + "minimatch": "^9.0.0", + "read-package-json-fast": "^3.0.0" }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/@radix-ui/react-context": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.0.tgz", - "integrity": "sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + "node_modules/@npmcli/map-workspaces/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@radix-ui/react-dialog": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.1.tgz", - "integrity": "sha512-zysS+iU4YP3STKNS6USvFVqI4qqx8EpiwmT5TuCApVEBca+eRCbONi4EgzfNSuVnOXvC5UPHHMjs8RXO6DH9Bg==", + "node_modules/@npmcli/metavuln-calculator": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@npmcli/metavuln-calculator/-/metavuln-calculator-7.1.1.tgz", + "integrity": "sha512-Nkxf96V0lAx3HCpVda7Vw4P23RILgdi/5K1fmj2tZkWIYLpXAN8k2UVVOsW16TsS5F8Ws2I7Cm+PU1/rsVF47g==", + "dev": true, "dependencies": { - "@radix-ui/primitive": "1.1.0", - "@radix-ui/react-compose-refs": "1.1.0", - "@radix-ui/react-context": "1.1.0", - "@radix-ui/react-dismissable-layer": "1.1.0", - "@radix-ui/react-focus-guards": "1.1.0", - "@radix-ui/react-focus-scope": "1.1.0", - "@radix-ui/react-id": "1.1.0", - "@radix-ui/react-portal": "1.1.1", - "@radix-ui/react-presence": "1.1.0", - "@radix-ui/react-primitive": "2.0.0", - "@radix-ui/react-slot": "1.1.0", - "@radix-ui/react-use-controllable-state": "1.1.0", + "cacache": "^18.0.0", + "json-parse-even-better-errors": "^3.0.0", + "pacote": "^18.0.0", + "proc-log": "^4.1.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/name-from-folder": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/name-from-folder/-/name-from-folder-2.0.0.tgz", + "integrity": "sha512-pwK+BfEBZJbKdNYpHHRTNBwBoqrN/iIMO0AiGvYsp3Hoaq0WbgGSWQR6SCldZovoDpY3yje5lkFUe6gsDgJ2vg==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/node-gyp": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-3.0.0.tgz", + "integrity": "sha512-gp8pRXC2oOxu0DUE1/M3bYtb1b3/DbJ5aM113+XJBgfXdussRAsX0YOrOhdd8WvnAR6auDBvJomGAkLKA5ydxA==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/package-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@npmcli/package-json/-/package-json-5.2.0.tgz", + "integrity": "sha512-qe/kiqqkW0AGtvBjL8TJKZk/eBBSpnJkUWvHdQ9jM2lKHXRYYJuyNpJPlJw3c8QjC2ow6NZYiLExhUaeJelbxQ==", + "dev": true, + "dependencies": { + "@npmcli/git": "^5.0.0", + "glob": "^10.2.2", + "hosted-git-info": "^7.0.0", + "json-parse-even-better-errors": "^3.0.0", + "normalize-package-data": "^6.0.0", + "proc-log": "^4.0.0", + "semver": "^7.5.3" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/package-json/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@npmcli/promise-spawn": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-7.0.2.tgz", + "integrity": "sha512-xhfYPXoV5Dy4UkY0D+v2KkwvnDfiA/8Mt3sWCGI/hM03NsYIH8ZaG6QzS9x7pje5vHZBZJ2v6VRFVTWACnqcmQ==", + "dev": true, + "dependencies": { + "which": "^4.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/promise-spawn/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "engines": { + "node": ">=16" + } + }, + "node_modules/@npmcli/promise-spawn/node_modules/which": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", + "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", + "dev": true, + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/query": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@npmcli/query/-/query-3.1.0.tgz", + "integrity": "sha512-C/iR0tk7KSKGldibYIB9x8GtO/0Bd0I2mhOaDb8ucQL/bQVTmGoeREaFj64Z5+iCBRf3dQfed0CjJL7I8iTkiQ==", + "dev": true, + "dependencies": { + "postcss-selector-parser": "^6.0.10" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/redact": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@npmcli/redact/-/redact-2.0.1.tgz", + "integrity": "sha512-YgsR5jCQZhVmTJvjduTOIHph0L73pK8xwMVaDY0PatySqVM9AZj93jpoXYSJqfHFxFkN9dmqTw6OiqExsS3LPw==", + "dev": true, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/run-script": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-8.1.0.tgz", + "integrity": "sha512-y7efHHwghQfk28G2z3tlZ67pLG0XdfYbcVG26r7YIXALRsrVQcTq4/tdenSmdOrEsNahIYA/eh8aEVROWGFUDg==", + "dev": true, + "dependencies": { + "@npmcli/node-gyp": "^3.0.0", + "@npmcli/package-json": "^5.0.0", + "@npmcli/promise-spawn": "^7.0.0", + "node-gyp": "^10.0.0", + "proc-log": "^4.0.0", + "which": "^4.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/run-script/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "engines": { + "node": ">=16" + } + }, + "node_modules/@npmcli/run-script/node_modules/which": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", + "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", + "dev": true, + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^16.13.0 || >=18.0.0" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@pkgr/core": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz", + "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, + "node_modules/@radix-ui/number": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.0.tgz", + "integrity": "sha512-V3gRzhVNU1ldS5XhAPTom1fOIo4ccrjjJgmE+LI2h/WaFpHmx0MQApT+KZHnx8abG6Avtfcz4WoEciMnpFT3HQ==" + }, + "node_modules/@radix-ui/primitive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.0.tgz", + "integrity": "sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==" + }, + "node_modules/@radix-ui/react-accordion": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-accordion/-/react-accordion-1.2.0.tgz", + "integrity": "sha512-HJOzSX8dQqtsp/3jVxCU3CXEONF7/2jlGAB28oX8TTw1Dz8JYbEI1UcL8355PuLBE41/IRRMvCw7VkiK/jcUOQ==", + "dependencies": { + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-collapsible": "1.1.0", + "@radix-ui/react-collection": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-direction": "1.1.0", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-controllable-state": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-arrow": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.0.tgz", + "integrity": "sha512-FmlW1rCg7hBpEBwFbjHwCW6AmWLQM6g/v0Sn8XbP9NvmSZ2San1FpQeyPtufzOMSIx7Y4dzjlHoifhp+7NkZhw==", + "dependencies": { + "@radix-ui/react-primitive": "2.0.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-aspect-ratio": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-aspect-ratio/-/react-aspect-ratio-1.1.0.tgz", + "integrity": "sha512-dP87DM/Y7jFlPgUZTlhx6FF5CEzOiaxp2rBCKlaXlpH5Ip/9Fg5zZ9lDOQ5o/MOfUlf36eak14zoWYpgcgGoOg==", + "dependencies": { + "@radix-ui/react-primitive": "2.0.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-collapsible": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.1.0.tgz", + "integrity": "sha512-zQY7Epa8sTL0mq4ajSJpjgn2YmCgyrG7RsQgLp3C0LQVkG7+Tf6Pv1CeNWZLyqMjhdPkBa5Lx7wYBeSu7uCSTA==", + "dependencies": { + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-presence": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-controllable-state": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-collection": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.0.tgz", + "integrity": "sha512-GZsZslMJEyo1VKm5L1ZJY8tGDxZNPAoUeQUIbKeJfoi7Q4kmig5AsgLMYYuyYbfjd8fBmFORAIwYAkXMnXZgZw==", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-slot": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-compose-refs": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.0.tgz", + "integrity": "sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw==", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-context": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.0.tgz", + "integrity": "sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dialog": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.1.tgz", + "integrity": "sha512-zysS+iU4YP3STKNS6USvFVqI4qqx8EpiwmT5TuCApVEBca+eRCbONi4EgzfNSuVnOXvC5UPHHMjs8RXO6DH9Bg==", + "dependencies": { + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-dismissable-layer": "1.1.0", + "@radix-ui/react-focus-guards": "1.1.0", + "@radix-ui/react-focus-scope": "1.1.0", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-portal": "1.1.1", + "@radix-ui/react-presence": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-slot": "1.1.0", + "@radix-ui/react-use-controllable-state": "1.1.0", "aria-hidden": "^1.1.1", "react-remove-scroll": "2.5.7" }, @@ -1884,15 +2412,89 @@ "win32" ] }, - "node_modules/@swc/core": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.7.0.tgz", - "integrity": "sha512-d4vMzH6ICllDwlPuhset2h8gu/USHdbyfJim+2hQEdxC0UONtfpmu38XBgNqRjStrji1Q5M10jfeUZL3cu1i8g==", + "node_modules/@sigstore/bundle": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@sigstore/bundle/-/bundle-2.3.2.tgz", + "integrity": "sha512-wueKWDk70QixNLB363yHc2D2ItTgYiMTdPwK8D9dKQMR3ZQ0c35IxP5xnwQ8cNLoCgCRcHf14kE+CLIvNX1zmA==", + "dev": true, + "dependencies": { + "@sigstore/protobuf-specs": "^0.3.2" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@sigstore/core": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@sigstore/core/-/core-1.1.0.tgz", + "integrity": "sha512-JzBqdVIyqm2FRQCulY6nbQzMpJJpSiJ8XXWMhtOX9eKgaXXpfNOF53lzQEjIydlStnd/eFtuC1dW4VYdD93oRg==", + "dev": true, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@sigstore/protobuf-specs": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@sigstore/protobuf-specs/-/protobuf-specs-0.3.2.tgz", + "integrity": "sha512-c6B0ehIWxMI8wiS/bj6rHMPqeFvngFV7cDU/MY+B16P9Z3Mp9k8L93eYZ7BYzSickzuqAQqAq0V956b3Ju6mLw==", + "dev": true, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@sigstore/sign": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@sigstore/sign/-/sign-2.3.2.tgz", + "integrity": "sha512-5Vz5dPVuunIIvC5vBb0APwo7qKA4G9yM48kPWJT+OEERs40md5GoUR1yedwpekWZ4m0Hhw44m6zU+ObsON+iDA==", + "dev": true, + "dependencies": { + "@sigstore/bundle": "^2.3.2", + "@sigstore/core": "^1.0.0", + "@sigstore/protobuf-specs": "^0.3.2", + "make-fetch-happen": "^13.0.1", + "proc-log": "^4.2.0", + "promise-retry": "^2.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@sigstore/tuf": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/@sigstore/tuf/-/tuf-2.3.4.tgz", + "integrity": "sha512-44vtsveTPUpqhm9NCrbU8CWLe3Vck2HO1PNLw7RIajbB7xhtn5RBPm1VNSCMwqGYHhDsBJG8gDF0q4lgydsJvw==", "dev": true, + "dependencies": { + "@sigstore/protobuf-specs": "^0.3.2", + "tuf-js": "^2.2.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@sigstore/verify": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@sigstore/verify/-/verify-1.2.1.tgz", + "integrity": "sha512-8iKx79/F73DKbGfRf7+t4dqrc0bRr0thdPrxAtCKWRm/F0tG71i6O1rvlnScncJLLBZHn3h8M3c1BSUAb9yu8g==", + "dev": true, + "dependencies": { + "@sigstore/bundle": "^2.3.2", + "@sigstore/core": "^1.1.0", + "@sigstore/protobuf-specs": "^0.3.2" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@swc/core": { + "version": "1.7.14", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.7.14.tgz", + "integrity": "sha512-9aeXeifnyuvc2pcuuhPQgVUwdpGEzZ+9nJu0W8/hNl/aESFsJGR5i9uQJRGu0atoNr01gK092fvmqMmQAPcKow==", + "devOptional": true, "hasInstallScript": true, "dependencies": { "@swc/counter": "^0.1.3", - "@swc/types": "^0.1.9" + "@swc/types": "^0.1.12" }, "engines": { "node": ">=10" @@ -1902,16 +2504,16 @@ "url": "https://opencollective.com/swc" }, "optionalDependencies": { - "@swc/core-darwin-arm64": "1.7.0", - "@swc/core-darwin-x64": "1.7.0", - "@swc/core-linux-arm-gnueabihf": "1.7.0", - "@swc/core-linux-arm64-gnu": "1.7.0", - "@swc/core-linux-arm64-musl": "1.7.0", - "@swc/core-linux-x64-gnu": "1.7.0", - "@swc/core-linux-x64-musl": "1.7.0", - "@swc/core-win32-arm64-msvc": "1.7.0", - "@swc/core-win32-ia32-msvc": "1.7.0", - "@swc/core-win32-x64-msvc": "1.7.0" + "@swc/core-darwin-arm64": "1.7.14", + "@swc/core-darwin-x64": "1.7.14", + "@swc/core-linux-arm-gnueabihf": "1.7.14", + "@swc/core-linux-arm64-gnu": "1.7.14", + "@swc/core-linux-arm64-musl": "1.7.14", + "@swc/core-linux-x64-gnu": "1.7.14", + "@swc/core-linux-x64-musl": "1.7.14", + "@swc/core-win32-arm64-msvc": "1.7.14", + "@swc/core-win32-ia32-msvc": "1.7.14", + "@swc/core-win32-x64-msvc": "1.7.14" }, "peerDependencies": { "@swc/helpers": "*" @@ -1923,13 +2525,12 @@ } }, "node_modules/@swc/core-darwin-arm64": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.7.0.tgz", - "integrity": "sha512-2ylhM7f0HwUwLrFYZAe/dse8PCbPsYcJS3Dt7Q8NT3PUn7vy6QOMxNcOPPuDrnmaXqQQO3oxdmRapguTxaat9g==", + "version": "1.7.14", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.7.14.tgz", + "integrity": "sha512-V0OUXjOH+hdGxDYG8NkQzy25mKOpcNKFpqtZEzLe5V/CpLJPnpg1+pMz70m14s9ZFda9OxsjlvPbg1FLUwhgIQ==", "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "darwin" @@ -1939,13 +2540,12 @@ } }, "node_modules/@swc/core-darwin-x64": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.7.0.tgz", - "integrity": "sha512-SgVnN4gT1Rb9YfTkp4FCUITqSs7Yj0uB2SUciu5CV3HuGvS5YXCUzh+KrwpLFtx8NIgivISKcNnb41mJi98X8Q==", + "version": "1.7.14", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.7.14.tgz", + "integrity": "sha512-9iFvUnxG6FC3An5ogp5jbBfQuUmTTwy8KMB+ZddUoPB3NR1eV+Y9vOh/tfWcenSJbgOKDLgYC5D/b1mHAprsrQ==", "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "darwin" @@ -1955,13 +2555,12 @@ } }, "node_modules/@swc/core-linux-arm-gnueabihf": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.7.0.tgz", - "integrity": "sha512-+Z9Dayart1iKJQEJJ9N/KS4z5EdXJE3WPFikY0jonKTo4Dd8RuyVz5yLvqcIMeVdz/SwximATaL6iJXw7hZS9A==", + "version": "1.7.14", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.7.14.tgz", + "integrity": "sha512-zGJsef9qPivKSH8Vv4F/HiBXBTHZ5Hs3ZjVGo/UIdWPJF8fTL9OVADiRrl34Q7zOZEtGXRwEKLUW1SCQcbDvZA==", "cpu": [ "arm" ], - "dev": true, "optional": true, "os": [ "linux" @@ -1971,13 +2570,12 @@ } }, "node_modules/@swc/core-linux-arm64-gnu": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.7.0.tgz", - "integrity": "sha512-UnLrCiZ1EI4shznJn0xP6DLgsXUSwtfsdgHhGYCrvbgVBBve3S9iFgVFEB3SPl7Q/TdowNbrN4zHU0oChfiNfw==", + "version": "1.7.14", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.7.14.tgz", + "integrity": "sha512-AxV3MPsoI7i4B8FXOew3dx3N8y00YoJYvIPfxelw07RegeCEH3aHp2U2DtgbP/NV1ugZMx0TL2Z2DEvocmA51g==", "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -1987,13 +2585,12 @@ } }, "node_modules/@swc/core-linux-arm64-musl": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.7.0.tgz", - "integrity": "sha512-H724UANA+ptsfwKRr9mnaDa9cb5fw0oFysiGKTgb3DMYcgk3Od0jMTnXVPFSVpo7FlmyxeC9K8ueUPBOoOK6XA==", + "version": "1.7.14", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.7.14.tgz", + "integrity": "sha512-JDLdNjUj3zPehd4+DrQD8Ltb3B5lD8D05IwePyDWw+uR/YPc7w/TX1FUVci5h3giJnlMCJRvi1IQYV7K1n7KtQ==", "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -2003,13 +2600,12 @@ } }, "node_modules/@swc/core-linux-x64-gnu": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.7.0.tgz", - "integrity": "sha512-SY3HA0K0Dpqt1HIfMLGpwL4hd4UaL2xHP5oZXPlRQPhUDZrbb4PbI3ZJnh66c63eL4ZR8EJ+HRFI0Alx5p69Zw==", + "version": "1.7.14", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.7.14.tgz", + "integrity": "sha512-Siy5OvPCLLWmMdx4msnEs8HvEVUEigSn0+3pbLjv78iwzXd0qSBNHUPZyC1xeurVaUbpNDxZTpPRIwpqNE2+Og==", "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -2019,13 +2615,12 @@ } }, "node_modules/@swc/core-linux-x64-musl": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.7.0.tgz", - "integrity": "sha512-cEJ2ebtV1v/5Ilb55E05J6F5SrHKQWzUttIhR5Mkayyo+yvPslcpByuFC3D+J7X1ebziTOBpWuMpUdjLfh3SMQ==", + "version": "1.7.14", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.7.14.tgz", + "integrity": "sha512-FtEGm9mwtRYQNK43WMtUIadxHs/ja2rnDurB99os0ZoFTGG2IHuht2zD97W0wB8JbqEabT1XwSG9Y5wmN+ciEQ==", "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -2035,13 +2630,12 @@ } }, "node_modules/@swc/core-win32-arm64-msvc": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.7.0.tgz", - "integrity": "sha512-ecQOOmzEssz+m0pR4xDYCGuvn3E/l0nQ3tk5jp1NA1lsAy4bMV0YbYCHjptYvWL/UjhIerIp3IlCJ8x5DodSog==", + "version": "1.7.14", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.7.14.tgz", + "integrity": "sha512-Jp8KDlfq7Ntt2/BXr0y344cYgB1zf0DaLzDZ1ZJR6rYlAzWYSccLYcxHa97VGnsYhhPspMpmCvHid97oe2hl4A==", "cpu": [ "arm64" ], - "dev": true, "optional": true, "os": [ "win32" @@ -2051,13 +2645,12 @@ } }, "node_modules/@swc/core-win32-ia32-msvc": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.7.0.tgz", - "integrity": "sha512-gz81seZkRn3zMnVOc7L5k6F4vQC82gIxmHiL+GedK+A37XI/X26AASU3zxvORnqQbwQYXQ+AEVckxBmFlz3v2g==", + "version": "1.7.14", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.7.14.tgz", + "integrity": "sha512-I+cFsXF0OU0J9J4zdWiQKKLURO5dvCujH9Jr8N0cErdy54l9d4gfIxdctfTF+7FyXtWKLTCkp+oby9BQhkFGWA==", "cpu": [ "ia32" ], - "dev": true, "optional": true, "os": [ "win32" @@ -2067,13 +2660,12 @@ } }, "node_modules/@swc/core-win32-x64-msvc": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.7.0.tgz", - "integrity": "sha512-b5Fd1xEOw9uqBpj2lqsaR4Iq9UhiL84hNDcEsi6DQA7Y1l85waQAslTbS0E4/pJ1PISAs0jW0zIGLco1eaWBOg==", + "version": "1.7.14", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.7.14.tgz", + "integrity": "sha512-NNrprQCK6d28mG436jVo2TD+vACHseUECacEBGZ9Ef0qfOIWS1XIt2MisQKG0Oea2VvLFl6tF/V4Lnx/H0Sn3Q==", "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "win32" @@ -2086,13 +2678,13 @@ "version": "0.1.3", "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==", - "dev": true + "devOptional": true }, "node_modules/@swc/types": { "version": "0.1.12", "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.12.tgz", "integrity": "sha512-wBJA+SdtkbFhHjTMYH+dEH1y4VpfGdAc2Kw/LK09i9bXd/K6j6PkDcFCEzb6iVfZMkPRrl/q0e3toqTAJdkIVA==", - "dev": true, + "devOptional": true, "dependencies": { "@swc/counter": "^0.1.3" } @@ -2121,6 +2713,56 @@ "react": "^18.0.0" } }, + "node_modules/@tsconfig/node10": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", + "optional": true, + "peer": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "optional": true, + "peer": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "optional": true, + "peer": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "optional": true, + "peer": true + }, + "node_modules/@tufjs/canonical-json": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tufjs/canonical-json/-/canonical-json-2.0.0.tgz", + "integrity": "sha512-yVtV8zsdo8qFHe+/3kw81dSLyF7D576A5cCFCi4X7B39tWT7SekaEFUnvnWJHz+9qO7qJTah1JbrDjWKqFtdWA==", + "dev": true, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@tufjs/models": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@tufjs/models/-/models-2.0.1.tgz", + "integrity": "sha512-92F7/SFyufn4DXsha9+QfKnN03JGqtMFMXgSHbZOo8JG59WkTni7UzAouNQDf7AuP9OAMxVOPQcqG3sB7w+kkg==", + "dev": true, + "dependencies": { + "@tufjs/canonical-json": "2.0.0", + "minimatch": "^9.0.4" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, "node_modules/@types/estree": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", @@ -2139,7 +2781,7 @@ "version": "20.14.11", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.11.tgz", "integrity": "sha512-kprQpL8MMeszbz6ojB5/tU8PLN4kesnN8Gjzw349rDlNgsSzg90lAVj3llK99Dh7JON+t9AuscPPFW6mPbTnSA==", - "dev": true, + "devOptional": true, "dependencies": { "undici-types": "~5.26.4" } @@ -2180,16 +2822,16 @@ "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.17.0.tgz", - "integrity": "sha512-pyiDhEuLM3PuANxH7uNYan1AaFs5XE0zw1hq69JBvGvE7gSuEoQl1ydtEe/XQeoC3GQxLXyOVa5kNOATgM638A==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.18.0.tgz", + "integrity": "sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.17.0", - "@typescript-eslint/type-utils": "7.17.0", - "@typescript-eslint/utils": "7.17.0", - "@typescript-eslint/visitor-keys": "7.17.0", + "@typescript-eslint/scope-manager": "7.18.0", + "@typescript-eslint/type-utils": "7.18.0", + "@typescript-eslint/utils": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", @@ -2213,15 +2855,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.17.0.tgz", - "integrity": "sha512-puiYfGeg5Ydop8eusb/Hy1k7QmOU6X3nvsqCgzrB2K4qMavK//21+PzNE8qeECgNOIoertJPUC1SpegHDI515A==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.18.0.tgz", + "integrity": "sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "7.17.0", - "@typescript-eslint/types": "7.17.0", - "@typescript-eslint/typescript-estree": "7.17.0", - "@typescript-eslint/visitor-keys": "7.17.0", + "@typescript-eslint/scope-manager": "7.18.0", + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/typescript-estree": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0", "debug": "^4.3.4" }, "engines": { @@ -2241,13 +2883,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.17.0.tgz", - "integrity": "sha512-0P2jTTqyxWp9HiKLu/Vemr2Rg1Xb5B7uHItdVZ6iAenXmPo4SZ86yOPCJwMqpCyaMiEHTNqizHfsbmCFT1x9SA==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.18.0.tgz", + "integrity": "sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.17.0", - "@typescript-eslint/visitor-keys": "7.17.0" + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -2258,13 +2900,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.17.0.tgz", - "integrity": "sha512-XD3aaBt+orgkM/7Cei0XNEm1vwUxQ958AOLALzPlbPqb8C1G8PZK85tND7Jpe69Wualri81PLU+Zc48GVKIMMA==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.18.0.tgz", + "integrity": "sha512-XL0FJXuCLaDuX2sYqZUUSOJ2sG5/i1AAze+axqmLnSkNEVMVYLF+cbwlB2w8D1tinFuSikHmFta+P+HOofrLeA==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "7.17.0", - "@typescript-eslint/utils": "7.17.0", + "@typescript-eslint/typescript-estree": "7.18.0", + "@typescript-eslint/utils": "7.18.0", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, @@ -2285,9 +2927,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.17.0.tgz", - "integrity": "sha512-a29Ir0EbyKTKHnZWbNsrc/gqfIBqYPwj3F2M+jWE/9bqfEHg0AMtXzkbUkOG6QgEScxh2+Pz9OXe11jHDnHR7A==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.18.0.tgz", + "integrity": "sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==", "dev": true, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -2298,13 +2940,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.17.0.tgz", - "integrity": "sha512-72I3TGq93t2GoSBWI093wmKo0n6/b7O4j9o8U+f65TVD0FS6bI2180X5eGEr8MA8PhKMvYe9myZJquUT2JkCZw==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.18.0.tgz", + "integrity": "sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.17.0", - "@typescript-eslint/visitor-keys": "7.17.0", + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -2326,15 +2968,15 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.17.0.tgz", - "integrity": "sha512-r+JFlm5NdB+JXc7aWWZ3fKSm1gn0pkswEwIYsrGPdsT2GjsRATAKXiNtp3vgAAO1xZhX8alIOEQnNMl3kbTgJw==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.18.0.tgz", + "integrity": "sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.17.0", - "@typescript-eslint/types": "7.17.0", - "@typescript-eslint/typescript-estree": "7.17.0" + "@typescript-eslint/scope-manager": "7.18.0", + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/typescript-estree": "7.18.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -2348,12 +2990,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.17.0.tgz", - "integrity": "sha512-RVGC9UhPOCsfCdI9pU++K4nD7to+jTcMIbXTSOcrLqUEW6gF2pU1UUbYJKc9cvcRSK1UDeMJ7pdMxf4bhMpV/A==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.18.0.tgz", + "integrity": "sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.17.0", + "@typescript-eslint/types": "7.18.0", "eslint-visitor-keys": "^3.4.3" }, "engines": { @@ -2382,11 +3024,20 @@ "vite": "^4 || ^5" } }, + "node_modules/abbrev": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz", + "integrity": "sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/acorn": { "version": "8.12.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", - "dev": true, + "devOptional": true, "bin": { "acorn": "bin/acorn" }, @@ -2403,6 +3054,44 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, + "node_modules/acorn-walk": { + "version": "8.3.3", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz", + "integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==", + "optional": true, + "peer": true, + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/agent-base": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", + "dev": true, + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -2419,6 +3108,15 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", @@ -2532,9 +3230,9 @@ } }, "node_modules/axios": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.2.tgz", - "integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.4.tgz", + "integrity": "sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==", "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", @@ -2546,6 +3244,41 @@ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/bin-links": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/bin-links/-/bin-links-4.0.4.tgz", + "integrity": "sha512-cMtq4W5ZsEwcutJrVId+a/tjt8GSbS+h0oNkdl6+6rBuEv8Ot33Bevj5KPm40t309zuhVic8NjpuL42QCiJWWA==", + "dev": true, + "dependencies": { + "cmd-shim": "^6.0.0", + "npm-normalize-package-bin": "^3.0.0", + "read-cmd-shim": "^4.0.0", + "write-file-atomic": "^5.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/binary-extensions": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", @@ -2557,6 +3290,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, "node_modules/brace-expansion": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", @@ -2608,6 +3352,73 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/cacache": { + "version": "18.0.4", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-18.0.4.tgz", + "integrity": "sha512-B+L5iIa9mgcjLbliir2th36yEwPftrzteHYujzsx3dFP/31GCHcIeS8f5MGd80odLOjaOvSpU3EEAmRQptkxLQ==", + "dev": true, + "dependencies": { + "@npmcli/fs": "^3.1.0", + "fs-minipass": "^3.0.0", + "glob": "^10.2.2", + "lru-cache": "^10.0.1", + "minipass": "^7.0.3", + "minipass-collect": "^2.0.1", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^4.0.0", + "ssri": "^10.0.0", + "tar": "^6.1.11", + "unique-filename": "^3.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/cacache/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -2730,6 +3541,15 @@ "node": ">= 6" } }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, "node_modules/class-variance-authority": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.0.tgz", @@ -2749,6 +3569,48 @@ "node": ">=6" } }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, "node_modules/clsx": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", @@ -2757,6 +3619,15 @@ "node": ">=6" } }, + "node_modules/cmd-shim": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/cmd-shim/-/cmd-shim-6.0.3.tgz", + "integrity": "sha512-FMabTRlc5t5zjdenF6mS0MBeFZm0XqHqeOkcskKFb/LYCcRQ5fVgLOHVc4Lq9CqABd9zhjwPjMBCJvMCziSVtA==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/cmdk": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/cmdk/-/cmdk-1.0.0.tgz", @@ -3161,12 +4032,51 @@ "node": ">= 6" } }, + "node_modules/common-ancestor-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/common-ancestor-path/-/common-ancestor-path-1.0.1.tgz", + "integrity": "sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w==", + "dev": true + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, + "node_modules/cosmiconfig": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", + "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", + "dev": true, + "dependencies": { + "env-paths": "^2.2.1", + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "optional": true, + "peer": true + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -3188,6 +4098,16 @@ "node": ">=4" } }, + "node_modules/css-selector-tokenizer": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.8.0.tgz", + "integrity": "sha512-Jd6Ig3/pe62/qe5SBPTN8h8LeUg/pT4lLgtavPf7updwwHpvFzxvOQBHYj2LZDMjUnBzgvIUSjRcf6oT5HzHFg==", + "dev": true, + "dependencies": { + "cssesc": "^3.0.0", + "fastparse": "^1.1.2" + } + }, "node_modules/css-to-react-native": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz", @@ -3214,6 +4134,34 @@ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" }, + "node_modules/culori": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/culori/-/culori-3.3.0.tgz", + "integrity": "sha512-pHJg+jbuFsCjz9iclQBqyL3B2HLCBF71BwVNujUYEvCeQMvV97R59MNK3R2+jgJ3a1fcZgI9B3vYgz8lzr/BFQ==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/daisyui": { + "version": "4.12.10", + "resolved": "https://registry.npmjs.org/daisyui/-/daisyui-4.12.10.tgz", + "integrity": "sha512-jp1RAuzbHhGdXmn957Z2XsTZStXGHzFfF0FgIOZj3Wv9sH7OZgLfXTRZNfKVYxltGUOBsG1kbWAdF5SrqjebvA==", + "dev": true, + "dependencies": { + "css-selector-tokenizer": "^0.8", + "culori": "^3", + "picocolors": "^1", + "postcss-js": "^4" + }, + "engines": { + "node": ">=16.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/daisyui" + } + }, "node_modules/debug": { "version": "4.3.5", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", @@ -3237,6 +4185,18 @@ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "dev": true, + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -3255,6 +4215,16 @@ "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==" }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "optional": true, + "peer": true, + "engines": { + "node": ">=0.3.1" + } + }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -3290,9 +4260,9 @@ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" }, "node_modules/electron-to-chromium": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.0.tgz", - "integrity": "sha512-Vb3xHHYnLseK8vlMJQKJYXJ++t4u1/qJ3vykuVrVjvdiOEhYyT1AuP4x03G8EnPmYvYOhe9T+dADTmthjRQMkA==", + "version": "1.5.13", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.13.tgz", + "integrity": "sha512-lbBcvtIJ4J6sS4tb5TLp1b4LyfCdMkwStzXPyAgVgTRAsep4bvrAGaBOP7ZJtQMNJpSQ9SqG4brWOroNaQtm7Q==", "dev": true }, "node_modules/emoji-regex": { @@ -3300,6 +4270,53 @@ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" }, + "node_modules/encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "dev": true, + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, + "node_modules/enquirer": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", + "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", + "dev": true, + "dependencies": { + "ansi-colors": "^4.1.1", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/err-code": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", + "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", + "dev": true + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, "node_modules/esbuild": { "version": "0.21.5", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", @@ -3414,6 +4431,57 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint-config-prettier": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", + "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", + "dev": true, + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-plugin-header": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-header/-/eslint-plugin-header-3.1.1.tgz", + "integrity": "sha512-9vlKxuJ4qf793CmeeSrZUvVClw6amtpghq3CuWcB5cUNnWHQhgcqy5eF8oVKFk1G3Y/CbchGfEaw3wiIJaNmVg==", + "dev": true, + "peerDependencies": { + "eslint": ">=7.7.0" + } + }, + "node_modules/eslint-plugin-prettier": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.2.1.tgz", + "integrity": "sha512-gH3iR3g4JfF+yYPaJYkN7jEl9QbweL/YfkoRlNnuIEHEz1vHVlCmWOS+eGGiRuzHQXdJFCOTxRgvju9b8VUmrw==", + "dev": true, + "dependencies": { + "prettier-linter-helpers": "^1.0.0", + "synckit": "^0.9.1" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-plugin-prettier" + }, + "peerDependencies": { + "@types/eslint": ">=8.0.0", + "eslint": ">=8.0.0", + "eslint-config-prettier": "*", + "prettier": ">=3.0.0" + }, + "peerDependenciesMeta": { + "@types/eslint": { + "optional": true + }, + "eslint-config-prettier": { + "optional": true + } + } + }, "node_modules/eslint-plugin-react-hooks": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.2.tgz", @@ -3427,9 +4495,9 @@ } }, "node_modules/eslint-plugin-react-refresh": { - "version": "0.4.9", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.9.tgz", - "integrity": "sha512-QK49YrBAo5CLNLseZ7sZgvgTy21E6NEw22eZqc4teZfH8pxV3yXc9XXOYfUI6JNpw7mfHNkAeWtBxrTyykB6HA==", + "version": "0.4.11", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.11.tgz", + "integrity": "sha512-wrAKxMbVr8qhXTtIKfXqAn5SAtRZt0aXxe5P23Fh4pUAdC6XEsybGLB8P0PI4j1yYqOgUEUlzKAGDfo7rJOjcw==", "dev": true, "peerDependencies": { "eslint": ">=7" @@ -3544,12 +4612,24 @@ "node": ">=0.10.0" } }, + "node_modules/exponential-backoff": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.1.tgz", + "integrity": "sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==", + "dev": true + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, + "node_modules/fast-diff": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", + "dev": true + }, "node_modules/fast-glob": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", @@ -3588,6 +4668,12 @@ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, + "node_modules/fastparse": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz", + "integrity": "sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==", + "dev": true + }, "node_modules/fastq": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", @@ -3759,6 +4845,18 @@ } } }, + "node_modules/fs-minipass": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz", + "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==", + "dev": true, + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -3783,7 +4881,67 @@ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/generate-license-file": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/generate-license-file/-/generate-license-file-3.5.1.tgz", + "integrity": "sha512-XgZPDopGzFim1Dmp2DdERreSD2rXmLz1X2g1Zx1KnmCNCh4M5BmQT96cSl28nn/HppAzQRZcZgvus6U5Og/vqg==", + "dev": true, + "dependencies": { + "@commander-js/extra-typings": "^12.0.0", + "@npmcli/arborist": "^7.0.0", + "cli-spinners": "^2.6.0", + "commander": "^12.0.0", + "cosmiconfig": "^9.0.0", + "enquirer": "^2.3.6", + "glob": "^10.3.0", + "json5": "^2.2.3", + "ora": "^5.4.1", + "tslib": "^2.3.0", + "zod": "^3.21.4" + }, + "bin": { + "generate-license-file": "bin/generate-license-file" + } + }, + "node_modules/generate-license-file/node_modules/@commander-js/extra-typings": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/@commander-js/extra-typings/-/extra-typings-12.1.0.tgz", + "integrity": "sha512-wf/lwQvWAA0goIghcb91dQYpkLBcyhOhQNqG/VgWhnKzgt+UOMvra7EX/2fv70arm5RW+PUHoQHHDa6/p77Eqg==", + "dev": true, + "peerDependencies": { + "commander": "~12.1.0" + } + }, + "node_modules/generate-license-file/node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "dev": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/generate-license-file/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/get-nonce": { @@ -3891,6 +5049,12 @@ "csstype": "^3.0.10" } }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, "node_modules/graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", @@ -3950,6 +5114,83 @@ "node": "*" } }, + "node_modules/hosted-git-info": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz", + "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==", + "dev": true, + "dependencies": { + "lru-cache": "^10.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/http-cache-semantics": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", + "dev": true + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dev": true, + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", + "dev": true, + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/ignore": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", @@ -3959,6 +5200,18 @@ "node": ">= 4" } }, + "node_modules/ignore-walk": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-6.0.5.tgz", + "integrity": "sha512-VuuG0wCnjhnylG1ABXT3dAuIpTNDs/G8jlpmwXY03fXoXy/8ZK8/T+hMzt8L4WnrLCJgdybqgPagnF/f97cg3A==", + "dev": true, + "dependencies": { + "minimatch": "^9.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", @@ -3984,6 +5237,15 @@ "node": ">=0.8.19" } }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -4001,6 +5263,15 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, + "node_modules/ini": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.3.tgz", + "integrity": "sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/invariant": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", @@ -4009,6 +5280,19 @@ "loose-envify": "^1.0.0" } }, + "node_modules/ip-address": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", + "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", + "dev": true, + "dependencies": { + "jsbn": "1.1.0", + "sprintf-js": "^1.1.3" + }, + "engines": { + "node": ">= 12" + } + }, "node_modules/is-alphabetical": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", @@ -4031,6 +5315,12 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -4101,6 +5391,21 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-lambda": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", + "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==", + "dev": true + }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -4118,6 +5423,18 @@ "node": ">=8" } }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -4162,12 +5479,27 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/jsbn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", + "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", + "dev": true + }, "node_modules/json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", "dev": true }, + "node_modules/json-parse-even-better-errors": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.2.tgz", + "integrity": "sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -4180,6 +5512,48 @@ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, + "node_modules/json-stringify-nice": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/json-stringify-nice/-/json-stringify-nice-1.1.4.tgz", + "integrity": "sha512-5Z5RFW63yxReJ7vANgW6eZFGWaQvnPE3WNmZoOJrSkGju2etKA2L5rrOa1sm877TVTFt57A80BH1bArcmlLfPw==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", + "dev": true, + "engines": [ + "node >= 0.2.0" + ] + }, + "node_modules/just-diff": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/just-diff/-/just-diff-6.0.2.tgz", + "integrity": "sha512-S59eriX5u3/QhMNq3v/gm8Kd0w8OS6Tz2FS1NG4blv+z0MuQcBRJyFWjdovM0Rad4/P4aUPFtnkNjMjyMlMSYA==", + "dev": true + }, + "node_modules/just-diff-apply": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/just-diff-apply/-/just-diff-apply-5.5.0.tgz", + "integrity": "sha512-OYTthRfSh55WOItVqwpefPtNt2VdKsq5AnAK6apdtR6yCH8pr0CmSr710J0Mf+WdQy7K/OzMy7K2MgAfdQURDw==", + "dev": true + }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", @@ -4236,6 +5610,22 @@ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -4273,6 +5663,36 @@ "react": "^16.5.1 || ^17.0.0 || ^18.0.0" } }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "optional": true, + "peer": true + }, + "node_modules/make-fetch-happen": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-13.0.1.tgz", + "integrity": "sha512-cKTUFc/rbKUd/9meOvgrpJ2WrNzymt6jfRDdwg5UCnVzv9dTpEj9JS5m3wtziXVCjluIXyL8pcaukYqezIzZQA==", + "dev": true, + "dependencies": { + "@npmcli/agent": "^2.0.0", + "cacache": "^18.0.0", + "http-cache-semantics": "^4.1.1", + "is-lambda": "^1.0.1", + "minipass": "^7.0.2", + "minipass-fetch": "^3.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "proc-log": "^4.2.0", + "promise-retry": "^2.0.1", + "ssri": "^10.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -4282,9 +5702,9 @@ } }, "node_modules/micromatch": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", - "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" @@ -4306,40 +5726,187 @@ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "dependencies": { - "mime-db": "1.52.0" + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/mini-svg-data-uri": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz", + "integrity": "sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==", + "bin": { + "mini-svg-data-uri": "cli.js" + } + }, + "node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minipass-collect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-2.0.1.tgz", + "integrity": "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==", + "dev": true, + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minipass-fetch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.5.tgz", + "integrity": "sha512-2N8elDQAtSnFV0Dk7gt15KHsS0Fyz6CbYZ360h0WTYV1Ty46li3rAXVOQj1THMNLdmrD9Vt5pBPtWtVkpwGBqg==", + "dev": true, + "dependencies": { + "minipass": "^7.0.3", + "minipass-sized": "^1.0.3", + "minizlib": "^2.1.2" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } + }, + "node_modules/minipass-flush": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", + "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-flush/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", + "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", + "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" }, "engines": { - "node": ">= 0.6" + "node": ">=8" } }, - "node_modules/mini-svg-data-uri": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz", - "integrity": "sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==", - "bin": { - "mini-svg-data-uri": "cli.js" + "node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" } }, - "node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, "dependencies": { - "brace-expansion": "^2.0.1" + "yallist": "^4.0.0" }, "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">=8" } }, - "node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": ">=10" } }, "node_modules/ms": { @@ -4381,12 +5948,118 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/node-gyp": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-10.2.0.tgz", + "integrity": "sha512-sp3FonBAaFe4aYTcFdZUn2NYkbP7xroPGYvQmP4Nl5PxamznItBnNCgjrVTKrEfQynInMsJvZrdmqUnysCJ8rw==", + "dev": true, + "dependencies": { + "env-paths": "^2.2.0", + "exponential-backoff": "^3.1.1", + "glob": "^10.3.10", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^13.0.0", + "nopt": "^7.0.0", + "proc-log": "^4.1.0", + "semver": "^7.3.5", + "tar": "^6.2.1", + "which": "^4.0.0" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/node-gyp/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/node-gyp/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "engines": { + "node": ">=16" + } + }, + "node_modules/node-gyp/node_modules/which": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", + "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", + "dev": true, + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^16.13.0 || >=18.0.0" + } + }, "node_modules/node-releases": { "version": "2.0.18", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", "dev": true }, + "node_modules/nopt": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-7.2.1.tgz", + "integrity": "sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==", + "dev": true, + "dependencies": { + "abbrev": "^2.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/normalize-package-data": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.2.tgz", + "integrity": "sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==", + "dev": true, + "dependencies": { + "hosted-git-info": "^7.0.0", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -4404,6 +6077,100 @@ "node": ">=0.10.0" } }, + "node_modules/npm-bundled": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-3.0.1.tgz", + "integrity": "sha512-+AvaheE/ww1JEwRHOrn4WHNzOxGtVp+adrg2AeZS/7KuxGUYFuBta98wYpfHBbJp6Tg6j1NKSEVHNcfZzJHQwQ==", + "dev": true, + "dependencies": { + "npm-normalize-package-bin": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-install-checks": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-6.3.0.tgz", + "integrity": "sha512-W29RiK/xtpCGqn6f3ixfRYGk+zRyr+Ew9F2E20BfXxT5/euLdA/Nm7fO7OeTGuAmTs30cpgInyJ0cYe708YTZw==", + "dev": true, + "dependencies": { + "semver": "^7.1.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-normalize-package-bin": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-3.0.1.tgz", + "integrity": "sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-package-arg": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-11.0.3.tgz", + "integrity": "sha512-sHGJy8sOC1YraBywpzQlIKBE4pBbGbiF95U6Auspzyem956E0+FtDtsx1ZxlOJkQCZ1AFXAY/yuvtFYrOxF+Bw==", + "dev": true, + "dependencies": { + "hosted-git-info": "^7.0.0", + "proc-log": "^4.0.0", + "semver": "^7.3.5", + "validate-npm-package-name": "^5.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm-packlist": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-8.0.2.tgz", + "integrity": "sha512-shYrPFIS/JLP4oQmAwDyk5HcyysKW8/JLTEA32S0Z5TzvpaeeX2yMFfoK1fjEBnCBvVyIB/Jj/GBFdm0wsgzbA==", + "dev": true, + "dependencies": { + "ignore-walk": "^6.0.4" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-pick-manifest": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-9.1.0.tgz", + "integrity": "sha512-nkc+3pIIhqHVQr085X9d2JzPzLyjzQS96zbruppqC9aZRm/x8xx6xhI98gHtsfELP2bE+loHq8ZaHFHhe+NauA==", + "dev": true, + "dependencies": { + "npm-install-checks": "^6.0.0", + "npm-normalize-package-bin": "^3.0.0", + "npm-package-arg": "^11.0.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm-registry-fetch": { + "version": "17.1.0", + "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-17.1.0.tgz", + "integrity": "sha512-5+bKQRH0J1xG1uZ1zMNvxW0VEyoNWgJpY9UDuluPFLKDfJ9u2JmmjmTJV1srBGQOROfdBMiVvnH2Zvpbm+xkVA==", + "dev": true, + "dependencies": { + "@npmcli/redact": "^2.0.0", + "jsonparse": "^1.3.1", + "make-fetch-happen": "^13.0.0", + "minipass": "^7.0.2", + "minipass-fetch": "^3.0.0", + "minizlib": "^2.1.2", + "npm-package-arg": "^11.0.0", + "proc-log": "^4.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -4429,6 +6196,21 @@ "wrappy": "1" } }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/optionator": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", @@ -4446,6 +6228,29 @@ "node": ">= 0.8.0" } }, + "node_modules/ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "dev": true, + "dependencies": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -4476,11 +6281,57 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/package-json-from-dist": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==" }, + "node_modules/pacote": { + "version": "18.0.6", + "resolved": "https://registry.npmjs.org/pacote/-/pacote-18.0.6.tgz", + "integrity": "sha512-+eK3G27SMwsB8kLIuj4h1FUhHtwiEUo21Tw8wNjmvdlpOEr613edv+8FUsTj/4F/VN5ywGE19X18N7CC2EJk6A==", + "dev": true, + "dependencies": { + "@npmcli/git": "^5.0.0", + "@npmcli/installed-package-contents": "^2.0.1", + "@npmcli/package-json": "^5.1.0", + "@npmcli/promise-spawn": "^7.0.0", + "@npmcli/run-script": "^8.0.0", + "cacache": "^18.0.0", + "fs-minipass": "^3.0.0", + "minipass": "^7.0.2", + "npm-package-arg": "^11.0.0", + "npm-packlist": "^8.0.0", + "npm-pick-manifest": "^9.0.0", + "npm-registry-fetch": "^17.0.0", + "proc-log": "^4.0.0", + "promise-retry": "^2.0.1", + "sigstore": "^2.2.0", + "ssri": "^10.0.0", + "tar": "^6.1.11" + }, + "bin": { + "pacote": "bin/index.js" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -4493,6 +6344,20 @@ "node": ">=6" } }, + "node_modules/parse-conflict-json": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/parse-conflict-json/-/parse-conflict-json-3.0.1.tgz", + "integrity": "sha512-01TvEktc68vwbJOtWZluyWeVGWjP+bZwXtPDMQVbBKzbJ/vZBif0L69KH1+cHv1SZ6e0FKLvjyHe8mqsIqYOmw==", + "dev": true, + "dependencies": { + "json-parse-even-better-errors": "^3.0.0", + "just-diff": "^6.0.0", + "just-diff-apply": "^5.2.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/parse-entities": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", @@ -4510,6 +6375,30 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse-json/node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -4598,9 +6487,9 @@ } }, "node_modules/postcss": { - "version": "8.4.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz", - "integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==", + "version": "8.4.41", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.41.tgz", + "integrity": "sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==", "funding": [ { "type": "opencollective", @@ -4739,26 +6628,109 @@ "node": ">=4" } }, - "node_modules/postcss-value-parser": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", + "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", + "dev": true, + "peer": true, + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "dependencies": { + "fast-diff": "^1.1.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/prismjs": { + "version": "1.29.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz", + "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==", + "engines": { + "node": ">=6" + } + }, + "node_modules/proc-log": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-4.2.0.tgz", + "integrity": "sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/proggy": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/proggy/-/proggy-2.0.0.tgz", + "integrity": "sha512-69agxLtnI8xBs9gUGqEnK26UfiexpHy+KUpBQWabiytQjnn5wFY8rklAi7GRfABIuPNnQ/ik48+LGLkYYJcy4A==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/promise-all-reject-late": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-all-reject-late/-/promise-all-reject-late-1.0.1.tgz", + "integrity": "sha512-vuf0Lf0lOxyQREH7GDIOUMLS7kz+gs8i6B+Yi8dC68a2sychGrHTJYghMBD6k7eUcH0H5P73EckCA48xijWqXw==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/promise-call-limit": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/promise-call-limit/-/promise-call-limit-3.0.1.tgz", + "integrity": "sha512-utl+0x8gIDasV5X+PI5qWEPqH6fJS0pFtQ/4gZ95xfEFb/89dmh+/b895TbFDBLiafBvxD/PGTKfvxl4kH/pQg==", "dev": true, - "engines": { - "node": ">= 0.8.0" + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/prismjs": { - "version": "1.29.0", - "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz", - "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==", + "node_modules/promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", + "dev": true + }, + "node_modules/promise-retry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", + "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", + "dev": true, + "dependencies": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + }, "engines": { - "node": ">=6" + "node": ">=10" } }, "node_modules/property-information": { @@ -4996,6 +6968,42 @@ "pify": "^2.3.0" } }, + "node_modules/read-cmd-shim": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/read-cmd-shim/-/read-cmd-shim-4.0.0.tgz", + "integrity": "sha512-yILWifhaSEEytfXI76kB9xEEiG1AiozaCJZ83A87ytjRiN+jVibXjedjCRNjoZviinhG+4UkalO3mWTd8u5O0Q==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/read-package-json-fast": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/read-package-json-fast/-/read-package-json-fast-3.0.2.tgz", + "integrity": "sha512-0J+Msgym3vrLOUB3hzQCuZHII0xkNGCtz/HJH9xZshwv9DbDwkw1KaE3gx/e2J5rpEY5rtOy6cyhKOPrkP7FZw==", + "dev": true, + "dependencies": { + "json-parse-even-better-errors": "^3.0.0", + "npm-normalize-package-bin": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -5059,6 +7067,34 @@ "node": ">=4" } }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/restore-cursor/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -5141,6 +7177,33 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true, + "optional": true + }, "node_modules/scheduler": { "version": "0.23.2", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", @@ -5196,6 +7259,23 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/sigstore": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/sigstore/-/sigstore-2.3.1.tgz", + "integrity": "sha512-8G+/XDU8wNsJOQS5ysDVO0Etg9/2uA5gR9l4ZwijjlwxBcrU6RPfwi2+jJmbP+Ap1Hlp/nVAaEO4Fj22/SL2gQ==", + "dev": true, + "dependencies": { + "@sigstore/bundle": "^2.3.2", + "@sigstore/core": "^1.0.0", + "@sigstore/protobuf-specs": "^0.3.2", + "@sigstore/sign": "^2.3.2", + "@sigstore/tuf": "^2.3.4", + "@sigstore/verify": "^1.2.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -5205,6 +7285,44 @@ "node": ">=8" } }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "dev": true, + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz", + "integrity": "sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==", + "dev": true, + "dependencies": { + "ip-address": "^9.0.5", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.4.tgz", + "integrity": "sha512-GNAq/eg8Udq2x0eNiFkr9gRg5bA7PXEWagQdeRX4cPSG+X/8V38v637gim9bjFptMk1QWsCTr0ttrJEiXbNnRw==", + "dev": true, + "dependencies": { + "agent-base": "^7.1.1", + "debug": "^4.3.4", + "socks": "^2.8.3" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/source-map-js": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", @@ -5222,6 +7340,65 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.20", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.20.tgz", + "integrity": "sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw==", + "dev": true + }, + "node_modules/sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", + "dev": true + }, + "node_modules/ssri": { + "version": "10.0.6", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.6.tgz", + "integrity": "sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==", + "dev": true, + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, "node_modules/string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", @@ -5444,6 +7621,22 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/synckit": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.1.tgz", + "integrity": "sha512-7gr8p9TQP6RAHusBOSLs46F4564ZrjV8xFmw5zCmgmhGUcw2hxsShhJ6CEiHQMgPDwAQ1fWHPM0ypc4RMAig4A==", + "dev": true, + "dependencies": { + "@pkgr/core": "^0.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, "node_modules/tailwind-merge": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.4.0.tgz", @@ -5497,6 +7690,56 @@ "tailwindcss": ">=3.0.0 || insiders" } }, + "node_modules/tar": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", + "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", + "dev": true, + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tar/node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/tar/node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tar/node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -5533,6 +7776,15 @@ "node": ">=8.0" } }, + "node_modules/treeverse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/treeverse/-/treeverse-3.0.0.tgz", + "integrity": "sha512-gcANaAnd2QDZFmHFEOF4k7uc1J/6a6z3DJMd/QwEyxLoKGiptJRwid582r7QIsFlFMIZ3SnxfS52S4hm2DHkuQ==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/ts-api-utils": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", @@ -5550,11 +7802,76 @@ "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==" }, + "node_modules/ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "optional": true, + "peer": true, + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/ts-node/node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "optional": true, + "peer": true + }, "node_modules/tslib": { "version": "2.6.3", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, + "node_modules/tuf-js": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tuf-js/-/tuf-js-2.2.1.tgz", + "integrity": "sha512-GwIJau9XaA8nLVbUXsN3IlFi7WmQ48gBUrl3FTkkL/XLu/POhBzfmX9hd33FNMX1qAsfl6ozO1iMmW9NC8YniA==", + "dev": true, + "dependencies": { + "@tufjs/models": "2.0.1", + "debug": "^4.3.4", + "make-fetch-happen": "^13.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -5583,7 +7900,7 @@ "version": "5.5.4", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", - "dev": true, + "devOptional": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -5596,7 +7913,31 @@ "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "dev": true + "devOptional": true + }, + "node_modules/unique-filename": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-3.0.0.tgz", + "integrity": "sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==", + "dev": true, + "dependencies": { + "unique-slug": "^4.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/unique-slug": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-4.0.0.tgz", + "integrity": "sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } }, "node_modules/update-browserslist-db": { "version": "1.1.0", @@ -5683,6 +8024,32 @@ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "optional": true, + "peer": true + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/validate-npm-package-name": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-5.0.1.tgz", + "integrity": "sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/vaul": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/vaul/-/vaul-0.9.1.tgz", @@ -5750,6 +8117,21 @@ } } }, + "node_modules/walk-up-path": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/walk-up-path/-/walk-up-path-3.0.1.tgz", + "integrity": "sha512-9YlCL/ynK3CTlrSRrDxZvUauLzAswPCrsaCgilqFevUYpeEW0/3ScEjaa3kbW/T0ghhkEr7mv+fpjqn1Y1YuTA==", + "dev": true + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "dev": true, + "dependencies": { + "defaults": "^1.0.3" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -5866,6 +8248,19 @@ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true }, + "node_modules/write-file-atomic": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", + "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", @@ -5874,6 +8269,12 @@ "node": ">=0.4" } }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "node_modules/yaml": { "version": "2.4.5", "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.5.tgz", @@ -5885,6 +8286,16 @@ "node": ">= 14" } }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "optional": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/app/frontend/package.json b/app/frontend/package.json index 8e8ffc02..3debca3f 100644 --- a/app/frontend/package.json +++ b/app/frontend/package.json @@ -4,13 +4,15 @@ "version": "0.0.0", "type": "module", "scripts": { - "dev": "vite", + "dev": "vite ", "build": "tsc && vite build", "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", - "preview": "vite preview" + "preview": "vite preview", + "generate-license": "npx generate-license-file --input package.json --output ./third-party-licenses.txt" }, "dependencies": { "@hookform/resolvers": "^3.3.4", + "@radix-ui/react-accordion": "^1.2.0", "@radix-ui/react-aspect-ratio": "^1.1.0", "@radix-ui/react-collapsible": "^1.0.3", "@radix-ui/react-dialog": "^1.0.5", @@ -49,13 +51,18 @@ "@types/node": "^20.12.8", "@types/react": "^18.2.66", "@types/react-dom": "^18.2.22", - "@typescript-eslint/eslint-plugin": "^7.2.0", - "@typescript-eslint/parser": "^7.2.0", + "@typescript-eslint/eslint-plugin": "^7.18.0", + "@typescript-eslint/parser": "^7.18.0", "@vitejs/plugin-react-swc": "^3.5.0", "autoprefixer": "^10.4.19", + "daisyui": "^4.12.10", "eslint": "^8.57.0", - "eslint-plugin-react-hooks": "^4.6.0", - "eslint-plugin-react-refresh": "^0.4.6", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-header": "^3.1.1", + "eslint-plugin-prettier": "^5.2.1", + "eslint-plugin-react-hooks": "^4.6.2", + "eslint-plugin-react-refresh": "^0.4.11", + "generate-license-file": "^3.5.1", "postcss": "^8.4.38", "tailwindcss": "^3.4.3", "typescript": "^5.2.2", diff --git a/app/frontend/postcss.config.js b/app/frontend/postcss.config.js index 2e7af2b7..3d5ec0e2 100644 --- a/app/frontend/postcss.config.js +++ b/app/frontend/postcss.config.js @@ -1,6 +1,8 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC export default { plugins: { tailwindcss: {}, autoprefixer: {}, }, -} +}; diff --git a/app/frontend/src/App.tsx b/app/frontend/src/App.tsx index 4a8c3c22..11c2dc32 100644 --- a/app/frontend/src/App.tsx +++ b/app/frontend/src/App.tsx @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC import "./App.css"; import { ThemeProvider } from "./providers/ThemeProvider"; import AppRouter from "./routes/index.tsx"; diff --git a/app/frontend/src/api/modelsDeployedApis.ts b/app/frontend/src/api/modelsDeployedApis.ts index d6087f04..81f38a88 100644 --- a/app/frontend/src/api/modelsDeployedApis.ts +++ b/app/frontend/src/api/modelsDeployedApis.ts @@ -1,4 +1,5 @@ -// Summary: API functions for fetching and deleting models deployed on the models deployed component. +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC import axios from "axios"; import { customToast } from "../components/CustomToaster"; import { NavigateFunction } from "react-router-dom"; @@ -11,9 +12,11 @@ interface PortBinding { HostIp: string; HostPort: string; } + interface Network { DNSNames: string[]; } + interface ContainerData { name: string; status: string; @@ -24,6 +27,7 @@ interface ContainerData { port_bindings: { [key: string]: PortBinding[] }; networks: { [key: string]: Network }; } + interface Model { id: string; image: string; @@ -33,10 +37,22 @@ interface Model { name: string; } +interface StopResponse { + status: string; + stop_response: { + status: string; + output?: string; + }; + reset_response?: { + status: string; + output?: string; + }; +} + export const fetchModels = async (): Promise => { try { const response = await axios.get<{ [key: string]: ContainerData }>( - statusURl + statusURl, ); const data = response.data; console.log("Data fetched for tables:", data); @@ -46,7 +62,7 @@ export const fetchModels = async (): Promise => { const portMapping = Object.keys(container.port_bindings) .map( (port) => - `${container.port_bindings[port][0].HostIp}:${container.port_bindings[port][0].HostPort}->${port}` + `${container.port_bindings[port][0].HostIp}:${container.port_bindings[port][0].HostPort}->${port}`, ) .join(", "); @@ -68,40 +84,67 @@ export const fetchModels = async (): Promise => { } }; -export const deleteModel = async (modelId: string): Promise => { +export const deleteModel = async (modelId: string): Promise => { const truncatedModelId = modelId.substring(0, 4); try { const payload = JSON.stringify({ container_id: modelId }); console.log("Payload:", payload); - const response = await axios.post(stopModelsURL, payload, { + const response = await axios.post(stopModelsURL, payload, { headers: { "Content-Type": "application/json", }, }); - console.log("Response:", response); + console.log("Response: on ts from backend", response); - if (response.data.status !== "success") { + if ( + response.data.status !== "success" || + !response.data.stop_response || + response.data.stop_response.status !== "success" + ) { customToast.error("Failed to stop the container"); throw new Error("Failed to stop the container"); + } else { + customToast.success( + `Model ID: ${truncatedModelId} has been deleted successfully.`, + ); + + if ( + response.data.reset_response && + response.data.reset_response.status === "success" + ) { + customToast.success( + `Model ID: ${truncatedModelId} has been reset successfully.`, + ); + } else { + customToast.error(`Model ID: ${truncatedModelId} reset failed.`); + } + + console.log( + `Reset Output: ${ + response.data.reset_response?.output || "No reset output available" + }`, + ); } + + return response.data; // Ensure this is returning the correct response } catch (error) { if (axios.isAxiosError(error)) { console.error("Error stopping the container:", error.response?.data); customToast.error( `Failed to delete Model ID: ${truncatedModelId} - ${ error.response?.data.message || error.message - }` + }`, ); } else if (error instanceof Error) { console.error("Error stopping the container:", error.message); customToast.error( - `Failed to delete Model ID: ${truncatedModelId} - ${error.message}` + `Failed to delete Model ID: ${truncatedModelId} - ${error.message}`, ); } else { console.error("Unknown error stopping the container", error); customToast.error( - `Failed to delete Model ID: ${truncatedModelId} - Unknown error` + `Failed to delete Model ID: ${truncatedModelId} - Unknown error`, ); } throw error; @@ -116,7 +159,7 @@ export const handleRedeploy = (modelName: string): void => { export const handleChatUI = ( modelID: string, modelName: string, - navigate: NavigateFunction + navigate: NavigateFunction, ): void => { console.log(`ChatUI button clicked for model: ${modelID}`); console.log(`Opening Chat UI for model: ${modelName}`); diff --git a/app/frontend/src/assets/tt_logo.svg b/app/frontend/src/assets/tt_logo.svg index 093f4be2..966dfeec 100644 --- a/app/frontend/src/assets/tt_logo.svg +++ b/app/frontend/src/assets/tt_logo.svg @@ -1,9 +1,34 @@ - - - - - - - - - + +image/svg+xml \ No newline at end of file diff --git a/app/frontend/src/components/ChatComponent.tsx b/app/frontend/src/components/ChatComponent.tsx index 0ae779c5..0a47293a 100644 --- a/app/frontend/src/components/ChatComponent.tsx +++ b/app/frontend/src/components/ChatComponent.tsx @@ -1,17 +1,17 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC import React, { useEffect, useState, useRef } from "react"; import { Card } from "./ui/card"; import { Button } from "./ui/button"; import { ScrollArea } from "./ui/scroll-area"; import { useLocation } from "react-router-dom"; import { Spinner } from "./ui/spinner"; -import { useTheme } from "../providers/ThemeProvider"; import { + MessageCircle, Smile, - Sun, + CloudSun, + Lightbulb, User, - Angry, - DollarSign, - CircleArrowUp, ChevronDown, } from "lucide-react"; import { Textarea } from "./ui/textarea"; @@ -31,6 +31,7 @@ import { DropdownMenuItem, DropdownMenuTrigger, } from "./ui/dropdown-menu"; +import { fetchModels } from "../api/modelsDeployedApis"; interface InferenceRequest { deploy_id: string; @@ -42,11 +43,12 @@ interface ChatMessage { text: string; } -const modelAPIURL = "/models-api/"; -const inferenceUrl = `${modelAPIURL}/inference/`; +interface Model { + id: string; + name: string; +} const ChatComponent: React.FC = () => { - const { theme } = useTheme(); const location = useLocation(); const [textInput, setTextInput] = useState(""); const [chatHistory, setChatHistory] = useState([]); @@ -56,15 +58,25 @@ const ChatComponent: React.FC = () => { const scrollAreaRef = useRef(null); const bottomRef = useRef(null); const [isScrollButtonVisible, setIsScrollButtonVisible] = useState(false); + const [modelsDeployed, setModelsDeployed] = useState([]); useEffect(() => { if (location.state) { setModelID(location.state.containerID); setModelName(location.state.modelName); } - }, [location.state]); - console.log("Model ID:", modelID, "Model Name:", modelName); + const loadModels = async () => { + try { + const models = await fetchModels(); + setModelsDeployed(models); + } catch (error) { + console.error("Error fetching models:", error); + } + }; + + loadModels(); + }, [location.state]); const scrollToBottom = () => { if (bottomRef.current) { @@ -88,7 +100,7 @@ const ChatComponent: React.FC = () => { const runInference = async (request: InferenceRequest) => { try { setIsStreaming(true); - const response = await fetch(inferenceUrl, { + const response = await fetch(`/models-api/inference/`, { method: "POST", headers: { "Content-Type": "application/json", @@ -106,31 +118,34 @@ const ChatComponent: React.FC = () => { let result = ""; if (reader) { - while (true) { - const { done, value } = await reader.read(); - if (done) break; + let done = false; + while (!done) { + const { done: streamDone, value } = await reader.read(); + done = streamDone; - const decoder = new TextDecoder(); - const chunk = decoder.decode(value); - result += chunk; - const cleanedResult = result.replace(/<\|endoftext\|>/g, ""); - setChatHistory((prevHistory) => { - const lastMessage = prevHistory[prevHistory.length - 1]; - if (lastMessage && lastMessage.sender === "assistant") { - const updatedHistory = [...prevHistory]; - updatedHistory[updatedHistory.length - 1] = { - ...lastMessage, - text: cleanedResult, - }; - return updatedHistory; - } else { - return [ - ...prevHistory, - { sender: "assistant", text: cleanedResult }, - ]; - } - }); - scrollToBottom(); + if (value) { + const decoder = new TextDecoder(); + const chunk = decoder.decode(value); + result += chunk; + const cleanedResult = result.replace(/<\|endoftext\|>/g, ""); + setChatHistory((prevHistory) => { + const lastMessage = prevHistory[prevHistory.length - 1]; + if (lastMessage && lastMessage.sender === "assistant") { + const updatedHistory = [...prevHistory]; + updatedHistory[updatedHistory.length - 1] = { + ...lastMessage, + text: cleanedResult, + }; + return updatedHistory; + } else { + return [ + ...prevHistory, + { sender: "assistant", text: cleanedResult }, + ]; + } + }); + scrollToBottom(); + } } } @@ -149,11 +164,11 @@ const ChatComponent: React.FC = () => { text: textInput, }; - if (textInput === "When will Tenstorrent out sell Nvidia?") { + if (textInput === "Tell me a fun fact.") { setChatHistory((prevHistory) => [ ...prevHistory, { sender: "user", text: textInput }, - { sender: "assistant", text: "2024, that was a silly question." }, + { sender: "assistant", text: "Did you know? Honey never spoils." }, ]); setTextInput(""); scrollToBottom(); @@ -173,37 +188,53 @@ const ChatComponent: React.FC = () => { return (
- - - - - Models Deployed - - - - - - - - Toggle menu - - - Model 1 - Model 2 - Model 3 - - - - - - {modelName} - - - -
+
+ + + + + Models Deployed + + + + / + + + + + + Toggle menu + + + {modelsDeployed.map((model) => ( + { + setModelID(model.id); + setModelName(model.name); + }} + > + {model.name} + + ))} + + + + + / + + + + {modelName} + + + + +
+
{chatHistory.length === 0 && (
{ alt="Tenstorrent Logo" className="w-10 h-10 sm:w-14 sm:h-14 transform transition duration-300 hover:scale-110" /> -

+

Start a conversation with LLM Studio Chat...

@@ -220,7 +251,7 @@ const ChatComponent: React.FC = () => { className="border border-gray-300 p-4 flex flex-col items-center cursor-pointer rounded-lg hover:bg-zinc-200 dark:hover:bg-zinc-800 transition duration-300" onClick={() => setTextInput("Hello, how are you today?")} > - + Hello, how are you today? @@ -229,7 +260,7 @@ const ChatComponent: React.FC = () => { className="border border-gray-300 rounded-lg p-4 flex flex-col items-center cursor-pointer hover:bg-zinc-200 dark:hover:bg-zinc-800 transition duration-300" onClick={() => setTextInput("Can you tell me a joke?")} > - + Can you tell me a joke? @@ -238,20 +269,18 @@ const ChatComponent: React.FC = () => { className="border border-gray-300 rounded-lg p-4 flex flex-col items-center cursor-pointer hover:bg-zinc-200 dark:hover:bg-zinc-800 transition duration-300" onClick={() => setTextInput("What's the weather like?")} > - + What's the weather like? - setTextInput("When will Tenstorrent out sell Nvidia?") - } + onClick={() => setTextInput("Tell me a fun fact.")} > - + - When will Tenstorrent out sell Nvidia? + Tell me a fun fact.
@@ -268,33 +297,31 @@ const ChatComponent: React.FC = () => { {chatHistory.map((message, index) => (
+
+
+ {message.sender === "user" ? ( + + ) : ( + Tenstorrent Logo + )} +
+
- {message.sender === "user" ? ( - - ) : ( - Tenstorrent Logo - )} -
{message.text}
+ {message.text}
))} @@ -316,23 +343,30 @@ const ChatComponent: React.FC = () => { onChange={(e) => setTextInput(e.target.value)} onKeyDown={handleKeyPress} placeholder="Enter text for inference" - className="px-4 py-2 border rounded-lg shadow-md w-full pr-12" + className="px-4 py-2 border rounded-lg shadow-md w-full pr-12 font-rmMono" disabled={isStreaming} rows={4} /> - + +
diff --git a/app/frontend/src/components/CodeBlocks.tsx b/app/frontend/src/components/CodeBlocks.tsx index 2ec9d801..aeba2fd5 100644 --- a/app/frontend/src/components/CodeBlocks.tsx +++ b/app/frontend/src/components/CodeBlocks.tsx @@ -1,5 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC import React from "react"; -import { CodeBlock, CopyBlock, dracula } from "react-code-blocks"; +import { CodeBlock, dracula } from "react-code-blocks"; interface CodeBlocksProps { code: string; diff --git a/app/frontend/src/components/CopyableText.tsx b/app/frontend/src/components/CopyableText.tsx index fd137003..cff35eb7 100644 --- a/app/frontend/src/components/CopyableText.tsx +++ b/app/frontend/src/components/CopyableText.tsx @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC import React, { useState } from "react"; import { Tooltip, @@ -6,7 +8,7 @@ import { TooltipTrigger, } from "./ui/tooltip"; import { ClipboardCopy } from "lucide-react"; -import CustomToaster, { customToast } from "./CustomToaster"; +import { customToast } from "./CustomToaster"; const CopyableText = ({ text }: { text: string }) => { const [isCopied, setIsCopied] = useState(false); diff --git a/app/frontend/src/components/CustomToaster.tsx b/app/frontend/src/components/CustomToaster.tsx index daec9df3..7d38efe7 100644 --- a/app/frontend/src/components/CustomToaster.tsx +++ b/app/frontend/src/components/CustomToaster.tsx @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC import { Toaster, toast } from "react-hot-toast"; import { useTheme } from "../providers/ThemeProvider"; @@ -19,8 +21,8 @@ export const customToast = { }, }), promise: ( - promise: Promise, - messages: { loading: string; success: string; error: string } + promise: Promise, + messages: { loading: string; success: string; error: string }, ) => toast.promise(promise, { loading: messages.loading, diff --git a/app/frontend/src/components/DarkModeToggle.tsx b/app/frontend/src/components/DarkModeToggle.tsx index ad6b1fd2..079ebdcc 100644 --- a/app/frontend/src/components/DarkModeToggle.tsx +++ b/app/frontend/src/components/DarkModeToggle.tsx @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC import { Moon, Sun } from "lucide-react"; import { Button } from "./ui/button"; import { useTheme } from "../providers/ThemeProvider"; diff --git a/app/frontend/src/components/DeployModelStep.tsx b/app/frontend/src/components/DeployModelStep.tsx index 1e7c4175..90cd816a 100644 --- a/app/frontend/src/components/DeployModelStep.tsx +++ b/app/frontend/src/components/DeployModelStep.tsx @@ -1,5 +1,7 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC "use client"; -import { Button } from "./ui/button"; +import { AnimatedDeployButton } from "./magicui/AnimatedDeployButton"; import { useStepper } from "./ui/stepper"; import { Weight } from "./SelectionSteps"; import { StepperFormActions } from "./StepperFormActions"; @@ -17,14 +19,20 @@ export function DeployModelStep({ const onDeploy = async () => { const deploySuccess = await handleDeploy(); if (deploySuccess) { - nextStep(); + setTimeout(() => { + nextStep(); + }, 1200); // Timing matches the animation for a smooth transition } }; return ( <>
- + Deploy Model} + changeText={Model Deployed!} + onDeploy={onDeploy} + />
{}} /> diff --git a/app/frontend/src/components/FilesUploader.tsx b/app/frontend/src/components/FilesUploader.tsx index b84023b4..82c2735d 100644 --- a/app/frontend/src/components/FilesUploader.tsx +++ b/app/frontend/src/components/FilesUploader.tsx @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC import React, { useState } from "react"; import { Input } from "./ui/input"; import { Progress } from "./ui/progress"; diff --git a/app/frontend/src/components/FirstStepForm.tsx b/app/frontend/src/components/FirstStepForm.tsx index 2d1a5908..45e8ee9f 100644 --- a/app/frontend/src/components/FirstStepForm.tsx +++ b/app/frontend/src/components/FirstStepForm.tsx @@ -1,9 +1,12 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC "use client"; import { zodResolver } from "@hookform/resolvers/zod"; import { useForm } from "react-hook-form"; import * as z from "zod"; import axios from "axios"; import { useEffect, useState } from "react"; + import { Select, SelectContent, diff --git a/app/frontend/src/components/HealthBadge.tsx b/app/frontend/src/components/HealthBadge.tsx index 011bef43..cec6c020 100644 --- a/app/frontend/src/components/HealthBadge.tsx +++ b/app/frontend/src/components/HealthBadge.tsx @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC import React from "react"; import { Badge } from "./ui/badge"; import { diff --git a/app/frontend/src/components/HelpIcon.tsx b/app/frontend/src/components/HelpIcon.tsx index 43f33bbb..d1822ca5 100644 --- a/app/frontend/src/components/HelpIcon.tsx +++ b/app/frontend/src/components/HelpIcon.tsx @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC import React from "react"; import { HelpCircle } from "lucide-react"; import { Button } from "./ui/button"; diff --git a/app/frontend/src/components/ModelsDeployedSkeleton.tsx b/app/frontend/src/components/ModelsDeployedSkeleton.tsx new file mode 100644 index 00000000..99deeee0 --- /dev/null +++ b/app/frontend/src/components/ModelsDeployedSkeleton.tsx @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC +import { Skeleton } from "./ui/skeleton"; + +export function ModelsDeployedSkeleton() { + return ( +
+ {/* Table Header */} +
+ {[...Array(5)].map((_, i) => ( +
+ {/* Container ID */} + {/* Image */} + {/* Status */} + {/* Health */} + {/* Ports */} + {/* Names */} + {/* Manage */} +
+ ))} +
+
+ ); +} + +export default ModelsDeployedSkeleton; diff --git a/app/frontend/src/components/ModelsDeployedTable.tsx b/app/frontend/src/components/ModelsDeployedTable.tsx index 8fc931bf..8c9d9a00 100644 --- a/app/frontend/src/components/ModelsDeployedTable.tsx +++ b/app/frontend/src/components/ModelsDeployedTable.tsx @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC import { useState, useEffect } from "react"; import { Card } from "./ui/card"; import { @@ -23,8 +25,10 @@ import { handleRedeploy, handleChatUI, } from "../api/modelsDeployedApis"; - import { ScrollArea, ScrollBar } from "./ui/scroll-area"; +import { NoModelsDialog } from "./NoModelsDeployed"; +import { ModelsDeployedSkeleton } from "./ModelsDeployedSkeleton"; +import { useRefresh } from "../providers/RefreshContext"; interface Model { id: string; @@ -39,26 +43,35 @@ const initialModelsDeployed: Model[] = []; export function ModelsDeployedTable() { const navigate = useNavigate(); + const { refreshTrigger } = useRefresh(); // Access the refreshTrigger state const [modelsDeployed, setModelsDeployed] = useState( - initialModelsDeployed + initialModelsDeployed, ); const [fadingModels, setFadingModels] = useState([]); const [loadingModels, setLoadingModels] = useState([]); + const [loading, setLoading] = useState(true); const { theme } = useTheme(); - useEffect(() => { - const loadModels = async () => { - try { - const models = await fetchModels(); - setModelsDeployed(models); - } catch (error) { - console.error("Error fetching models:", error); - customToast.error("Failed to fetch models."); - } - }; + const loadModels = async () => { + try { + const models = await fetchModels(); + setModelsDeployed(models); + } catch (error) { + console.error("Error fetching models:", error); + customToast.error("Failed to fetch models."); + } finally { + setLoading(false); + } + }; + useEffect(() => { loadModels(); - }, []); + + // Reload models whenever refreshTrigger changes + if (refreshTrigger > 0) { + loadModels(); + } + }, [refreshTrigger]); const handleDelete = async (modelId: string) => { console.log(`Delete button clicked for model ID: ${modelId}`); @@ -67,7 +80,13 @@ export function ModelsDeployedTable() { const deleteModelAsync = async () => { setLoadingModels((prev) => [...prev, modelId]); try { - await deleteModel(modelId); + const response = await deleteModel(modelId); + + // Accessing the reset_response output correctly + const resetOutput = + response.reset_response?.output || "No reset output available"; + console.log(`Reset Output in tsx: ${resetOutput}`); + setFadingModels((prev) => [...prev, modelId]); } catch (error) { console.error("Error stopping the container:", error); @@ -86,33 +105,26 @@ export function ModelsDeployedTable() { useEffect(() => { const timer = setTimeout(() => { setModelsDeployed((prevModels) => - prevModels.filter((model) => !fadingModels.includes(model.id)) + prevModels.filter((model) => !fadingModels.includes(model.id)), ); }, 3000); return () => clearTimeout(timer); }, [fadingModels]); + if (loading) { + return ; + } + + if (modelsDeployed.length === 0) { + return ; + } + return ( - + - - +
+ Models Deployed @@ -189,11 +201,7 @@ export function ModelsDeployedTable() { ) : ( @@ -202,11 +210,7 @@ export function ModelsDeployedTable() { onClick={() => handleChatUI(model.id, model.name, navigate) } - className={`${ - theme === "dark" - ? "bg-blue-500 hover:bg-blue-400 text-white" - : "bg-blue-500 hover:bg-blue-400 text-white" - } rounded-lg`} + className="bg-blue-500 dark:bg-blue-700 hover:bg-blue-600 dark:hover:bg-blue-600 text-white rounded-lg" > ChatUI @@ -218,7 +222,10 @@ export function ModelsDeployedTable() { ))}
- +
); diff --git a/app/frontend/src/components/NavBar.tsx b/app/frontend/src/components/NavBar.tsx index 6fa3fada..e781a14e 100644 --- a/app/frontend/src/components/NavBar.tsx +++ b/app/frontend/src/components/NavBar.tsx @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC import { useMemo, useRef } from "react"; import { NavLink, useLocation } from "react-router-dom"; import logo from "../assets/tt_logo.svg"; @@ -6,30 +8,47 @@ import { NavigationMenuItem, NavigationMenuList, } from "./ui/navigation-menu"; -import { Home, BrainCog, BotMessageSquare } from "lucide-react"; // Import BotMessageSquare +import { Home, BrainCog, BotMessageSquare } from "lucide-react"; import ModeToggle from "./DarkModeToggle"; import HelpIcon from "./HelpIcon"; import { Separator } from "./ui/separator"; -import useCommonClasses from "../theme/commonThemeClasses"; import Sidebar from "./SideBar"; +import { useTheme } from "../providers/ThemeProvider"; +import ResetIcon from "./ResetIcon"; +import CustomToaster from "./CustomToaster"; +import { + Tooltip, + TooltipContent, + TooltipProvider, + TooltipTrigger, +} from "./ui/tooltip"; +import { useRefresh } from "../providers/RefreshContext"; export default function NavBar() { const location = useLocation(); - const { textColor, hoverTextColor, activeBorderColor, hoverBackgroundColor } = - useCommonClasses(); + const { theme } = useTheme(); + const { triggerRefresh } = useRefresh(); + const sidebarRef = useRef<{ toggleSidebar: () => void }>(null); + + const iconColor = theme === "dark" ? "text-zinc-200" : "text-black"; + const textColor = theme === "dark" ? "text-zinc-200" : "text-black"; + const hoverTextColor = + theme === "dark" ? "hover:text-zinc-300" : "hover:text-gray-700"; + const activeBorderColor = + theme === "dark" ? "border-zinc-400" : "border-black"; + const hoverBackgroundColor = + theme === "dark" ? "hover:bg-zinc-700" : "hover:bg-gray-300"; const navLinkClass = useMemo( () => `flex items-center justify-center px-2 py-2 rounded-md text-sm font-medium ${textColor} transition-all duration-300 ease-in-out`, - [textColor] + [textColor], ); const getNavLinkClass = (isActive: boolean) => `${navLinkClass} ${ isActive ? `border-2 ${activeBorderColor}` : "border-transparent" - } ${hoverTextColor} ${hoverBackgroundColor}`; - - const sidebarRef = useRef<{ toggleSidebar: () => void }>(null); + } ${hoverTextColor} ${hoverBackgroundColor} hover:border-4 hover:scale-105 hover:shadow-lg dark:hover:shadow-TT-dark-shadow dark:hover:border-TT-light-border transition-all duration-300 ease-in-out`; const handleToggleSidebar = () => { if (sidebarRef.current) { @@ -37,108 +56,154 @@ export default function NavBar() { } }; + const handleReset = () => { + triggerRefresh(); + }; + const isChatUI = location.pathname === "/chat-ui"; return ( -
+
- +
- Tenstorrent Logo - {!isChatUI && ( -

- LLM Studio -

- )} -
- - - - getNavLinkClass(isActive)} - > - - {!isChatUI && Home} - - + Tenstorrent Logo {!isChatUI && ( - +

+ LLM Studio +

)} - + + - getNavLinkClass(isActive)} + - - {!isChatUI && Models Deployed} - - - {isChatUI && ( + getNavLinkClass(isActive)} + > + + {!isChatUI && Home} + + + {!isChatUI && ( + + )} getNavLinkClass(isActive)} > - + + {!isChatUI && Models Deployed} - )} -
-
- {!isChatUI && ( -
+ {isChatUI && ( + + getNavLinkClass(isActive)} + > + + + + )} + + + {!isChatUI && ( +
+ + +
+ +
+
+ +

Toggle Dark/Light Mode

+
+
+ + + +
+ +
+
+ +

Reset Board

+
+
+ + + +
+ +
+
+ +

Get Help

+
+
+
+ )} +
+ {isChatUI && ( +
- +
)} +
- {isChatUI && ( -
- - -
- )} - -
+
); } diff --git a/app/frontend/src/components/NoModelsDeployed.tsx b/app/frontend/src/components/NoModelsDeployed.tsx new file mode 100644 index 00000000..3974f72b --- /dev/null +++ b/app/frontend/src/components/NoModelsDeployed.tsx @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC +import { + Dialog, + DialogContent, + DialogHeader, + DialogTitle, + DialogFooter, + DialogDescription, +} from "./ui/dialog"; +import { Button } from "./ui/button"; +import { useNavigate } from "react-router-dom"; + +interface NoModelsDialogProps { + messageKey?: "reset" | "noModels"; +} + +export function NoModelsDialog({ + messageKey = "noModels", +}: NoModelsDialogProps) { + const navigate = useNavigate(); + + const messages = { + reset: "The board was reset, so all models were stopped.", + noModels: + "There are currently no models deployed. You can head to the homepage to deploy models.", + }; + + return ( + + + + No Models Deployed + {messages[messageKey]} + + + + + + + ); +} diff --git a/app/frontend/src/components/ResetIcon.tsx b/app/frontend/src/components/ResetIcon.tsx new file mode 100644 index 00000000..0f2eaf97 --- /dev/null +++ b/app/frontend/src/components/ResetIcon.tsx @@ -0,0 +1,305 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + +import React, { useState } from "react"; +import axios from "axios"; +import { Cpu, CheckCircle, AlertTriangle } from "lucide-react"; +import { Spinner } from "./ui/spinner"; +import { customToast } from "./CustomToaster"; +import { useTheme } from "../providers/ThemeProvider"; +import { Button } from "./ui/button"; +import { + Dialog, + DialogContent, + DialogFooter, + DialogHeader, + DialogTitle, + DialogTrigger, + DialogDescription, +} from "./ui/dialog"; +import { + Accordion, + AccordionContent, + AccordionItem, + AccordionTrigger, +} from "./ui/accordion"; +import { ScrollArea } from "./ui/scroll-area"; +import { fetchModels, deleteModel } from "../api/modelsDeployedApis"; + +interface ResetIconProps { + onReset?: () => void; +} + +const ResetIcon: React.FC = ({ onReset }) => { + const { theme } = useTheme(); + const [isLoading, setIsLoading] = useState(false); + const [isCompleted, setIsCompleted] = useState(false); + const [isDialogOpen, setIsDialogOpen] = useState(false); + const [errorMessage, setErrorMessage] = useState(null); + const [resetHistory, setResetHistory] = useState([]); + const [fullOutput, setFullOutput] = useState(null); + + const iconColor = theme === "dark" ? "text-zinc-200" : "text-black"; + const hoverIconColor = + theme === "dark" ? "hover:text-zinc-300" : "hover:text-gray-700"; + const buttonBackgroundColor = theme === "dark" ? "bg-zinc-900" : "bg-white"; + const hoverButtonBackgroundColor = + theme === "dark" ? "hover:bg-zinc-700" : "hover:bg-gray-200"; + + // Function to delete all deployed models + const deleteAllModels = async (): Promise => { + try { + const models = await fetchModels(); // Fetch all deployed models + console.log("Models to delete:", models); + for (const model of models) { + await customToast.promise(deleteModel(model.id), { + loading: `Deleting Model ID: ${model.id.substring(0, 4)}...`, + success: `Model ID: ${model.id.substring( + 0, + 4, + )} deleted successfully.`, + error: `Failed to delete Model ID: ${model.id.substring(0, 4)}.`, + }); + } + } catch (error) { + console.error("Error deleting models:", error); + throw new Error("Failed to delete all models."); + } + }; + + const resetBoardAsync = async (): Promise => { + const response = await axios.post("/docker-api/reset_board/", null, { + responseType: "blob", + }); + + const reader = response.data.stream().getReader(); + const decoder = new TextDecoder(); + let output = ""; + let success = true; + const statusCode = response.status; + + // eslint-disable-next-line no-constant-condition + while (true) { + const { done, value } = await reader.read(); + if (done) break; + + const chunk = decoder.decode(value, { stream: true }); + output += chunk; + + // Check for failure in each chunk + if ( + chunk.includes("Command failed") || + chunk.includes("No Tenstorrent devices detected") || + chunk.includes("Exiting") || + chunk.includes("Error") + ) { + success = false; + } + } + + const finalChunk = decoder.decode(); + if (finalChunk) { + output += finalChunk; + if ( + finalChunk.includes("Command failed") || + finalChunk.includes("No Tenstorrent devices detected") || + finalChunk.includes("Exiting") || + finalChunk.includes("Error") + ) { + success = false; + } + } + + const styledOutput = success + ? ` + Board Reset Successfully + ----------------------- +
${output}
+ ` + : ` + Board Reset Failed + ----------------------- +
${output}
+ `; + + setFullOutput(styledOutput); + + if (!success) { + if (statusCode === 501) { + throw new Error( + "No Tenstorrent devices detected or functionality not implemented.", + ); + } else { + throw new Error("Command failed or no devices detected"); + } + } + + setIsCompleted(true); + setResetHistory((prevHistory) => [...prevHistory, new Date()]); + setTimeout(() => setIsCompleted(false), 5000); + }; + + const resetBoard = async (): Promise => { + setIsLoading(true); + setIsCompleted(false); + setErrorMessage(null); + setIsDialogOpen(false); + + try { + await deleteAllModels(); + + await customToast.promise(resetBoardAsync(), { + loading: "Resetting board...", + success: "Board reset successfully!", + error: "Failed to reset board.", + }); + + if (onReset) { + console.log("Calling onReset prop function"); + onReset(); + } + } catch (error) { + console.error("Error resetting board:", error); + + if (error instanceof Error) { + const errorOutput = ` + Error Resetting Board + ----------------------- +
${error.message}
+ `; + setFullOutput(errorOutput); + setErrorMessage("Command failed or no devices detected"); + } else { + setErrorMessage("An unknown error occurred"); + } + + setIsDialogOpen(true); + } finally { + setIsLoading(false); + } + }; + + const handleDialogOpenChange = (isOpen: boolean) => { + setIsDialogOpen(isOpen); + if (isOpen) { + setErrorMessage(null); + } + }; + + return ( + + + + + + +
+ + + Reset Card + +
+ + Are you sure you want to reset the card? + +
+
+
+
+ Warning! This action will stop all deployed models and might + interrupt ongoing processes. +
+ {resetHistory.length > 0 && ( +
+ Note: This card was reset in the last 5 minutes. Frequent resets + may cause issues. Please wait before resetting again. +
+ )} +
+
+ {errorMessage && ( +
+
+ + Error: {errorMessage} +
+
+ )} + + + + Reset History + + +
    + {resetHistory.length > 0 ? ( + resetHistory.map((resetTime, index) => ( +
  • {resetTime.toLocaleString()}
  • + )) + ) : ( +
  • No resets yet.
  • + )} +
+
+
+ {fullOutput && ( + + + Command Output + + + +
+ + + + )} + + + + + + +
+ ); +}; + +export default ResetIcon; diff --git a/app/frontend/src/components/SecondStepForm.tsx b/app/frontend/src/components/SecondStepForm.tsx index ac7ba5cd..241c9745 100644 --- a/app/frontend/src/components/SecondStepForm.tsx +++ b/app/frontend/src/components/SecondStepForm.tsx @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC "use client"; import { zodResolver } from "@hookform/resolvers/zod"; import { useForm } from "react-hook-form"; diff --git a/app/frontend/src/components/SelectionSteps.tsx b/app/frontend/src/components/SelectionSteps.tsx index d91e5ea7..d5a02cab 100644 --- a/app/frontend/src/components/SelectionSteps.tsx +++ b/app/frontend/src/components/SelectionSteps.tsx @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC "use client"; import axios from "axios"; @@ -91,8 +93,8 @@ export default function StepperDemo() { setSteps((prevSteps) => prevSteps.filter( (step) => - step.label !== "Custom Step" && step.label !== "Fine-Tune Step" - ) + step.label !== "Custom Step" && step.label !== "Fine-Tune Step", + ), ); }; @@ -133,7 +135,7 @@ export default function StepperDemo() { return (
- + { const [isOpen, setIsOpen] = useState(false); const { theme } = useTheme(); + const location = useLocation(); const toggleSidebar = () => { setIsOpen(!isOpen); }; + const getHelpContent = () => { + const baseStyles = `shadow-lg rounded-lg p-6 my-4 ${ + theme === "dark" ? "bg-TT-slate text-white" : "bg-white text-tt-black" + }`; + + return ( + { + "/": ( + + + + Home + + + +

+ The "Home" page serves as your central hub for exploring the + various features of the LLM Studio app. Use the dropdown to + browse and select from a list of available models, and click the + "Deploy" button to begin the process. +

+
    +
      +
    • + Model Selection: Start by selecting a model + from the dropdown menu. This is the first step in + configuring your deployment. +
    • +
    • + Weight Selection: After choosing a model, + select the appropriate weights for your model to ensure + optimal performance. +
    • +
    • + Deploy Model: Once you’ve configured the + model and selected the weights, click the "Deploy" button to + initiate the deployment process. +
    • +
    • + Navigation: Use the "Next" and "Previous" + buttons at the bottom to move between these steps as needed. +
    • +
    +
+
+
+ ), + "/chat-ui": ( + + + + ChatUI + + + +

+ The "ChatUI" page allows you to interact with your deployed + models in a conversational format. You can ask questions, + provide input, and receive responses from the models you have + deployed. +

+
    +
  • + Entering Queries: Type your questions in the + input box at the bottom. +
  • +
  • + Response Display: Responses from the model + will appear on the left side. +
  • +
+
+
+ ), + "/models-deployed": ( + + + + Models Deployed + + + +

+ The "Models Deployed" page gives you an overview of all models + currently running in your environment. From here, you can manage + your models, check their health status, and access specific + tools like the ChatUI. +

+
    +
  • + Monitoring Models: Each row displays a + model's status and health indicators. +
  • +
  • + Actions: Use the "Delete" button to stop and + remove a model. +
  • +
+
+
+ ), + }[location.pathname] || null + ); + }; + useImperativeHandle(ref, () => ({ toggleSidebar, })); @@ -23,8 +131,8 @@ const Sidebar = forwardRef((_, ref) => {
@@ -43,31 +151,7 @@ const Sidebar = forwardRef((_, ref) => {
- +
-
); diff --git a/app/frontend/src/components/StepperFormActions.tsx b/app/frontend/src/components/StepperFormActions.tsx index a0303f22..494d35b3 100644 --- a/app/frontend/src/components/StepperFormActions.tsx +++ b/app/frontend/src/components/StepperFormActions.tsx @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC "use client"; import { Button } from "./ui/button"; import { useStepper } from "./ui/stepper"; @@ -7,7 +9,7 @@ export function StepperFormActions({ removeDynamicSteps, isSubmitting, }: { - form: any; + form: unknown; removeDynamicSteps: () => void; isSubmitting?: boolean; }) { diff --git a/app/frontend/src/components/UploadDialog.tsx b/app/frontend/src/components/UploadDialog.tsx index db8f316c..cf189a74 100644 --- a/app/frontend/src/components/UploadDialog.tsx +++ b/app/frontend/src/components/UploadDialog.tsx @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC import { Button } from "./ui/button"; // import { Card } from "./ui/card"; import { diff --git a/app/frontend/src/components/WeightForm.tsx b/app/frontend/src/components/WeightForm.tsx index 093841dd..d429c4e8 100644 --- a/app/frontend/src/components/WeightForm.tsx +++ b/app/frontend/src/components/WeightForm.tsx @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC "use client"; import { zodResolver } from "@hookform/resolvers/zod"; import { useForm } from "react-hook-form"; @@ -43,7 +45,7 @@ export function WeightForm({ const fetchWeights = async () => { try { const response = await axios.get( - getWeightsUrl(selectedModel) + getWeightsUrl(selectedModel), ); console.log("fetched weights:", response.data); setWeights(response.data); @@ -60,7 +62,7 @@ export function WeightForm({ resolver: zodResolver( z.object({ weight: z.string().nonempty("Please select a weight file."), - }) + }), ), defaultValues: { weight: "", @@ -75,7 +77,7 @@ export function WeightForm({ setIsSubmitting(true); try { const selectedWeight = weights.find( - (weight) => weight.name === data.weight + (weight) => weight.name === data.weight, ); if (selectedWeight) { setCustomWeight(selectedWeight); diff --git a/app/frontend/src/components/magicui/AnimatedDeployButton.tsx b/app/frontend/src/components/magicui/AnimatedDeployButton.tsx new file mode 100644 index 00000000..6634a106 --- /dev/null +++ b/app/frontend/src/components/magicui/AnimatedDeployButton.tsx @@ -0,0 +1,71 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC +"use client"; + +import React, { useState } from "react"; +import { AnimatePresence, motion } from "framer-motion"; +import { Rocket } from "lucide-react"; + +interface AnimatedDeployButtonProps { + initialText: React.ReactElement | string; + changeText: React.ReactElement | string; + onDeploy: () => void; +} + +export const AnimatedDeployButton: React.FC = ({ + initialText, + changeText, + onDeploy, +}) => { + const [isDeployed, setIsDeployed] = useState(false); + const [displayText, setDisplayText] = useState( + initialText, + ); + + const handleDeploy = async () => { + setIsDeployed(true); + setDisplayText(changeText); // Change the text after clicking deploy + await onDeploy(); + }; + + return ( + + {isDeployed ? ( + setIsDeployed(false)} + initial={{ opacity: 0 }} + animate={{ opacity: 1 }} + exit={{ opacity: 0 }} + > + + Model Deployed! + + + ) : ( + + + {displayText} + + + + )} + + ); +}; diff --git a/app/frontend/src/components/ui/accordion.tsx b/app/frontend/src/components/ui/accordion.tsx new file mode 100644 index 00000000..797f551c --- /dev/null +++ b/app/frontend/src/components/ui/accordion.tsx @@ -0,0 +1,56 @@ +import * as React from "react"; +import * as AccordionPrimitive from "@radix-ui/react-accordion"; +import { ChevronDown } from "lucide-react"; + +import { cn } from "../../lib/utils"; + +const Accordion = AccordionPrimitive.Root; + +const AccordionItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +AccordionItem.displayName = "AccordionItem"; + +const AccordionTrigger = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + svg]:rotate-180", + className + )} + {...props} + > + {children} + + + +)); +AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName; + +const AccordionContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + +
{children}
+
+)); + +AccordionContent.displayName = AccordionPrimitive.Content.displayName; + +export { Accordion, AccordionItem, AccordionTrigger, AccordionContent }; diff --git a/app/frontend/src/components/ui/badge.tsx b/app/frontend/src/components/ui/badge.tsx index 21d6fc5a..8715086f 100644 --- a/app/frontend/src/components/ui/badge.tsx +++ b/app/frontend/src/components/ui/badge.tsx @@ -1,19 +1,24 @@ +/* this shadcnn badge component has been updated to be more specific to a status badge component and +should not be used for the other badges in the application +*/ + 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 border-stone-200 px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-stone-950 focus:ring-offset-2 dark:border-stone-800 dark:focus:ring-stone-300", + "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-offset-2", { variants: { variant: { default: - "border-transparent bg-green-100 text-green-900 hover:bg-green-100/80 dark:bg-green-800 dark:text-green-50 dark:hover:bg-green-800/80", + "border-TT-green-accent bg-[#4CAF50] text-white hover:bg-[#45A049]/80 dark:bg-[#388E3C] dark:text-white dark:hover:bg-[#2E7D32]/80", // Updated green shades destructive: - "border-transparent bg-red-100 text-red-900 hover:bg-red-100/80 dark:bg-red-800 dark:text-red-50 dark:hover:bg-red-800/80", - outline: "text-stone-950 dark:text-stone-50", + "border-TT-red-accent bg-TT-red-tint2 text-white hover:bg-TT-red-tint2/80 dark:bg-TT-red-shade dark:text-white dark:hover:bg-TT-red-shade/80", + outline: + "text-TT-slate-shade dark:text-TT-slate-tint1 border-TT-slate-accent dark:border-TT-slate-tint2", warning: - "border-transparent bg-yellow-100 text-yellow-900 hover:bg-yellow-100/80 dark:bg-yellow-800 dark:text-yellow-50 dark:hover:bg-yellow-800/80", // Adding the new warning variant + "border-TT-yellow-accent bg-TT-yellow-tint2 text-TT-yellow-shade hover:bg-TT-yellow-tint2/80 dark:bg-TT-yellow-accent dark:text-white dark:hover:bg-TT-yellow-accent/80", }, }, defaultVariants: { diff --git a/app/frontend/src/components/ui/scroll-area.tsx b/app/frontend/src/components/ui/scroll-area.tsx index 257ae4b4..38ba8f7e 100644 --- a/app/frontend/src/components/ui/scroll-area.tsx +++ b/app/frontend/src/components/ui/scroll-area.tsx @@ -29,16 +29,22 @@ const ScrollBar = React.forwardRef< ref={ref} orientation={orientation} className={cn( - "flex touch-none select-none transition-colors", + "flex touch-none select-none transition-colors duration-200 ease-in-out", orientation === "vertical" && "h-full w-2.5 border-l border-l-transparent p-[1px]", orientation === "horizontal" && "h-2.5 flex-col border-t border-t-transparent p-[1px]", + "hover:bg-zinc-200 dark:hover:bg-zinc-700", // Subtle zinc hover effect for light and dark mode className )} {...props} > - + )); ScrollBar.displayName = ScrollAreaPrimitive.ScrollAreaScrollbar.displayName; diff --git a/app/frontend/src/components/ui/skeleton.tsx b/app/frontend/src/components/ui/skeleton.tsx new file mode 100644 index 00000000..6e10fe23 --- /dev/null +++ b/app/frontend/src/components/ui/skeleton.tsx @@ -0,0 +1,15 @@ +import { cn } from "../../lib/utils"; + +function Skeleton({ + className, + ...props +}: React.HTMLAttributes) { + return ( +
+ ); +} + +export { Skeleton }; diff --git a/app/frontend/src/components/ui/spinner.tsx b/app/frontend/src/components/ui/spinner.tsx index 9a659384..ebea8760 100644 --- a/app/frontend/src/components/ui/spinner.tsx +++ b/app/frontend/src/components/ui/spinner.tsx @@ -2,6 +2,8 @@ import React from "react"; export const Spinner: React.FC = () => { return ( -
+ //
+ + ); }; diff --git a/app/frontend/src/fonts/DegularDisplay-Light.otf b/app/frontend/src/fonts/DegularDisplay-Light.otf new file mode 100644 index 0000000000000000000000000000000000000000..937449e1ca47f0fd08e962bf331707f62958f5eb GIT binary patch literal 77372 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�H#Isc+D)fYpV^rZJvBb9e+sZ#kEHNF1>A*= zo02<2Q*d(Y<{x*M{eBBofSsXxm3Sdzm!Pbc ziwS6&+A%kxKklx^Df7_XYBP}1|oNI4q6Qr$f~a$b-oWA^eD>AD5um}P~Vm+jU(tU2=Tm=1-BabO1U z!~K$mhuKYcZ!_)Agtv+3eUP(F0BEvTfY+Vgy+d|ebRlaQ+#p$r<9I=U`Gue0;19e4_2NKP`GuJfRe%m)$L03 zR^zTUsO#%Wd$D7HqCwu!kpVe(O*9o-s__%-sF)IzmorX>PN5&c9D%$q!-jSkO0|Cg zo7b*`24Zt;^~-o51Mq?dz>7G%y}D~a$@6E&&Vb-Ezcg&1pZ^dH(j>1^%&mlVUF=ya zueL@hEX*tV%X!7tHdLs^T+~B>ydFvOY7m)MN))5cEy>$lWQ&HJ`x$B8myO1XZCb-> z2DMKJx`jJHL!k;h9H+i^L!D8#yZ4a=QcI?vVgV+QNLL;blo_y(SrpDCmN5f{NZE3Uai!QtdY+H#bn1n~&~^GN!V@ zay*hLZr{u+IH$w+8|1KW6e<-;Hh5l4QiN^TzSOH){_jmi1tBj*b2419&g!3s0Z`Xrjnq9}BeDHx@IJ={(_80};N zVACCgZ!$_8fwnTBl$}2J-1hgt8(62s^BZ2)vf^!(|bRSob{h%3s~4Pj!W7{)4hf5jB6 zS+`yj5(p1}>XMtbt%IjIX9qK#hEb7_Uad8sclj zcr>iK!G#60#Zd!|Vr${kQ8kKeI9e+nMNx)^8Laa7sdt)Z)zkX*A0FqebC~!C%fCQY z`=i|5m106jL$YH0oS29O+4=d4wTmV)xvRd(*{D(Cg|Na8!f7}ib;q7)5n7D8gCQ$j zi7zRtXE9s$Tq?S#K{CTc*UrPHI_Olz$a=$^J*ZW&)!L&;WoT$w(oy~gaD{{y6^MYG0X-pW?_SU=io2fFSk*O&Ztyf4O3W_?t2Mafvo7<3wKqj zYfumxQH4jKQ9*bV9vO;8vZ`$1ObtR8##Qt0#8hSRhdrokvDNw`D7qs2FerL`!RR`z z^3LtzW7n=0PxADL9q$8X(!NKYo;f%Q%^I)3$#@nMqfi#39(&#bv4_JeQ1lW0-3j1M zVs(0DEp85O*bLGesd3MqWFf(Wf5vT)lTzL1PIA(lF3h$jix1iSH|@-gn}4taNTw&F zQETIIyb+9A71gZrBC;o1=YA7d>?iv6Q!Xo7pSw--w8ZdGC+dP=myW(+PhKb}IH|+- zxLaRk^WNTS!%5Npgz^=dr$#MV2rV?_kU(;1$v@^+cG4)V6`Ns<3q%B ztmeVES;c~-$&whmdsiUSWArP75{<}KKfH1HS&=SZiI;6jN4aPNQvhZt{`QskFRMcP zY=%)=a|q{L%9_lmUJ~nv!*=Ln<`md`+!(YHvWX@{O0M?=H%wXDvG|rg6lgtWrHg` z__otO(BwYm4-`0SgS$KU@q@EE{Xh=wB_s z+aBEP;r0M{chiW5YXES60Q|k-767=_gP%NI-x9p*!ChXaq`}D^&W2|bG z4BYu;R$8j18D&W>pimkb9RJ}=N#;cE!^ptRT>-Z*D7YUW>rKJ^6u1f?gBvn&6x2G>NKX;<1E zE{7z6cl>P0KYkf_!T&+O2d{Uyq#|1+TPDi~-}bYB&P;A0Zz-QF50^*Fr@;j*@yfZ%#mWNZMrDP$U_QaTz{1?3g~bw!Llze;-l@8& zyj1hR1NxTgqh%k>{%ZMG3$8_<76V(1ZV}far^W6T`&*Q?Fu?KKke1V0 zX0+VZ@|l&)%HFEGm5Wup)hw$;R$p6vXSL7juvM+qEjWy$`L?`2pUBVR7xSfj1^=>@ zS*uR1#YO~SinaxX^hBj=QR&Bi6WViXY&3Rkic9LzJZI10N zO>2!#W3QQ@nXOr-*{S)xt+FlOR@1hBThF$EZ4=uTw`~wQ2!6s0VFzd?Cxr{bkHSZ- zR@+nSp&h0jr=6-z*DlvS*S^t;I$GCGm!dnM@1ozJ->l!Quhd`AKhi(fzik)YZf?7y z?cTI|+g{yXXm8)%r@epsl=j)}ziIzR2h$GT9Y%MU)?rnLogMCURCOHFF}~yej*mOO z?IiEy(P@6C>`t3HZRu3o>1Lu)#FF4JzK-QV^>_TSsz zw*RY(d6%|bT)PbG65A!C%bG6RyBzCswad#c|2UXC=p1@GcsT?+#5rU-tZ_K#aLVCX zSAEyXUDtNK*7fIZR^2*v8`bT0_t5V5dW7`U_B`Vl=Xl?#hf}1}kG+^)BYNHL-M{zt z-Y@$k_xZhV+rHPFdpjpM?{zQpjo=p!Xr~r#_5NXP==yD|||PPWasNdG7PCZ!6y(zNx;8 zeRujAeE;xm7;HAU^33lWH^hI) z*dftF77ZyFQaO|zYCW{;(9oeVL-!87;&0_|>)+jfkbj{6Wd8#H&Hj)5-w)Fda~|e5 zEMnN~VGD+>7cdIl7aYCEdODECoMNBuEc zKDzbjQKR!mSB!o!CSlC0!1TbUL9RhZg2RIogBJzw2tFMAAo%y-h7gMoA*5%>ppejz z*pOKvOG3U2ITUhxY~t9|v9rd`9s6?Jq;WUK{XFi?xVK=Ez@e&8o6z>5eL~$shlGv} zjR~C}dN}lS=;hGcp}&N_2}R>w#?KyKHU8fT-V=6CY&S7>;-yLclU7W&o4jF4`zdKt z9!woRb$6H|EHP|<_`vWT5#1wtffHg@#JPwo5&uS-M!H1?M2?OOjtq_bKC&+IRpj4M zu2E@GN21%u^p2SuOU24!$Hf-Lsp4A3wTiQjYZKQtP8ZiMu49~CoI_mqILEl&an5lr z=;vuC#i1E!!f`9q_Wq{As4vP?FAT`~@u(LbfGsC@ z^`ET!ree+UwL47tzcG(O)qTQ;2e=s~UcP*x_U@Ue(=Iwy!+KSN3HetTAgGqYsYrSy zN~tF5+3A|pTK-)%SkvKnXRQL+oVoezZg|yzLShXR&urOUb=CH_;is`mi@h6;sZlx# zQSk3x9-A~|MEE$cWK2Z6)F=hc?RfFY;qW2-g5n42RKJdfP3?X`749pj0^u0`djpDV zI*-dD zpqdP1e_MqXLv^*N@|64o`WB8LS+Egb{R=4u*I=a%CpGQbdb6(%MfdAJDcVVg`>=qZ z*#SVT>#FXDbj3s>V}L z73S55M>3?7aI~pLoq93y*Z4bN-Ma*~L_|CmPO*siFN|if8ef|35!Ew!Xd4yUHbPJ> z>@3iW#m(|FFxDerFPe-iVFzVka?UDHC@NwKSTqS2F&AJnI13rTmR89Wj8uRXYXh@{ zRi%eQRjRG zU+%QAb|^B_pq6)Ez+R)F?Q*q&Yd82FQfO5Pd7Ns=Izbf?BdGA0Utx3KRh*&zU+%b7 zBZmoAxs|i36ON&;tMV)P_tapHe@l6AV2K(m0OZO+nzsPaL7XZHw0yTp*ayJrx%@Bm zLXCEiO$IoO^n}WP*~;O2xJ!k2HUm)?tghV{VSv48>-p+aLLkTgv06N9RNkG6zT;F4 zR6KCX^`eOa;A+*DuOsOA%HDAFeTc(*j&N9T2n_8$Pn*L&$eMH!vl_{xMW;&ohErvX z6jV#HkBhAv&+?l)5v=E5bR)}`qmCgBuMMaqUvZe@?-@8PUoQ2W?h^*1&H5g(S!4UV z-BHVYEmGvxUMzfOT7b_P07<=B2=17p;O{-l9CHcNa8%;c9oy?f7>LCR%=)?O^; zame!IH6;6R)eok-3NPKvsq|ULMa{7RFcrhHt3+i5{n#KM#W^1y{p{e5m83A2$(N&knRd?uj>ku{XbK#UtB`9j zr|Q$4qnC&yYyS&XVjYy)bOLTz3d6 z_k%DW0)$?Fs!?tR2aFkjPInOs`wF`cS)pDXIR2%pz&8|ti%8704d<7E3zOU7sB6~_ zKNA8RxvEk)ll#5{S7hL;v-$}9{Hz`vKn@&#BI^M9+fD$?1;}YE$&1*=13bQ(pVBznt?XNaGZ&(6|ce&Fix zIA+wm@TA>bLl=~py==;$+*f zy{T6>Z2=1!*|ew5UN(!^&$jCL6MGL9JzA$lM-)gId5gUR1z!}aMtQaKPvB*K%s$*fEg1}oz%Of7`ivayLUv}stfIZPs(?imXaMPw zZG^HthT771hYlF{H(6-dBK4!|hkphe0k$xpBWzRSgRo+DQ{x|Meoo+|^H}7KrmLeB zp2GsAW7pb4yKiXuk69(CTum%c69nC86s|@ImGi4{d;oJ5N2-ZmM-x@k($lBwNCzI( zbI9%>8dS``b`=6qY>L4Dd#KR&w40Em{f?K5m8dA>35WggIl=^oI9WgfuW zM?F%-VNj;paA>3N88;zO3rR699Qt-CtY#^NAc z@wX`DItK|$>isIYgigYtipq@T9NICQ`@Ms(_e4Uvc-~-DSc49g@-KG_a43!Y{)Vkk zk96&vu^V7QZm3|E6OBfd4cRM`(?#z}a^jW&*)K@h+uZDpOlLvvNT`0c^4tQw7-6A2ZK7BOF zaSKumsKec_IXo3T9?gMzvbWw`@>hA?hxkeTn7)fqRjh-3}UxGT8@V^}3_%~=my`!4H+q7KqZ^(kB>I_5v85PTC2edjYzEbA;{eYpHEehzwV=Ll=fJ z|3DEem8c%h8B2^AD?m=N5WN7bCc5^^@9hPy|*z ziK5Qj$^S&rF7#VFQmpnS6nlRsf|z zS66cD8ojTMdmkT)7UExQaug$zqDLfW=dVcDE*j4SaIZ?w{HzmSf@({=mqz9JH z%h!RP@bVC+3WsI)jR9p=qId(*#yyWtLC$;wxNUAI6^P?zCaSIk$IbXg$4!MQ0{b0H zPY3g&(UH~I^q?buRr7PQh_meWZ3SN!>Ee@2{xY;w=Ht(l%h7XqW8|;HD~+mHkg~dJ{q+*JoZ02q{zF?(p=_loc~c* z4Q|oX4ePM}X`%m^he`g{w2)(RY3E>M~!HbiS%Du?;6E{UU{~(QM24YCg?_@UH)AJ+GTwaXqOEuLA$Ik0`2ne zBG4`yt_|Yq#C-X3Frh&K@84TSijL0p;mV>(phqKP<$-Q%^Rm18uuaU&&!S7x}Pc|A>bF zY4o^F;{GS4KLP!lCXlV>uzHOhhd0M^gT+-{Af>ZVdB`fhxV-jg318O_+PSOVF$ywt z=N^>O8%oLz<%hrpGKkv=n*!n>pU6pvVUdz+d@LMU1I}IbV{Qwi2N7SzY9y%qekJ2zS51_tUyCiR-zQe%**xN3mVbK!}k^likMpDZzPwfshO z3w2TtPl_6u0*hUSmY=w2EW>XM;9iuUf36cJ1S)tp90x~#;!AM)1pmxVuq#5UbTJ&9 zB|luSIth~x*^n7{KMP%$ujYTtIwb%c$l;K6P1Eop)pXi{3azC>57O*gE}D9#zikS}PKch%Z!{dtdN?l1pEQyPxjrLK%O4xDezY?jn?^a1Vt_SwX$*U zXJ=d^icghP;*qpbuZ9ATpg=Y1h!WMk@1!KXc3`$I5Y9nI)di%B2hJN62EKA0i1wMn z;Ra2pkOX}OlK!QHK@#DBp$@fb&^QU_@{GkmL9ebkUyR&~&(-h=Sy1|5)=VKs>k8gy{0fxna`Vc(wx1YXJl{0Fk0pi@w|Dhqh=02D)Dp6V(7 zX~%&Tp~F+@k_~hZn4Ahhu+<=~B-n&n{?QoN8`QHVM4Mcyi!S3bI)T;*V*5-7?%rf> z0n*tC1XsPiNuzso(*ZGL1pQAE@FZWq-V*wfi$tf^cIHr9aU*~%IIlpu;Y?@l z?qse64UzV@IBB?q`my-uZ9-<<(@*zjNR=bSC+f#YHf6UrHe*nm4E6JOVS8LL{I^Gt zdB+R&FK@&5lIY+hl5MJ#O|q&TDQ~=3^M7`i1FPygh6$woWnZc-|L6BmaBI}w9{M8_ ztT+Xr4*@Vh{0j!7KyZEh*WK>bhTK@4EVO0GT7{-qLo%U+Z4>&P0rOAsQ{^zEGqFt~_gq_-HP3h;Cj+UjuX76!K=8X~Hbaw*gtfW7Z z(Sdm=_5mr|4NN9*fuI#QNw~uWg4QTNCx#pFGtehbRN@noKFK!NhNv4B_$t5x`2n>< z`d{87N1aMkWLLnoDZeAAf8_+&1i-Z&as%Xf6+bfzd?YR{ys*fcP0%XddpbM%0?ir(SD5oEXt@g^n0VYtem>-C(VnhP)d` z08-(GQNuJy2F;;sZ6(bA9o%`8W^|KqV74s~4#I4P8!NBj#>ykOvGTg<#tL$1FjXfJ zH-W>(8)kSZ8$B|OKORjcw=X^4$Ey?)|Y!ALXA{sG)P@weVw9%!Gd zghp5MdGE{ehRY3>uS+D zSogtrh=R(HUa}veBWNyYZ{3jo4`INB2Uzbn^{Tz%lTGo<>r<~3#Q2S}>YDDBH0@{c zWXU3V0`&l+N(bO+&llPA)?(k5S|5;nvCzjK!Q zNoY1eY(C9wZgN_J2EkBPC8dk56;_W8uS)sXqqu<0lgd)H8N>eru1lQcZgmC}iH+3^ z|2k*w+T3q7lJ!&v*3)R}v}h{!`DLdls#DDonz+{sh? zM&rp%E%?EM1F*ZI@qEI!26H;>&hisc3q?b36ZpCq^;f(sZ9JuDv>g*m_%Gm0{9oGd z|5-$=&g@|hsjgjpk7OqYgGadK7;k-};U117x`=;(m>wnIg<|V2LXA67nyYKCk^Rzj z5I{>nL0VMLsADAwWHi5CFa6w2C#k>ipcHQN9q7P;RqaH7kdbhi??g`ycNB-)2~fqN zdb=h&4`c>Sy7BH`CFGq8c`K#7k<&S-{TeY!T)*(*;Y}N znmYX`*X+T#b6erbb>Kt2{=y?TXb3#$k-hE&zC05D!baIas z+H;E-NXrcdFx?uU=d#FHW|6_n>dB22Grb6VfQDUNdzvUmr$8hw;r#0-6Oq`g6+H%} zsJ{UEP`P0nF<@>n@cRj(c!Fp@AOazSCyRwC0;ogH7R&=##DWP&Tuz843v*UE&VhxQ z95CSFDE+$htpN4EEg;ur5(~|#pURid5cqr3gQ!gs`!?=3OK zi)g73Fa?_18BQsoP~CK4D!TPa&w+}cLdDJgV5HuBly1~`=D>|%I68yvC77EtIF}s) z5{@?tDM*Jc;#k4O=-&*yy-PrIQ46CLGhNyvBJIUZwS}-r+(x#7WRuvK`z6py!Lh^t z7cXYC7qx3{2ORFQm@UzfA@zG5h4ZZWf_V&f|#mnu4-PzR{>0(7CSs<-y5LLCG zaKBzOs7JPPFsb?D6qzNFy?jq{0944v4i5??mLLl^3}D5{FTKz)vWBQ zS?TET&cq6|Ksp>PIEr=G_8by_$Rom{u6tn#Vt!!b8tS#9Y@ z?yom^8$@r#wkl(2k@5UoGIU8+u>GK@2!q($>#Fj{V~Q zL)&-2HI;OI6G9Tak*LJ$Lf9m__AZKD#NI1Kx`2WO>H^#L~j*%=2351+Fb=%hp*@8}@+c0$eFgLUwU)pMr82>JoLGYQ>4N zcH>BT!C-%VeJ9t1ZZ|eKmVe~CFTu9ySxA)j2C|Tw8yQ=U8Ae;Bql_g=dlOS{Y-FU- zT4Ddqyiqfa?<6>T=WXn>>=^_GlLdIZ2dOO=a*Lt#preJR^11q9f38tqp^x z==yV9+fz;gxo*gXqO~ZQAJ=wdp8mi{o(9*t+ZdFEE%a+D5$^khAiMgR>+eT%{mi*9 zmp{cRd%t`m$+MQ%7s|oChC=YFfXP~Z2(thu4*9W}ayLeT-vy{XDtMd*;gDpntIL@QA#vm1(}i^&+Vv@alc({Em}G0Gog=K+mDeiTD9zlptVYr z91n24glPXw+xn-zttj>39lXY>p6F9w+cObV#M_NBZDbzrXd!1_z=xxk<i?5ynXGAI@i; z(QyJ^=TkH1W?Z(vkT{P%=&p_`I+Pn_S-nmq2}Te7pETw%`Lnd}pb#w(;tt5y27Af5 z_PWJ|*u2BRyX4VV7<9psx^O+93oG4Ax)g|{F3^R#sI=C*sI;aoDs#|9r724)^)4!* zq3EJgL|s&NqVRuI1yl2QcYNiLlg1L0v1eWfC>_=ah%)mx2e7b$M!y&1Z3>2z68Y$< ztCsmG(H-G=UUkbe@{Mbl@9|0HpliW|)BK%WP60!FR}&}G)4#~8zsJ$Kn)xv}SbnPB z?%tiVU}uE|u8@&2lT^&Lk+4ZIE6^6-3Lw9%gF!=+Ot>fdBwY*&U#khXTMNb}VS-A44e*?;CH@U1GfUW3NZoj-Jj za?b}(iY+m=>g$wst0Xb*YP#}l;*t2X+roBilR0e=&f7TG zX`w>;8tu@=te4v({LN>CAF-qSC%E-M6RHXnLy+*hFAy$GJV^;B9f>c-ee~@zr{K>B zldV)=eiWARE8$mG1N#LLexea1QUJqR=+9>9&m;}`D!3OTn8FrrWWOLJS#%j9@f{!r zBD~Lud~`)$OoHyyT_KVeg7v9@|2ds%6aCc#z~i5%S0%ZLoIP(Bm(ITdyV=nUS=^gJ zH#ozAL>G$}qwpeR!nTug9d|siHt$)QcL~iKUV9|bA#71yX6;Ei>7}O(zkNhmLb}9q z4!kH#q!d{{IV?eMJJOmvfrRy0&$4g?mIxxoATA260E_798j5K1G5074(D4oe^*=qd zQSJ;2@^}ZiA@q!O;fCa){o;LnT9ww2R;9%>EOorD)LmLCUQ=7@F6+t-(dbLjG<_*d ztI}fHRCg6GjPvG)nYeS_Dx?xYtg3=|J771znBW4!t13v~BqZJ+g76U;t{uQ@un;d6 z2#F6~o+d=gG%S_H%gg7#!St#u=MPy(>Xbh5Nj@LiqRk1{*co9>@~iDwc;-xX?j(wI zU%@+3fDim97P=$=dZL0@;eS$qc7$f$=vmlDM*3u;iU&^>r{V(0FoZvyNJ(2PcYGk0gI-u`02H#&ZaOq4VlYwo z&l9|BnMBNpR7T8a5wq6c=^G*jel{Ak(2|EqZ%vi|b%ykQBCqnl%zP-vttUgG#{3|R zax6f0HHP$NBdf~kv^mOEhzU(Tpzl1o3c1qEV>MOc>&#dzFUIl92#zT_(xg7A$jKy)ryJP_flb5E{8Zq@~s!EK!u? zO%O_7OmsS^QeLbmxQ<0Hx##rrUlS6#TCvSd5FULnJkl!v#4;s z%KNN``n&tuD@R^)n*P&Q&s><)~sr}&*k+k|r8c=Dl1=s_4|4$B9 z4P)zDoOfc?Y^>dWtou-zOZ>cZ>l7g(?3;PmH%~^M_jHoYTCmz>^~x~XH}184b61sG zq`Wvpjb0v{p>H%3gcF>iRm$@fnrm3F$UU{cp=Ts;l9=Q|^9-MCD9=Kv)%>6aI%{CA z8eCPF|S$a*CTX_O;gF-ikZQ3N0Rt8OubG!BO zmwVt11KUAovJT(%)?^l0kE=p?YgqX3QsnU>MRtg2nM>!uaaP2EG_&S5wToQqVn4vjVO9EhkY?U~fR)2{Sd^tRE=fHArw@tu|eyh8R-Rw zk>@srUa%h4qivWqIi&m$XhOm}gA#nf?-j@)1VUdDIq@UDUC=ZnLMi<#2%2&&SxtoC z{T62(F~vR^GMIcr?_oQz zofg>6k~H5`=#~X-^(`Hq55YPZoQHkLxpbpb!6(i7yxGd!e{LnXLw6P*5-w|c2yXqH zkzFpU@X2VSAa2!dQ2ee8f<7P+L2J^7+J0Yz=`1c!T8XY5S~|^j&Z5bP?vVyRYGFqP z4_fBJ6D#{m{_C;)gU@v z7JK<%KDBOl3mG+4Mw;cq%P}IKcFUXs`meCJtXARM4H8nA3x!~oK{ACBe{ObQI*c=i zg{p604(dVok#T}V;T{+#fbqnVCAK4X`NPO;fi$Mtw*`#y+7(Z1FA2EDh*W`0&CAV(XPJD?7$Vuy+yXF(3XR?x zgUff)WXDoRmu|bU-!{a@LQL?7Im)YCL=1q z^o2Zc_sZWVo+ZXREpcx_=#KjiM2IS#4c0b9DI+cK_JS6{3PjrxizJbVlQAY2Qjoiw z6l~0szRqaDIjhmXn-mETB>$L|AdA_0X!9WjEX@^4UnAnkdd)g*k?ee2(TiV`T-qN{ zLDMR1&+2MVk^QMaRrQ)DZw#~ zxCuk|hVI=b+Z~So6yTOdoP@xSxq1zZt-$nRKO(6EgXr;^Vk9U#btK9q%JDPL2t$Ly zf`Vjg!`4NtQ%LmIQ+8^%eCU;rj?@DJ&7-+Lq?uI=XU^u6{-Q`2AaE6~Ap->HZbDDo z3@7%^FcFV>3CLh)bXHkI>;##@D6kViZ~aLYX2ui8d@>o2dI`{8V)ix`1`59?{RL#8 zP@<-CKfKkQM&-j>=*N;fx~d(dn~3xoF&M3YzI!kn+A9$=;0{~0!|}roktC6H&8_O0 zYkpk4I}fsS>+_^n-*7Tk%6ZIRIDNXT_gQzCGD`u%WvPp%${c)WSQFvciy&O8a9WRx z|C2WdK}Re2MtlBN><>rQ#3-d#Q;r`>%az^s$|2)Z6-0V$e*9^fE+Oyb@7W_-A64k~ z3ZPklQzZpuY3?|p-;(XicCS=Q-z_F0Hg4a^q$7$Gi&cSF*P24-`B@7`%lv~EEn23S zf5E&`H{bAAE&q$LU@CXhdu!%1FQnqwa4mJNvK7eYIIGkb*2nt&?980SCbm-}_`83x@ z=}vG;!vh~2k3J7e<#?vXh16g^Hx*8?>gvI6xI281Tf{r4=3hV$t-_;)N6#Dw|CbiU zqUuq^U*Im{=ufeT_`jTd-2SN35lhLeXe_|>RPnif4;;>}uA`;NSVlw6he}M{1 z;?HCe1av&J@br>`rIwPP!3DtqR6Gr>dJ(v=s_MZ=dN95s`XfmX&MOcbX30m#wqrjr zPGEHTclGa=c;I%4wl&_+RzxgX$d0^pNi>pNVMkoLERy^bj38QS-jPC1g130+D)R)l zp1MHiCkSxV5Bha|k0ugsCeZj|FGPcsjkZQX&}{T01bnf)@DR+D66-J(w-8_1**bo# zigo9tD$7^O1hg z2K9q+@|`wnIHrOr`35bYAJy^|Q!U^32>Mm8Pr#K#|4pL{wsZ{9?}PIq*h-F zB2<{(Mun+h+?m(@O2;~dDPqtu28F3zDfzZuVfrkuT6sqPc)R>@t-^GD5qehT+>{#> zrbVbQU4!lao_QQxCg&`I@mD|kigEPOF1yM+#nIOpIzKgxzAj%MeHR}>Vw3j;*t#~zU$=Z`*&Ka*@(J)Cx#e)J*E5gmQM;pltx_0cy}IPi<3Z+Jd2 z!_miBNgmVDSJ&G%*xPaP$MvJn&}TUO1mlWnpVbXNeV^%vpP|ochu^dOYGo2b`%FLl z^gR}UJ*FRiML7Iwd(5Ux4yD1&q_CXn+1&74^IR=38Gz8;YS@cH6Pj5-lWk{;Zp$vs z$R}-M6{Ojrd2wo4zUoxPvt-W!QHuOsD}R|@+HQ{}H1Q#3B4QLW!D*0eq{0gS`q3JN%LWwKcDE}Z0nLI;Ni&h;018vRGhnsG9GHSNI_c{yn8iw; z{2|=FYTN47GQW^{K{FL?+)%(GI^o`=pE6F#4s4Cw5~+Yi8C1IZUKpGdl$tI(drW() zB4Or`J&OFF1;4EKzKkMFOXsnje0KZpo~`VRB0!J|-}%ew&^niQLxVc4ReAx4IdZo@ z%CFGkm&d?HE8S4vX|!s>u$ESxClx;qRDx?7@fL>e3fsL~wl92d_#Op#r4tw7gF|Nv zpIE&u8__aKsX+`K^A$D^NpmYA?l+hS7AwcjC>DmS4_muVhT>0nutJg?21940KTJ1A zAx^por8o;Voy^`PD!3_t9_d6XMCLeOFUCzL+33lWEtrIEgI&pd0ck!1tc3-G1wmxa z445O5CKC(XrC0x}H4LmuHPNSEpbEaGAf#%z_TzV_4R`1Dhf;edv4Q=kWCzLq%GeuT&3 zF-pm?gL28wyBJBgg>uPvD3AW2L9}yTwvPX*1zO)kXh;Mq_7n5SuZZ9yN#Ae_jaP=F z5esRa4|@=n45lv;N!26J-xtdUX&^W-7Trw6mrw^8w@HJ(QipL{rxhZEoo1wqesC2? zlW)i+6Jz$E(z4?$^xk68JGz$&VS+ek1fjZ7%q}nTzr89Qm)OY`1FEBS2ynhTZ0}xK zURZHxHhM=No*3W%_##UW2;{BdcJLuMpA9VZzqJ@$ap5TSmR?aEO}(X; zbI}4vArXdqQkxW3?rOn(dej&oTPr-3EjqD;WR8M|dgtldC z1mQx&YhEKbgC45xuou^^djt_vMQC)nS`Z?X3{96yT;^gc=;-VEOm7`%E5|e31BMo@ z8NL@20UbWU*Z&kz3$ub)H3)MJSw_oUL7NX2EtA$VxTQI@6@y7P0|zm`J)^cJLBD?Q zBcOE^WDa788FXg7AtV#WK5pex|4==$KMyL=KQy=np?8fK_t*!&%P*qvKWUxMq7w|M zMlZ#BaOv&Bddz7`S4HiBpaX8h^LI0lS=G7DdDEIWEtb22;}Y6Nbj_5aYi4`QhKBN$ z+%>jtmwv{<`SI%%=vNT*yZka4gnduuaKVE3y-_FAWzttYTP~Il2G1o-5|QaCm7uF* zBf57ledWbWg;kLZb#R2CTXC%8*Mnd6W;C{PeC^tCcRc0CzGJdfn!v;IDl=-JvIN1f z&_Lzo(xU>&vDWhVS^!AcllH&DfNXW2ZYQr)Qh&w+=pi2wwhg!IzhmfjJyzX;8t)wI z(0~brmvEH|delL~$hs%XM$LHd>Bc=MHynB-5=kjxXeJ zd(Z*;PX{ysM+DNp+SAK;K(5H~Iu0sFJgaJPm7ZNG#oW8mxJjS8tg3x0O5^4ge5ord z5a=EhRlQr$j5hou+PMHV99#R-e_DB=;q zc<1zSsSe;rvMv7RV0RW(ba%MOX(UeM5;i5=Rk2wZkT;`r`gt-2c2WPjZa92@uZgKAH% z(L*PCICjSQYIBhelGs;ptpmnYsGA-@sfuL~f}|ek9nsx8QXDcmX^iI1)iRuF1dppo z2gx|*35D4FRh#=VtIVVG^MJ=GJVS9Qgh$ZgSu$6H?!8;o8efXIbU8ePpBA& z`=6NlI+zXzeQKbgI5fh#>NybkmQGgaZWJ9zpVuTEx*H*AG3&HEVA_fe;oDZByAhqe zA}Pw;;X0H#ywgEsQgt+I0Jy_jz(!{p=y##RtXgc~V|06Nd{${47Ty8TcyvzpilZ~- zck+8J8JFZD-5K=Yu|^M_$;dLOUrychi8rjDL9=lNT}j)JeM5d6yYHbLzOuC-_Sk(B z(Kurd1Ffqsqe(7Kt+O*~ISoAl#}?G5CT%4{I-;+Lnp;47LB~AQ=T@MI;dL22Xc~07 z#z*<$f|~5(7Koq|@nA<>!zCXvM`;*KUBFp72F|e=BGPWK03w{wICI=w!3`Mt#fgM_$a+BtZhYp2%jqAnhwt<^Qj&Q*11UYFMyOA8(n^2y%jkh_ z7fUdB!UhbUkSNTEz~BkgD0M^;_R6s>)U&>F*6K^t*D_cDfu{0I7k8q=<@$KIbF`UXLsc85?J(_Igc!IV74-LkY z-twh5>WXlRyNyidDE?0J@V8Zv&WI~ODy`)x)er%l^A3P-br(@b#*X zXFd%4fis^2&U~t6E4Z~PbHv-8kaiyZ140>eIoRFt^l;#Tts_Kx(I3Pp(S?=#+aFwVp2I$sYW>L&~w`?(Lp+__8YeHac> zv;10^Q3>^!`#K6KI9Fdruevbk>yZmSYB%(s#kX`n`a{~ub<}{~6gr9Cl@$N>`$P>D zUOS-q{Cg3prq=U5&{}jqVgB$DGf{%2vSoWNW+bz*3+1d?y4==Gt}XiHU28ALBm-ZC za+>n;DouG@N;9=%a%>qQ;{Iwy3%*R2-{)c~=phWH!yDUDj>CHfbCNrbZnEeDrFV%M zwS<-4pv+MaHB~PT>jSkF4WQ>p1+zLwJ0-YTzb<#f(QP=FkFkpfezH62& z_0M7q-jeA0c0z%WQ)Yn!0RMh~3L@<5E$SU2?U;DYfq@rAO3^m>gNs$#gJEF_;uv zqDgTxC9VVS7C?pQ`tj?SJ0mPSK@ln%ylCc(DYD@uONy2%r0Rm@>J?LEPO}3>*g9rZ z%v8)+DCnJ8?)=V5;=Uo5v!{#~VFLIN#GPP?vOf{vo@l7tM<&raqrSmy)-r1zuMECrv2i@0%fpO|n9 z<_gKM$&sEJ2XxWtk(Sl{MUt_o1sa2%VtKRjAhQ5Xu)?^N>@R6vQ^$JDBFr2LE^je& zsyk^cTaPhH)+@NaD&i+}85bJrrQCKuAs(dZreKzQE$g}L*_c8aCE*5XKCD0KvR0Y5 z1-HZYoY6k9l8oAr3tmT;WP=+{;#~ehoirUbA(p$vx#CB-Z&0xywbO0|VwPo>9ZXCs zmpvJujknfh@`$!;6nQ@g?(R=hKeoD=wQ%@Ir-kE{y{A7CVtL+)fN^7;XW9@G=ltK- zE1iB25VQT4heK;CTsp!iWD|)c=J1OawFtk!H>kWO-yoL5BKYP(t_{3IZ08E{Qs5zi zJ8+jJiNsRm=N=k5T?zXkSs-!22CvBi>wI2O9>n2fAC|&)bjbTp90P{H6tz!(;>_F3{ZY6}ZBE2W$wrnrr^6Mx>wzs-) z@jdVdWOZmc*1IdkRDsdY*J6;KN7e02;lnd?3fk|dT9y}=B2%+2$nH!%jdnn+z5Ret#pqP8%d2tNOW(C$ zGuv^BO!}r*u>*8fz;+X0Pfl~4;NpinnntcEB^nGA*POP0v&r+6nUhD@&mU}OfAVs1 za@upH#0?u@n*r-p=Erq#?yO#6+!h|O;q$^!Q$~6?*%Fh^&Z?Iy6wZh^YD?WTG9W6Ee^NRw{TJ1d$zHL9X)C{}KuJH2-^0XQ@J-JvHn{n>2GGVN4 zRJofeX##=ly7*0T$7SbJ6N(BCE%dQ>p4Da%?pBS0pgL={OlqyRvChUVv%$uVrs=KK zFwJ1&R>-{xAtQ z+#|SDdQ&DA4 z%cc_3oGMwic^+D9+ez=gC8iX`naQEtiK&uNQ!6H$p4fd@j#gQzgqKaT?*cm~YJ}R4 z@X#)6nLfjGnz_*jEOVbUnvR)$TjhW%cljaEXwy~mHM zWzwsq?paz{X7tgL$b(^MoRuXCU%fUWz^aFzv%OM!YqZwWLFPGgm50I+H>z(I2vupT zJe7`4o@21+)D)NB;`dSGtSnLJij`rjttJE>%}`2nw5se9nP$;(r#<*Ie2GyGXmXbx z0acFq>)eQZ1c4im{WNXef`w>(bajGy`ZSqO;F1Z{`e=p1OB5QpFC^aTQEFb1QhMWp zQ%<2QJN;meqA=G%=rJ=YTUn^fzJTRU`{r8*tfgjIUZU`rgJF?YCDBW~mD22KZeHVM zZpRnuaO>FtcL2J1>XqC%C^FU_=?PI9X&!rFUNQ+En{!nyznOCnswKX1CVaS1QOk$Yduj$S5s6m3pQ)-go@?c|H@BaE^qt z6BeYG(lYeQnNz;wX_@i!W=v8@M;WDZ>sXA^7I1JiEP>Ssqh7rmm-*)rEgt+=Mk3<< zDuKiaHq~wNs^})~Mrtjq-{jrMYN`jjiX`a1r{93hrOET_wp~BofW5{^>o#E5;s)%+ zPxfCo)$PBw*KfOyge&@OSP9v{{RHN`eXxTcs|S8r#O(nkF9nvMEi1P#h50B0{7Au6 z$WL6QiWiOc&S1e+1~7QO6CLB~Qch1`$R;j2jdv3DyU>y=ZZAh&>+zP%QN1Q}(L+6K z$ZK>pT7-&;wOn*2mJH!X>j6)GZHxPv;Pr7EpHrk`kH*a(boxK%jojC+OC9pc*%-_U@twN02fC3{5nSW|Ad8{5zC^j#&A zzmuMK=XScw00oli?`z*rfoWt=Z`K7KP~+*NDRSbxQ%>A=$Zs7;nzsVhXQ!1ja5DqF zKDm_#XuyQxq{*<-T|}1Z116w>BH0AbXp9g|kc*t-lO`C$qo-&w#_*VDh~aUN19G_XhQ?P4^K>Wzp6OJcdpd{~3#7Q`b@ zj=o#v59C$-4l*BiKN-b!N`mp(JXn{(hjm=13^|zu<%JBq-N6tiD8DG@z7J=}^eVGt z9+>2SQ8xd_DziiSYsGRXU&jzGgf_aa=Pp>cB_sK0upoSIGF%M%!JKzo1QqEe%bEEwssY z#d15^V7v2jyCZU#xn~6&&F95b+45r`mW8_{DIw*%C#~=HJxh%&%N~W^wBpS2tIdSA z)*+$eFcwYa*|&GzJ+YjdO70R|0YFpxDq9|?(CGe5l?h9d$la8=Pu|^qd$!UtR1`Wc z)Y?{7ZI;iOiEf5G3N2HFho9|xr}dNXEK?ImGTcQ1wM{sTO{j8&(=53QNpt<)b$i>t za*}1JFnpYKxUE&SnKNf5y!j|1yi6G$+ILdx0pE4AOz?%fbQJ|Ni4 zZr=@PJ*lr{Xt*G}EaK5k8E58PZ6>k}w+1sf)k5->*b>jN?7nlBcT!P5?SW$e#Aka570JRmJSp=B6) zJ5VCZ9C(=n&2rIL2hp_`~LK^>PU)Efl%4yK=egt|Fe1)BxE4lm1q zZrRYhznpVYEmniAT6$00hS`cbXpo%FzpRwL(v~cW>$Q`5;Z_bgv;P#Dn3cQbv?fN5 zle(@@iv);>S7)X8l|K+m3jnKzaz-8Kl?96#rb zkl%)?L$hG=%PWVtA9tziF=yuBK$`zZ^iILw>f8*RjBFMX2@lT)EZ z7Bs^L+C9@-3x_n&2OlYRlk_hwX$$4-PoY2Vkioa=()Tw{_}NA(vVRo(wr*w#5m{k2 z(r#Kiw9oE#a~e(%;F$=9r&edZ zG1SgQXM1IVCDxp%gZKDs+8}BeDpElqEV>pRaau`)twxcy>xtY{CzR&xg_hK4qY0Rp zO7CS=qa}p?7FuLN?^NiO3Fb)1T7w?fYt)N0C}$yer8nUXElj{ln|md1UPkvlbiMf@ zrgVQ&!fDwBmmFM52wXi!hblttljfGKF~t?f1FS z7tIXtX0cU&Vb?+%w2b^A?1#-VBAY&;qqT3&wRH;5O@eOwRb!!<705NO(e}ODU@dLm z#EE^oU!HU4d0u)h`d8NsAw68!VbhP56sBZ7`c*Z<#l_vTL+#`IHfwekJk8n^2;H$W zd~(j`fPKy*wKVHK)+yvJv0Xg-5=*7@`h6nH>HX|k&MzQC+}HbH=~>xD;bn3mb{wiZ z>1E!cF{4K>DhHnaveEIfas_!uo}wy!Ue*YaH0eGkSt`PkNTuOJZKFeZCOL!pk`QGDu zpEciSS-@be;8=BYF!n@$7Lt#KxWzqT5;qoxAW0{vhIM2)ESJ7+%lt?du+}r|`>j;E z?G(H`T5t=sC@)WY_Z>K9&Uf>bt>(>Nx_PW=cikk zYkIs|xAaJ7<)Dn~!h)RW)4B6c4jC|K#^B{j&z}WPV+zh9JCJg3)t+M<{O3+tOT$>d zd$=KX-UQhQduIx&O>YZ>J3|gc1>Vs2S4Xsw)L|g26;gFuM!FgXRfn?DHA95BmN!D% z^)+BbQd2~bh|Iiz#0jOVE6{_t#YI>o3<)QT$&&C;L3mzyc%q&SQBY6=`xt{hYisq) zV;;XPv%C5N`%7F>;TgXZeOz7Ety!v^xlaJg;k+lJe|HTFpMtpcqNuo>D4o@tBG0}y z4lei>+Gkd}D6?V&lasT29@mnu;~Ybfyf^CiXCrY8^|grYGs%I7iO^PyJ`Hm1YmE6O zN}JGQuVVTSf}5)sq}W;!V~laoRk=;5J5-SH$m+qBIbD=w;BRajH!n9AwfEy^r&5c` ze2xy$4{F0`!aCf!W-t@$Kr{U1Y&O@-ON3|%CR2!P9cgLmgl44ji-_PRcyAi&Xcua4 zXynK`-Y^u$&I}B>y^3-NScOM3q<;prWvc%&Ay&@0S2S^%kM+C(jK=Msoe+N7^g_5M z2L#Ah^E^k}&zU=J4Sj-t20dOM=j|#RKFtF|Pa|U>CQFbpWG;C6EE5^Sl1w5{B3I}e zFyDQudPRAN@q#dIk4|^ViJ_o*T3_ z(*nLp796RTT)}lU=9n+UC~(OP1{O?aI0<)*eMLURHnkDtD|}!jgVn ziA`tHyM1W5Mfja?U>?bS3wsmt9Ic$7cL%WP1pT_1O3=Xg6xuth)TfwgN%b+dEA;CO zHtnHzc(_IA9biHqS^f4VEaEvn^A4nUCt}l$)Hd!_6)%m^x1*|;I*qA5iN0CT?+Mtv zfZnf6!-XN8!`k$aS%>2d4p4-KlHR`)o9Cq8Q%md)jMB$xK8n#N$&pv>3f2D+an(g$ zQq@I%62Ta2iU?4IgM$7G1x4dFA)pAOCo=snUQ`gpR-yaYAO|4szy>FgEFY9 zB-HdB#~~^qPJg=b{Qq?0bJK_uiyjpH(cGX9*g_A4mFtNJBfSyDs~_n?`jOuFZ!qZz zwxkE9_Cb@p{-zS!ss!GtstP`Lft$*rbLL^e79nzp!$dVNbPFsZu9HZ{wh;Ik{djhf zj^PoL5E^U|xQ1@Whu$-gcdcq8zv?`73msQTEI{D^!%c&P4yaAAz%Cf)V7gue;}AZ8 zC<@7N)7`>C)G1*~j63d>i}^5vk`m;V-8)AC#N<*hJsJeJ?0FaIt1j+Wo9FK>lN zcv!ykHWpb#uU-yBX&NGQgqGF_U#G>;-XP2S_18jBnnnl(?+d8dKZ^#oTJBJdt=Jg`4?hLXGE~>E9cD% zbVpi&s(Eo92eHAq(Q)z7Dx?+d9yd?5!c^i^HIb*OO6PMYZtcj-h!hRBN6CLR}^aBVLPM;_sSM=dFEk!3X1>x1cBJ_^l#+FRUn4Ue^^rY|= z*dnANibFl8$6K^Q%nkwR+>`X3mFKGQ$~Bd!!`dei9rOYn$a`5t- z?c*UU+jzN-4B1=l82749x)mxAllPHr|lSGp| zlQSk|0uRA)!T$)m3ay1Zg?okBBB7|2Xpm@+=zu6e^ug5DbeUFGvHqoIvPHJZ>U zywTo9*Bd=$S~Kpiua16#RcMP;@6F(jcpoFX}qxU(#AhF zj%j?faem{Qjo+9xGHYel#jKCnL^EHr@69%u?KO)xOE)`XR%TXV_M6!&vl>ZL$+s9Y zZ;)hy#6uDwSt;2p*(r&X9FZhTG?Eg@b;+-i-zB7psEM?Ryh-~eJ)77z8Pmj}$@Gll zndV}{mU#=hLvM(lEvB%3;AuL7;hQ$zn4uTr1sEf`X94N+( z$(ey-(ilT-{6oAEaknW>o!ZR1dQAZ*r;#*Khcp|I-7m?07>%^*!<>j;*2Po(8t6Tm z)(ts&wEatg-n0(k*e^0P@Vi)mjP?jwEGS3I-y^VCAkHMg)&hwEq51{JXSKknGvd`0 zpw(d<%B2B;KOfrt(@(qhDWi@FHXS~;<%AVTOY$DynifB7H%8hD$%qO&W_4YK5|o&i zj6T3R{vmmrBf9ZmWhJKe%WE02jz5DDcX#ba`krUdH>mOL(Zuq&f`%!_DDN+RkRwoZ z3$Ry;M^}G?w&_A$^(WE-J-ymkL&_Td^uo=6`r~>?YLph|e*5 zlyili6j4@8I;jw)9=KfWW{AW6TH~^_*Q1r;LNV(~jh<8V;2BR>43~}&Ja%^hVqD_n#wTpR${JxABmZ9+j?{wL(7)}hy=wsCC!B-KqHc$)xTJgu$ z@8T^-B14Z_i4C|)BoQOe4!?c{6~YDpC!zRqO2HkaSP$quQzYIhH>W^;$%x5!F+eWv z!Iw{NoQ06|gt`#&z&p`Czeo%!IDyxu|4yii%Kd{V$|Dv(aw+XD4Ui3O(xK6&L!?pPt{MI%%&jl8++l8;vT z)C2vwNT)j6L{{j4B9^i zKJ>U&yu>F%K}J+Nvtyj16J{vkFU~{|=N0KV0e8Z!(MGT*G9L|W%7UOgZ0zC!C@w&R ztv9gqBtu${AJ-KXQiHRz8L(48rU`UR7(aFBR4??uXgW3PT2aDv`PezVY{n*5Udqg+ zmOAyM&KEAx!C3>TA|%xYNg<^yq%=fNsY4=Cn&L&8q8l|*O1v%~GsnhejDZqgPboPY z9I#P&E+qg3(s!2<J^(sDJmvzP$__GQt`Zaq9FBbmnIN^f2%y95|R9-SDF zBk(d)iqaM*kJ_a~eQSm{G(jA zN$}!8p?tCj0?AB13#Mz8j+@b-De`t-u(6WVdjwjO=9O{^{AC5h%JJEbhh-gZBZN(7 zJ6qD2nE&PmCLp<{ejP;(J7#{zcAk>*+pjripecyYkGCB?79-ayCAECxAo7jr$Tt#^ zZyZFvk%)Xli(rA6>_xEzlPH#8G{q83LM%ZsAKoK^K;-yCwlSmckewD6h0qOMEv5>G zk^L)2tQ`6MNXs9Dfmc_RF2C9j4p>YU_9X|F4_i4taG2$0;p$7PF0H&g6!v2}bVv7; z3&Pv5Gv>nKn^C2f;^6&qF`~eBeAEZ0-Yz%pLr29XWF6Z7QQxHDW2mvtTLf|8I^&Lx zt&qH|ekKSxD|&!|t`Q)pJ7@J-I2pujsg}91kIP6gC!btNY_0{F3Y-o;tWPhPl7O( z@It*hkwI2CQS}G$ow39sR++y`KT$oyiOLu!Di?6Mf>vj8Wj0B5!O+?v)Re2V_~GRl zIy5LyQiFn18d-rV@%qyg*S=9`P$2kyne$b;Ni7K$Op)1p_;zhM zrTFO@v?LI>m2bx(`9F!8J0(W~Chb#X>=4{rGbf{)6%l&dwjvfKo{wLsa;{u+I5BdV z$HIxh%B|QH(6pF6ld#;?ZIS=b5q=4osVNw7NdoEYlj731b)L_yi^rqq^PwPkNw%`X z=VBoDl#c?r>z%9teWAtM88T3eK=VIhJI46M>sBeff&~MQ75Z0N-8`3cv&z?hN=jUgk@l?5=n=)atr-zG2il2ol zKR5gAIa3LSDwN*P2N%f3*aA1Y%f%3Zvvb>D{(BI7F|vPKHCl`U(ebldfQJz5p8o;X z(7o$hGD=CDg*x<_<7~l71f8$i;&R<`On=f@DaPq*5R38AYyE#3ypYfv2*b25&w(A( zbRO;Ib+CMg2r)613$CGzbrT}s9I6i@Mu~72ZHHhBjj>L{nsC3P$wr?-X)>xMFr>*6 zLr9Yq3h5#m(j<8@^E9hAq=^^_%y7x?Y;XjpkS_9HaGcf`+PMIRS~q zu%iy-ShWC-p@`FQ^3YbT&e*+rS#=c7 z7;JUt!ef-%S_>1B!oyD~d-Rz`8U+)9X^wCgAmj?~`6JV0QY4aeWoo0epa$I35q&n^ z$l+uQSSLc;P$Pr)B!XZBlNte8FA|fn=*sqdXP)+^>=&03(o8{o>)iG_37^IJPF9L> z0gmx9AF|LKBamoezvzuR9{h|Mm(2UMPm&f(qmF9#W4jaXc}}w$m%|9+#=*mt3L>~3pp|OK_FJ)8_FFE zW*?tL%z{bhy4PbCi2rB-4=EQ6ggh+<)$*?mswEVY^P;?!f9RMDbp<91=SDU#kI#E7+6Lw$S-j9gxY0Ob9`}{2}OVFAzP4sfcLvekCNQLi$G? z*sk=?&0?3^fpn|t4H13sJ8rbBeffAXJM#jw4c!&Qkdw)hZ(VQV9u>!TKx{X$HDN2| zD2CC{cFQre9s9rzy)kN6GU$zgj%s-R3V|?(cO#bHD{yWF@c~_#_;a{-@kd@PIQV`N z7MzQS&?#{~?b2JE4DC<-p2|zhfGKEeGF*(>GlQ#7AiDajRNy|x=%T3(uv4LKu`CHYVJ8B-^OiV@oB9=Hq8*|vV|xC95-1@u+EAixl(VpMAw88tOh7%@i1M&B8A zGBO@9YJ#Itmw7(R78vy~G7j)tvcRZ|{<|IKFg4x*4^=vNHTLLMoIFRg&PR zrp9ot|Haf{CyY#tjE1A$#HhVd7n1TYUalqsb7amK z?eCwOr+-iT=aia14A<*^Kh0h9uI~KH*XyqS{kP`*-_sgWKE8{ZTMg;|{^;}e;G6Wt z&)3qwnE9)T4WsJwdcRuazrIlO^3x)9H5uN*`m@iTSHlzfw6x*u<9`0q^}nap*Ynvp zt)*B0b{Q!Dd-|W>-QR1jOR2e6cl4isYyP0T?8~2;5BM&*fBD*fPBlDnr2p`r^49$I zPglQm?LR!PU+T*I`<^wF_-DFxRO#=3N4X|hUl!-En#Tqz|K^_So^}l}l==I2O>RRw z>c?CIx4HjmiJD)r{!eBX!*l<8TWXRT=wg}Lr)S{HH4kd8QM$Enb0a)Lep~mUb|hT%-285L2$}(?8)QHCGI!YHsMS)%Cjm3`^9H z0Yk1&zw4gor>XyR_V;`LICsN+f1LVnjvHo#FXjGNI{EMBH$!`|fAw?!muS;8%G>b! z8U6n6K89ZZyiCJ8^Q9;DdG0Trf7V{n-}4wKf0WLAbo{r&h8F$p(nkrO)%wwuzaQ3A z|2^&NDF({_{FFZ~UDw{a-;b|-dfXs;);{ZhY*!t0`j5y+Uz358($vqm>Bo8TTFsmKlK-a%|Ci6D;a)y(;@98&hJO0I%>V8A*IQty z=WEx$mj3nDeJ*oSxv}mp8&-q#h{_tDN|g;%KYiX`@7abD4fmm^{l}+z8RT5JzN`5i z|Byr1yw`uDyo5);qulhe<}w}|q^E!2;Ixi^?va1K`gv>r{rT7W>A#@x**s_H2SfRf zo(sy|bf#{QI6tkS?n%~``!6M+FF(hc|M|2IJVSm_Q)>8YxQ0?$!Pn$;I$ml@X&J-k z%W_uT)i3>ir9bF6rTy_0ZQZBOrLG^pE-lnaymjLQSGe`#jq;*THApx*Q7+fF49BMa z_oMuOzY8k&QVR4b{revHL|WEA3#4JCr-f@y)Q-{jvsBLm*Z=-&xNAdtUH>9Q`dsK;ezGdX^V$*l zX?jDsztjKEDfQ#?TSJ|+M6IOrS?%?-n$;ia4{Az2Id4*T*6=n_ndzh6Yv7pg8}iha zqO@7VF^-SA`=#q;3DWpef5kA1OO31y`7r%&@0fn1N$ai~H5}C^{ilPETh_oY^gQ-6 zT^iQ^$r|)i$_-^dP5<|2b?;EabJmX!s)71{&7B9_6~(o{&zXBa?%t2ytN2l+mk*F4 zAOadfG%*BAj3Py`ArMiMXEfCyK_kXzj4?tIH5$uPpAw_SXNW;;*h`F}f-P90h>A#Y z-~Y_+-uB%KAA-KO`#aNi=FH5Qb7sz**?TwM-Ggn8d(WUk6?YZ;f#w zD|W^CYJH@mboaic=VqZ?%6dXM{wWA087lhaX8HX17q9FIlKk@|CGXd5TmIS3L!J|u zE$k}b4_oJqKkD>5&RLXRu18V6a&9@Cd08oF!;^(MSqavb!xp6_ww=m3;(R;VXB4k5 z^dIYgSi-ZRjeLa*+moNsDdo>o%4f^dE8)vhKQ0&ZeV!&hJpg+=Vx{;CWuWxgo`@&y ztc0uHd)o>Kk`ZUL{YcfV&ubf@G_HW4G`UexLeZ|N=t-GK_|N>z8?_^RKKz6cUYTeq zRtT-@X7Aq|ZVT@W|A!R6)|Vh`5yyQC=v|4`qV${~vhsq<^cq{sv6hx#jH7-%c^hpe z+AmuE*fwk_dATYq&3^Hf#NM?NJt$f!CAP}%?j}Ev{)?3R zZ8r6^Xh3UikBi)d577fwNTPT!T7>5Bd;V}-1UXIJu;LsD&tiFB3AP&utqDWhF-C1J)j zqGr+j5I9_E5Sv=QYa3y*6Y#m(@g$lz2lx^#^A@s%-(pNn zDQ~?_W?A_x`g)9Om%JUH2kjE7-O5}nN4te;_X>CZY{mVoYdYtv+%}`5ci9!`GuAtw z`cbkX+e`vi`WeXfbm0?G{<>~Lnfi^C-=nM#|HWFj!f=K60k+opHJuvQvWBc|`!!5zP$LADWydb4K`xZ;ff>Xbzqht8yzisnLbT zat}}c>hr#p$a(U#*e|A7Y2H#RWno#ghfO&x*H+rik#5e&*{FO7mHy2tye>Y?e#fuI z1#3lwE1_JmR-a!1ELSpX5Mqpd$`<1k;(nEhQp_dAxTbV&sce^u@kM1n4;Pv|N{ezU z3@f9bp)1uD@p9?YgnOfOaC}&rBOfnkgNyV`zuz?(%26%G_i?EnYU!R!v4@mzQNF$k zp)xvleq1c%;ay+4&TLWA-#X)2q0XHoC){1o4&zjlrl=it%IC+;9_9CIbuyMoh{~2= zK$fE`e##14oFjQ|ez_;fYFb7+E-dQ9%uB019@a$mB-qY;>=(rRJchs4tZDw;twvJK zs{CfMVlwKjqx^}R-|d9wgx7}W_;mK5JG^2Xrb)y-ek{rFZ8+F*qRa2FO)^?}t9EXl zpj5o~NOBhX;j)n4)Z>#C9d|IR>G7frK7DHKG(Ja=BJm{>rt4i)hCWig~tj z?$6~($yn{_I?Bxt1$FFTgbH%)G?=XRbu;GbZ&deLVT$d7^H(|fVI)`QutlqAEEiTT zk?@=!=5LF8+zjORV{vNE}D-BZ@)@b?IbVH zisnCLV{P;-H)p(^r&;`DGd_B@r^nmj-=b9SLW>ev=#V@uV_)ZNv;B5iMm{{ zr!W`dN%q!7X`Z@?_Ozop-Acu}{0=O*g}5t)%eKR>LzPPG$|*t~N8u-%3q%QUfU^6R_06WAheTtdIu$W^ab$;n$PZCk#@CvI6mjnc}vLWTanvy=*zuD z9NEVbF0NZwDZdxyDEG|LcE;(2ILe31Np|_1|6fxp+y1`T7ME%lpQZNFeRW+erx0tR z;S{EohU>>6d2O(?{O1r)*iy?p~!Mw7d8|YxzWrOUk2HS6J0{pD#`Ovr(`su|Gs1>HR!6>6IWDyGTIgFq^L&0nC035a;#!oaPNX8X zx;gW^i1=BF-0q}==drbQGVOLk(t|H%Tq-r!>_q?9S40VOZSPP@58IiSZ=o-dvow{@ zv#Y7es6^!|>qPb(8~vNRioa6+GJRz2u@i}M5>*~c860IZ+6>M6lN)J&v|~%?+sxwF zC%io(?mKH@L}zPBM4i$R%2$$5uYzSJpV5c>>BL6xuFwC<+11|+~|?yl(^*Nw@%)Y1{FjL--Aq&%~nJ!uxck)yw|O!-+nJp zX{<{0p`v|5em|C@UcoO;JqJLe=<-&lcXlYVzK{7e2g}yYyqj@FTz++e$@@k0$d@U~ zv%^Tz;v`cdtHld&P{m*^7d?RvSv z(#H*TLuDxciqQwWy(G}y+M6rwC#|JT>f5BgO>Jn?cuDgIqZ1^h6Llit1NA_{2hmpbZFRn_O?_K?(8}*il`hnU zlF{?@JX*g<7fH4LOn*iX7wckLf4-hCUGxIIK$`2%=}9Z!laBPHmo#v_U2kdY`nW!l zb$wl5X~Z9x_LIF_f7f4X+yFN~nz?~)ptN*@+#u=Z2GjozzW?^GA%irlEooV2?TTx( z$a-3I^0a8|Y0=EnqMN5hPfv?ho)&FAE&6y`?CojcJT083MLSQ6Do=~Fr$v>gMcUKC zd0M3Oa6O#f+UPa+v}nNJvi^XP_zB~-kEcuE>C(~DrIDvgQ%{$!o-RE+U0Qm&w9yOo zLh0?P)7eueUS)P7_a^E}lBwJ#|`m>a_OMfj6MeUY@aqI8%FC524%1ch%?V~5spTYVU+BZyBvM)@#THbx1 zMGFU@(aw}EwAR7bqkX#_zgjpJ=+9r{?#+9Z$8d&mH2?AfkH`>dE47m0M6i=IWrpl6 z1KCM7<*w%0B>oMiCI26zyf4*U_Lnizjd~i@3j(kjw5Ntr7$E!6(pvvK$yd&Iw8zp1 z$l?gn6J zle-6#-%<*1OBqZZ(OtQnR(oTL_A z8n`|Kx7wWK;NsR$E6d0m)dFq@@7VuVwe+)&%`~j3$VwAR)dvQW&maw!Qb>_jA23Tm zlCLvuOw-CjNYT~^viLiPEOS;LU&8PvW%It(Hwt>0{UL(VmhUK@@~t(@0hDf82iif& zLP$aV#>`~(fws`U5Na5U1PW)b2~eq!oAcrPtdi%_{8L+7qTBeT^fHO*%iX5*0kex; zJ>XRX%U60u9Gs-0CC1l2_y)z-{zSX^yEr``>&;pbT_#m~{%V9gRRMMS?fme@qo#0inN(AW6tUB=vlQ3X1O`DW-K_~1;@>ucdDB_`?MLe z+>htXJ>yi@WX`-99 z<1U{%G822=S$Cz%Vh zd|$77I?AV;B0qge?8oKPhez?M>9K!rvQoc>T|ly1->O!ZoS)*nwUB= zHOJcF=X&*;o3dhAil-YgWnteY>7P1?@Zi)$+}hN5+##uPxI=xOf!;NZN?Bv5%ZJR* zGB*h0XMSTsY1YwNbWAJPgu5BDNh{{fcC4+Pn7wOQ@4GXzp@U(SHoK6u#@6pDWTv6V z(uBFX87o2yzsj`sIn8pD&)HxX@@94+Z?Fq_vla7d_Gvj@G`n7zO{+WTFx*yH4K%yP z-5}axHKDulAIHA~SPNL%OTa_G8sKUGKFR(LfS!VSrFVs>Np*6c>Ilhzl(S`_KiK*FYZHG0ndCO z;_K#yExQ7kW>0_~ah`)Idr5Y-PiyIOF*j!$0Jr8U*~`~Tf3wxWn(U#p&3F(9 zHU|$`eL$3=!7^zOypg-1H%~f(xfW|nR;#rkA7^Q-O|+>t)8@?3)+57oRPe*#IYO2{ zqE0F}D3}vG6sPry^Nk3O3~rCpSi3E|;wV&C(^v6=4w4CG7TiO9HtPjXGutExCKlao z{PVrz=W8SzbT7U$n|zKgagMvBI&h_TCYooui3_GeLJCLLV$J{jj_Yz=kjg3qpO<=ChWat_#3a3#NtG z5f))PS&Yr(0&FE0Vk5a)|Df0EHD#Zb$q%Lu(gVxHC>^T@=w$s0pV0Z5enY3~VOTY$ zVa=F{6=QbU7MAI^xXf~?btkwJ-AV3bcZ!?Cr*`JLd2armPNSyD)O3uS=8kpK-3&L= z&Ems8$Gh2kI*mEzWH~-FJ~Juv)y&k)QJLwP*_k<+(=y-9d_Qw;W^v}C%%zztGFN8) zn7JvlJaboOMP^lIb>_*;bD5ViuLaj<-pZbpU6{Q%yDWQs_V(<(*+;X_XWz(d$ZX1N zgR_F5Nzf|j5Yz-cgMLA6Fd`TW$4(9o4Gs^EhOy3lO2jwPs&co9-Wp3Seu(|)Iy9gg^hW(Jy-9D@TlBxthHlg4`X{|z|EzcDooGgXQNF&V_wYHT z75X={q`&J*y-!!^{rZ4Dh{p7=uGUBNQGHAw*C)`Qp31 zHcUE9K1@PPModafPE1lvR!mwW zcm*raH*AO56TPAuXaQiK&UOYkxnQ|J!d%v3$KKvfHoCEk*DU)L%g24Xch4}_P4n(_ za@m=O+2~BKZE7WAJeKQdQq%I7JTCu~=LuJ#HGfC`L%t{H_}E~1R-WU@8pFd{G8;TL z`4~p<`6bVL(IU_P23dIVb9MQ9~W$d!tpEhJv;&(eC4 z+K6)tY_gnKj0DdZ9Rn4{={RyD^PGVp_0qtf_ynAT91Xr>bvox;v-CJ=>Ra3#J?JXa z3DGq97kjkAKjL<_u$-^A5bmab!L8PNaU1I2aT{?4;?NuK!)>CgaGUD=xXttd+~)cq zZVP<~x1~Oe+gjJ+?(N++x{h#-ciZYKgu8gRoxV!AtGV)&LxY#6&DHLX-fItMrvopz zW`y@~&2dL?0^@X)8-hDV$KsCD18^tlWZW++BSY`MihGED4fh+IDLI|$uzc!aZaD5S zZUpW$HxhS-8-+X5?T33jdrYUZoze1YXPE!s_Q$=}jl;dhQ44%?0`4?-BJQ#9m2=bG z$+$DzDY!G;9Nby%RNUj-T-@W`JlxrEVoKI%Px@hFeYwYzM%(<2$CXCwyu#y4qkS&* zIMZmM%RJsR+URdR?lfBI?>zoA+Uf6o9ci@GD}6m_wAHJ8T~^1!Tpj1->R6Pk<7c@# z7U$|XKUc>ExjKHHtK-649ZP&2c7}Qp{Ad)ZLficXE0NKq3cdGY)+D1&6&mn=vN{=! zs?dcmVVyEcRiPFCk`>G7RfT?hDQlNetqM)~SFB=2yDD_%%UI8hf>mhGzh-4KI#yZV zs5z>)x34*>w~wzms<*GNIjXmxuQ{r>zppu}cYv=ss&}BTIjVP%uQ{rBu&>$bRd%=4 z%mucOA6#}uIFq^RyUbQ+F<+g{jAiqf%~v*;t)bO*_ZGvE--2}-dHp(;G33>x)nwJr z$qU$5l-VEDcW+ZpN1!)9^wx(4*hT{E7?rFLZLmplb|Qc$udXg%6vI3nO)`k)cs>Dg$reo zES3x8Lb*sTmP_PU@@u(5mdWqrO1WCDk?Z6J`7gOy{#$O7KgplvPWg-ckNj2sCV!Xv zE8s{z^U_o z@{wP|HtF~Dd-5^o@_gWsbNQdj7WR(U%68VJn`r%7G<8-F%6F!vHCSJ}(sHxb_oUsu zSX298*YAg|dH|<2gL1YhJ2@O)mU9o`RQBtfLmkE$)Hmf@oLe6&GdSfwUQUpcfHF-nU^C8)H=$8R^dg6M!E{3;k#0^LEh?*ML0hc;{pcVQ{8ehZ~gtIM(;U-$>e^Y1O!t z)aqN{bW`Gs(%VU&^x7#)$Qxr75_2XR-C_c5>I96%Mhtae4~@^L*maSzKu2}@x+Ig z=y5IF4|un#J$a0-*5}XY8_hjE;_`;qXrmuNi#MS=<7Kq0=r86CFh^S$Q+QME7ts_ykEMN6M|fvnc2og_*R)^ zd?G6uL*o_3(E~igc(yd&Vcx9u{^h*MMqJaxZ)LW4l-)wyKetfY=fX)^;v3HyKkT~S zST}}SD3|yiPinBVNc{)+;9pj^+7iFJ=V|zDXFhyi<#`hRSI(474svnh)tBG}PHjv! zjBodpZ!%{5U&%Mw)8)uTiSOmnWX0sN(C8|Or~1vX5LrqAidaEb<|Hu+r(H{+Zq|)qCuR)``UkIzPKy=Sf3znVS`sA zaNpsC>JIoW27QFR=p*1UXhA&ytA7L^^Q($WY4TDh2hoga2vx1jgh6xsqN8m9p%c5-TD>7kbB&S78wr1sqkG>{y6bkyxS28v7!7<0m;m$z z#sCKZmOdV^Gz*UfCIc1ou@7(R+R&Hb%uV)Y?aSf&%-{XspQg00pI!$nMP>#vHVx1e zmjD|W#|KFNHu=s2(!fY;1=qy>yF7aoS?4HZ4d`&lRM#(#=_T0QjucN=95 ztUaYb``C>)^KGZ;#+^#@NV{d($LGwcj5O~9ypaBn8<;)g9rOaPw(>{l^V3+ zJ?kFK7kd%Ta#sEw=FNcJ%d5!xL((e6+K9ei&3oOAbsXb)Sh&qi3pcwTqeZs;^j$rM z`KsVK?XA*->C1uiYc#em^C#ffGoO1#T7$bSep~ZXBbhh$B%CW>Nky<6-(YeKv+xaW zGN{Ugp#kCUsdK~axi*{|zD!ydz{(je0cvCLWeJ;qw%0>ZMU`L9q}Jox`R27!*oM83`#q!GWN`%Vh#wRqNpTAK}A7O3@8E;Bq-4=W=ZCR5wj@f zfLRoC&KLj%QPef;y6#r9#jfvE52pXU_j~t!Pn@pm>Z((x(y4P!{mOUHAYY27(kLZm z@6oH5VS|5mdy3)xp<_d%b%1|`5IEF=jXB)8p8#_|33ZFR>dmg;hmurBo+QaIc3qm%Yi2Q z@6&%Dt5}(m@tgcq?4zgwl;R+~n9!f;&yAU+p<#yCy2 zhBsqeL8++&wQ(iYiz=**oBWVRMcL3yZ8}4>qz$!kmI|Z2YvZO=6M9c=-0X)qPc^0Q z)~1{P5Vug6(^74^n(Am`QX8*B=}fxR#_Lk%CPQlD0%b4>GsdBd8=B0njnfd%t&Jg+C9fEyUcY82B^%Ks`}@3#SsHYyy=6&oId831I}440%H! z)d25NkYk+uJ`vvg$@!unM=a&{Q(nSTf8eZ(TlBfc6-mPZJ;vgF0g6_Kk(Kcxnth|G)O=|0X{f!zAdtMCg-t z@D~rGO2#aycEs9Jq3|{cQb`{hfDh7UGVX~G8w0UanM*RZ#vJ2-e=I;E>}Kg8EY&>QsRLx1I!IF zenv`3-&)rTz8YKS53wIxM@mkFv}6cFp#B7CA89iwYYa(yW92?Fjuy#FYU(NT*@g;$ zZzK-LRatel!8uZE!7+Ct@)lAb60hCzNZOTM=2Ywv#LbHdDK(ebga(8vR9~Ra{b(>gMRy8&n1hLp_6yL1$=W zXlk%GbTN1u@@=hc8`&;xWM!9YchIiD?v&kGyNh^?SCHMMFQ(los3u4c`fc{U4c zwzS#mRt=>uSn=j`ihH+N4hkqRbgNa zf}y^lp}_#Pwlg??t96lF>jAqXb|>u$ztvi&w$`R{t!YrJ7HXyCTInx;LcJ12eJO(9 zDVd8O9$)5=mx`#0EfiJW-T0xr4#b6u`p++y_jum>dHJ)rl0Qp|OCFTmDY;d0ujEq6 zj*{gii%PneI6r;=H2JCT(=Jc`d}>ylVzykBsN7$>w~qr_S@2r{zxC7>YA1CBw30%_ z0L4%ko?t~JsY?+DzX^&diZlpkl9d1Je@fbgo=PXv2ha}m zV7deCM9-jS(KG2DbOb$;9zu_zPd=5areFk`8a zFqf0*6FsNvKISTC_K&qL%DIF1@mjRx5>0oGdzNaZQiR9FF%sWfT^tb^&) zGHN-sh+0g|rshyfK!3`BFN$mhB6;GXj@!k(}`xtecDx%I)7pRNW73wN=iMmW(qpnkTsJqlH>Na(Qx=B5z zo>0ZqBkBS5koukaMEy#=qsplY>Lc|V^@e&&y{A4sMKPccy8rx>K@ujoTnQ-4!`fc}dpNwHJ0OR-y#uh^?Npx94) z(miP}+MV{Gd(km;EbXk=Lr(#DA^-c5MD*VO`j4he6cjLE?HL}C921h@8I?FLCS+op ze&JzJ$+6^1x9UHr>d$obpXOBcUy5p^lzuV626H7ohR29R1^!#9g0PLk5}xfm>Rg0i z!x$^_(z7mI3e-VDu^=e~$_6B5b6HM#!2B8r<2nMyEefRAbeI=QVKg>C&+md>E`V88 z1U*?ymBGAv4gL3ts-`KLr7dWI*3m6!d%6?tM*Gmdv_Bn8N73=HR;JUl>ACcLdLg}n zUPo`CchdXl6ZA#;27RA?PQRkx(Vu7u~9xyn4{UgcqBq4JvYjOb|1QiD1St6PPq+ z95m_5uP<|I?ZTxD)EkC^9774sV-u@uX(0^5*n!nS2Qvu>;pJD45Gj$xzO zI5vSzVJETE*qQ8HHiKQjE@4-&tJ(GJCUzUUlikA}V2`lJ+0*Pf_9A&T@=}OaF(>&7x(<0N`rjJcun7%Rn z!?fB=VOGb?#;loHTQe84o@V{chMPs2jWe5QHqC6l*%GrgW_e}@%}$zKFuP^;(CnGn zYqQ_YFlWM9aMoNC&YpAT`f&c-a4woltg9-Ax7P0j0= z*EiRj+nYO^_cZTsKG=Med5rl)^Lgeg%r}|uH9u-zWPZi`w)qqDa`QLlznj-ss4UDa z1PdDrTZ@(!4i;T3JT3ZJ1X=`JL|Pp0xv(?MgYt)<6 zdFp-Y0`+P21@(3HJ@pfHx%##GqxvuPKb9tzyrq?8151NtGt0J?PL?i~9+uvg11*PG zjr^&8)6LH5~AWFLPC?1!b85r+vhRDODdMkRzM z$Bu~!pAh;z>Jb*76cQR59+wpQE#@ib50jssz)46_nEdQ1a~Cc@d&*zKJh3UNY4P`RVnYy@>Bo$Y|f*!NC|fdVQ-Y z;#;iu=#Yd+`1Sr?DDr!>k4!sCe)joRCaNt&`*=r1_c3xBWeoZld5kg!eUhSL!os8E zr}uY?(chyoSB@QxL8q}13E|;!F(GkbQK5b1frycxedX?ok)Ot_?#95QFK`h9zy5N* zxY{RirX<9Viwy5C7m52`u!ECautP^*xjpgn(>F31=0-wtY)nXUQv8oEzQ$I?8w20O zn2^LsxsLenQ9n5$L4NwlH6?tn&&k*{r%wLz_eA+Av*6Uz81(Z0-W!SEqvWGQ`_9I| zc@T_F68r|ql#{;G?`Ry?j*iBRZpOepKyFvE{0#W9LCHV91Q?r@YzzWwr*2%H&q~zDHHOnt@y>iUhOgU<7qZ}no{1*96 zTy8E&_mUsq>iS`gkq@N5VR6ZMzVS=mBHAW~%Av7j?aL308dHqr9lvJ&PNKHJ4W+y(D}{B1vSv$e}!2NKCG*qnw{a9ooB-)N$bnQSo6!lEJ`*wG9nP3?H2w z6BC{!M?vVtgv5r$r^d;z} zb4HSk^dKTrB%zTe#EjgLOfq{U5*8l=IE zpL~ZQf#rd5RdZuBJb6Jt)K zfyV8fM1KC(OHTT6IvM4!Go;I68iJonfRHwJ9FfuRF)}`Ztg7U%?KSS~B;}{}CjZdh zg8TT|8nOOLi2-QKZ+C7IXHF=wXh;hFG0^fF<+PHDI075_PG~eES z{Ak=|jGt=v7!VmoX$$;*6}HerAY&6lWr-^@O!i>HdQ39uhuEk%ISe1493qR>q#Ekt)Vsg)th)g*wEeMmw=d}{JIzajrBPj>vJ~N=j@o25ET+(WYNi8uHDI9 zuFuK6ll(1AX4lDGrs?D%Q*rW;skpb7t95U0thNK;x>x63a(zy2wK{UIn_R%j zL$0Bty|H}`#`ZZF+vi|xUq`tMI(C#R>eyZ;*0Fuf3t6kDDm3D1(E&gMAx# zIR1}$4Q??p203%00Su4ugcML>zgAi6F*F!GhX0XD$^JivvZCsPKe!k8bAx1Wa5Q*S z)4?;F3x3vn;0LV%52!h<0nc6&x)t3XJl?M0#SEgyfd6|U`1R(}S@cT!8vR1i0(_w% z;9*~(*rPZP9=R&;!_`&VDm#P!Z6J8w#w({P=O~vd*C@9t4=7J6i)5eMbLAWGxK)G4 zjWO{vS!c4*@0REyMf)# z?q-j%MY3Jar- z^=|ch@W61E{+2o5TX|vmsZO0bzI7JVIaB9xU8=5A-N?FY>Yl0l&Prp|#>&NNsMR#9 zEmqg89$38>EQD5qw=h&l6&4A(!WQ9-@I-hkNcF7h>Fc$r*R$U6dgJS*)|+2%UA^t~ z4%fR@{v0KTW76Q8Qh$P_sd^M{`PZUGqfqTJx8+iM6?PU2DKtF5^OnjXc)?0swURHr?a z8a&}8`|3aqo`u`u9yl4Npf=bI%|>%j8{~#kP%>_ddf?f5UgM9_i&*tv$F5YpDDrNm z<8xDx;Q>l1=ckuRBcAayN~NKx{L2(SmHPSst-9N=kzG5*U$~}2c^&W>w%OsX$fES} zk+&OkyavrGO*xO#+N;#lpAJuv>~8dVJUx|Xk0MCHd<80Ck-7g3Y>h2_`eS;su57yM z(W-qrZ)zWG4|Ufk;8rYF4esx(=TQ^nqCvULb?l=0z~Bt&oyrb^ns=&S88lK_a!uql zj(20-Cr+EXDcK%vt$?~96FZ_sBmLVqmE4cDi$!U_+u4Q^{AEWj;q zv_XOnd7?R*#{PbeZAM=FtP{4`iTw1Z=-E>`r&1|3M7uQ4R;!R%N}pS}p%&|#*~2tx z|EmLPI!z=Kz@-?ie@Rc2UMcNG-mAt$gM65R)hUUi;!}vc;HJ)kIByX%r4FmNql|EdhL^jsayLL72U}y)S_;bC{ zi3k?g3EL2qw|vX;Ez26<>G0)+XI_5e-&Nz7#&$cRRccL}D~VBmIHbO0qTAQ?P&{Kx^m&6dWia$!X{ z+`aS1v#0_-MQU=h_YR`dDY1?=YY^GA99n&?) z@&4UE%Ytv&9O3rnxR ziuXISWManLLyk}Ay_INMr4rReF`7>dYKdc1e?X6PLh-87HOEgsvH9S830v!MLd~X1 zM)Eg78s^dV*ug<##`V$TUl_irNKcY>j~98EU-zNg{E#WqqF%@g^Qb=d4Ha=OWQw)O zPhVz&^{(%b4H6!GKq3+!HOB(Baczn9dOq_py7t&=;}g(_k2S*c zApeYvAbmzQDn!>*k85nZAr*V^T2|IMeO3l8#Mf2bq_&SirW{DqpdOzPhuWj|wos)D z?rOlMxIJ$F33I52{;3Hz_bx#!qHa7#JmPP3#1v+|yI^xYpF3O>j=GD&qnRQ)!wN?~ zhCIa<&izNVPSx>B^b0b8IA+dagX%4VW2H^1rVNg+*`%ssP;aTPpU8uR{HK&&FZESQ zBg-_{hY1;yo-tCNz6jlyl&S|cJ)BWT_IP1d)=_=dJbbT4q3R*^WqHZU8mXjB9r1i- zXr^zrziu`&{#^Loh^ttS#?{BxHJi%Oe5Np?IQ_D2F|*x&zgu3ADc@Y2B=RmI)@Nw) z)@|6aV|{8|?1a>~xQQEf=+wDKMIPltS2TM21~pix@0g=%F=*XYYZXw{$4_62UF#T^Y;g*)&t8I;~2#iL_$F3s1EU^?v^^>DsOrpTt3%6THT zDeH#pkX`X(WTQim+T)w7OI&|D9iLe&1*Sr_GN}9?CVOM%x-~Yao@*u6<3_F9VtcY# zY$6$8o>@zq9BMYffYrZs7je1zKgG*`Am!zAFG>%Ma9b;jue|(5zZ3Cgmj@DPf2nRb z6EHt^YP43JKkI<@@<@??AmY3V{`s~6K01iNknv4aTba+FVt1+3QzOQQ+Jx*%x&@mk zc0^9dkyWF$_cV56E|=-iRR{ct<%{np$eb&)d8qeY=(?%`SdO zvW#GS`JA()C!G0tDU;?;(nd~LzJX_Q(PEG{oy*Hu_3D&ODI4WK6#T^fZqK{uVQOyb zM)}Wb$yK!FY4=CPk6p`NJ?ZusDW1DNynbGoIb+A)y_aehEXvA1`D{MSFLRr#S(ma; z=mgGoM`q%JCqXH8K&vi=0E=>BkJv-V2*CqY}%QGO5-X3v~6 z&1Uw3nMba=>2mycVO`c_({wf^%0I4$F7{UN)pa(1-$db> zWg|9vuQ!-xj`tkvs++uTP;vSe(`)Cqrg~?i*xoX9N%3=- zle@MNMX+>einOhCda6~xn^nmyRkSUm7MQYVd9ROci%``_x-fuhx_mkzRWdoKrNYH-6F9g*hs`P26|=oYqTy2bio z6P<9wKJ?(F+4}a=RhU{)HVA38s9DJa)KD+A>VS#*d(T7ch@0C8FMMFMOVRXe$f?w7 zb;Y73sOY8e`S&8xuNb%2;(nf>U3lTtPhC(eP$Wt~5fL0uViQce2is00Ji1qCULB2a zbB`E|6^#ZX6{rf;bCu{{$zPMxcdh#xpX)fYKH?eF1oqT+p!j4=?lr|{npcCF%#=G* zuTHw?n*TOl@evaj@bC-)i?J?U&1Xn>#_NU#BB#{3ifZmR+1m;wpRCI zo$6hR{{yVk;<`NtwC{G@54A|tf112Iak$O!u(%!$0VkeL)j3UGWqZpRIe-N7 zg+meXQ^R%s!x`cDdFJw(Nl{VpsX@IHcATEA?>9%)dFh$pkJ=AM4qwy@cTc5m>Ah5^ zt`HWw{$zLfy8d8ztaPolJQlkC_ol~oSFk~+j}ms7aMvz;nsRAqCnK`8lx^zqD9az{LPE7n0AT0 zGEc;PKy#{(eDr(@T3Cwum4e-Xwm=8kpoJP_${=^V5L91K5Pi`S)vxOcFTJ(-qwh_a z;CNBZyDCOnZGze{6?u{V{ez>s>v2nl*PPs#7#oq4>XND#UbjmMjp{NzGcC;q6`jNO z%=oB`aoX%7xoaM*H+{9?)Xr-*_lE9w(g}}R4;k2Umj2>g)q^GZJI`s=soTUkyyn;K zNAI3pKW@kh-KE8@1|Z&udGz2irDcFY>GPT`2}mVJC@CuK5g2}xTu7sIpg({!c~*= z@@E~?UIIl!bAI5VkYhtHU#>sw=%|AO&R;xNaQOI<{+H_q4;vNY@8@?u`3t6MbORQ+!(V@)mK*ert5ukp=-I z4?dv!NOi*lE7s{N*Qij7VV`8Ut-+07pvIMt z9VAOz7Qd>oRCQy8+poloVS2O>9Z;#eZ&D4K96hR&)-mAJt6BOf;ytmvU___Ipy7hi z1lBMynUwA#+R~w>x{4@KpgaAj?53dL8)#T6WK^PhQnd!MRiNM{42r|SDn!A!FGJJ7 z^D$AC4IGTZ!&I{we%3R;6zM~%6>3x^>_d%EM@?XI^x)JPSqmrVgmE)FtAu^?HWAJ0 z&*Qg0=%v2xK>1q)9n-AxEozP0w0eaNxKS&65Pz*JTcZ~G45^*wO;O)wO#^zjY8iO* zw~yzqzSi^8RN2c`!f0(Lqcz<)TI1x=+BrjyVwcokIM_`e;W z*RRC%VPpVMLKzxQlwg!ssq7?Hq6CzO6DmO+#^Z4w8V|;Im&+w*3J0SYHx>tjAr{D@ zu_!`=9eT4VaT&2%V98OXPLbGOjRS;=HK<94nurRN$-X?W`-SfCuW^j)$OueL06lti z!VppT_nFAQ6syNtOQ&k!kCi6g)YLdhog^oQZ&Ct|3j3~Iuo?@M!;lG5-YNKfyX|*9)JhD$8|v?cX|)z<^VLH8M4HVdS?@`=o>zy z?^h_@#F~Z`Qp0x-TN+F8SHy?=e^k|T&x3^#r`evlcC8KScB%yNuXhKvUaxzxT!m~? zfzE(Z8o9qzE|dmnQ1_YvFQoyfdufe3!+)JHlgaX)0fw|F%>{)IyW?eRCiCDLL60l& zW8{I3mE&W`89l0~=}_~I;blW8Q#9Hin&_CEOX>RIvW39Y536S>A6i$>TFBIxO8=~VzZM(Pe3TzoKkT>#p0_M1vBkY?VF35vX-xq~e z6c}7FS>nO)`}YolwKIYV;MeD7FW9KRzzWj5l*#iaYNJxY?5M3gQ{>adGcQrm(nS@* zXK4hF#xlt5JyL+>>(Kr;+*gkydEDlWBWj|9?%%JeSb641iI&%VymsTSKYgw>Yv$u) zYq-|uBUvvnd#XV4L*Wul0dd0lvEA?%6|WP11LtOI4Y&?y3_d`O!`(P=5k5nT!F!00 z1T`P8sr-{iCmw1rA9DA-9!c$L7+BaQEV8-c4Fb&E&l5M$^JI6c?tu5Fvqpa&zh0lk z3hy4}9y$KR=GWfWc~}bQWiif@0$G0lYVRWLp)K1lF3(t=u|m&33{FAA@1g!rtX956 zZ=UmDaTg(js@50>mykPJK6y3Xi8razq3*h%>UuRrW_XkyPvbLK;Zu_d!G0b#&F=K( zGjB?rZo=HSB{|(v@<>AeYVba6!A1I#Xvl4(djOg+FqCm&$^|^%8=$Kh%a*6F z0b>&U7+fhMJjbD+G<=P7{8KB*y286kc#SsmrB-WDsN)Ox8bIVk<65!LcV4UVoESUE zUfXs6A57YKo_&H~aK3uf4m10C&8pKl{rc2_Ds?3>nH@GqfyekUssIleXuSNcuVQlt zfA;#NGewAn9gv;}z+#GO)PQnt0N`UlbJOWGAin|J4M=wYcmrM?0N!+_509XdhH@%VtbT~l3=?zK%#{&`^Ant$)r#I8oVG6+E^i~zX%>h?V z@3Mf~190#`AEN>43@C2^!~<3wz{-Fw2go>miUq(reZibuIaor`cNxH(0~i`G=m09G zAJgPQ8DCS*aL`~enwMgD5``4kUN~P(B&*3$*EF`eq#YJcfhv; zY#&h7G@=2255RrESp)nY@azCkr>pA%tQ~Ob3Z4dZJAnEX7Bm3d0iCa~Q~-`%VWp$$ zno*YI<_D#v0dWu40TgiKGl^0FzMO??4-^3N6^;~K3;_(j09L3XtJ&I7FGz3Ktq~Bfw<@MRyvY z|8N&U;YtIJ9ANo?6$i*T+&-no(Qvv12TOo7r$T7Bt)Os+o0k+^HGq2yR3-&ze}MPH z4NkZiKoIe8Sp#lPZlfrXqVyD{qX6O$*mH%)S-3kuE>TXQ;OYR}b$}}b)N~pyF2LOf zYBmk`7nCX`+!KIH18`3O!0Sr002(fO5|sNjm;-lUEFaNb=Hc~cKwp4~F!vQP4NO@IxQ+ZeU(1bIwG^uCe zW8!P#Z<1kBVp4AMO2w!+RX3HpYO-p&YL;r5YAqnYD^>4QpBYo84bzS3#SCGRm?Lac zwksgEOH5~*ZZmyq`rP!T=?7EEj50Gbt7~R33o~0~mJ2xQ6M&#DbXE zJnjH@mb=Q`<7vJRKa7t9MD$cXi_hU}%-fldF|RUzYcbqnzD1tJ19g2sBzIAV!THv8 zOEb$r%jK5qEDu_qw7g*Xu8v6^i#pbI+Sch+XLy}abt3B|)Y)Ixyl&gNJ?f6FyRU9Z z-7i)qR&}hLtvsy)t+K6FSZ%P%vpQ<^%<8Sc2n_@;Ay!BhrV3|;E5cpjw|Zvvy4Opt zH?`iJdRyuh*1J~kUcJ}#{?S-yY&0!2P8u&wkY*Ll% z*0-#mT31@XxBk=m-(S3bne@xdU$TGM^~>d7{;J=$zGwaH`nMWbH)zzrzrltEw;Mca z@YcrC#=*wT#@lAT%}$%+HkWK3+B~;;ueH#Q(eBY+)V^p{oKg3k$IyojXWA9H`>@}d!xIJ>o)doJfiV}#s!W4Z8ES) zXp_B74m2rjQe@Z6uCtxLU5s6pT|V5Gx^7ou_pa%RrUgy!HT}KWz-AMh{+v4 zoBiFqQS)xiM>UUczOwnY<_DTTZvM9U-!0TFY+E?B=+k0&i*YT|TC8nxq{a0X?^?EO z8P#%Q%cm`WYsI(Hwd&NWu(e0)`)x+HZQAx)yV31R?CtHx*q64a+IzLX<MD?bNVSzfNhL7I(_+bg5Hy=SH1VIu~`m=xpVz zakh1C;ym4XpYx+Gwq4@7q;?l-#M>HeVmMw+=JaGy3cT*?Vjbn z)qRh9f%{GOa`zAJe|v;@tnddBoz z-}6wrd}E^doM39AFmN!>0Z~o?s=8; zZq?hdw_EQEz3=ue>BIFg^oi*+q0fmvMSV*9yzKMEoA>VI?diSHyU6=DAB7L^GtFnI z&l;c2J{Np$`V{xI?wi^7c3-LAh<=y)oAw{pzo@_Do9g@A_qPGmfGq=#4!Abp*}w(^ z2MwG(aKB$0zdU~@|F!;~2gL`}3D5;N1b77a1xyOa2-py?FW_iEVZhyhKLQnjy1>?f z0f8BTCkBrg95Oh3aMa*EL)?a38uEJ(6T}6ngRFw=f?R?Ef@TKQ47DEGa%iWau0#EY zh7FxKbkWdL!<>fo8oy-#J*sw;CaCpMh+W!YgGSHM?+eLoEohe zJ!SN(P($dRuwTN~g>4GE9riK2W4KHB*zol5+u<+5UxvR4e?P`;%(yW##w-|fGr}yQ zPeeiFxhOtrVbtQNr_qM!tmuW&OQM%WuZ&(Dy)Jq~^rq;o(L17dMem8;AAKmg09}i| zi(JtHpF?%NJB(I&C$oPQ%*wiL%aMH{^ z+5!Dmt&P#ApUOIve%UlLGc)V#?LE&g#9Zp4o1dPUu6>jH^aiSKB23z;9}kM-|0a=e#beZ!kmpIOYQ2X*Dt?x0q| zS+iF~?KvpQMB6LycF-3uSJX6tBT@C!;ha^@Ysmno%sn_^iW?`Kbmr7Y*K+C_Wq(nP zbN7hq)ZC?<8k@&*YBVhKlhpYUeYjFes8UM&Cr#45=oga;uo*g5A2+UfSBXwBOEQ-% zvAL1?DE*2qo7wETtKFXVpYi(o&lp6Z)w`eX{g1M{h+C|q{NWWOQKm{bkYGf4CBF`UrX@wkF*^myV||4TjQ z`QEYao};6?>9IAV{?p)%~Kwul}_8uP1az4lG%Nf`L(axIx z@wiUCHVOu?r>OSZ#i{pp$d=F5ugUYLjb^o z)(qI1*Asl=J(Bx1P@|Q-ICW|>j-D;;RlbA4w*%WU1a8@d;v(7X?1ZvaOBv*XvsItK z^$?Cuq7YQ5%5KhL2RvVu#;6m|b?U)hqB`1$v3NY06OQJ7X2K2B(BmpP0^;j^Xu29&&$;R`>U_)I_qQr^Q9h znw6C`TQ}47S5f$FiL_nwpqU%1ZkD@SRM+rDF#EQ_fhBly>NONj!l`8moLU+Um|1{` zAnqJX`#~d`P1dC|&t?W+F=*wJOmGj66V)LdICV5qipD-#E6qmJHA4Ok=&H3y>`?PN zm_pfXn{{XRbMrJySmF9TPA9A-9i^9x8IcqDav!z2(-xWkey*r$gDx8%s{jhsCLOQ{ z4&?mTsR2bTw76dHHn@#mxGt#{YG$*|{e2wUjkxmp&w|TuUK9;zq*LQXDbOA2-q5Sb z)1RUHvJb$B0l|ye4o7_6AK9{a`7YgQG0=%q+hsnLej$@AQHi!#qk&Qc_>6mFuLQ5S z9!Wk8<}=CH;vSB_4JIHQmZN~02sp@Z=EbR7b{6S*(op3`0GBj{8P*=B;0}0(D*ZhR zF6&_Q3%Is^gXz@)O+fZ&x+=Rhpd!GtrM8b0)g9tQBCa~1Uo`{EY6Bh!9vv6g#)@fCCzjZ=$xgB6YGQgkAurvPn1vOhOf+XFy{sBC6h1+^atZ9noYrZ)+7Bk=c9_j&&xhH_xX;-+h zLMR35r!db7XI3$RQz8@Kbap44&I+aLHxehuMOJt=S9WqlPFMlnr&Bxf*A=hS{jUK| zLTMKeKy=LdS4S8@_ z9~%RQ^|2E-yh`s=JWhxZ;#|u2p`gr+ss;=Q?`utVvxDtO&RM& zPRDd*a5}bf->#c*IyU+TtQR!trC#`wc3E1Xxv+b0(YdI-1HYoM^g#7bd`XkU`UDV^ z)Sf+uc5S+-i<1^>(1g>IuHeLeDk%C8kI}?WT)$)Iy7k-h)=!9yoiHI*PkQ%YBM#XY zpbkfb5B6dpT69bt&4kWNNz@4+q9?W_U45z%x4Ar{067*+t`Lrpo=zb>eZ&>!`C-@b zQjpOhc`D71ypuvGD+6R%&Js~gVsnvsJC3{ogyW1I2fKHxYTFhZh-Vy+CbkwKVQzK6 zK#?Taq7wwOHum#u@n*QVt!!Y5l>ZD))=<`Q;bESr7xv;#Z*d*eHd!}0h`2zOulUK& zzmF3h263wnsTO2sW^2`91pTvZ+tWcQQmdy{IhDx&gpj|N(+g!-yx$R-rUI4xeWH+` z10@z@F3?UBiFPr!I8$d%3TO zFzk)qFBCy9*)HLM;vTZ`pc=FoM?S8FrL85xbs{GWhfQbgHcrS#4J8ZNCv|p#ShYb+ ztKF-17Qt?HQd%u7(G(3k-eEY_`y)N}PG?(lPVX#mj*y@@g@12zQ0wV3Q2&Z6 z#&XD|I>D9$%4B?Ae5`nz3pgqC$yRQ}iCcu#AT(_R;S|K?;i|D*W%aON!piZY^&(*N zE;kX6ltM`imjUNp4`6&7bCngS&jZw>f+*IV zWZ7Lq`gjo&xSb>L6}|Acd}5)y%hh_hS+zIzx%s&m+1^6d523G-KAKjI|fB8kz ztSqn_Z2n__roa*Rf4ZfOBc+Ck9Rirji??Y|F$zJmG9D0Bp^iv3^iz}P`m&u9PGM$L zYC}@A)3~-rxy`K9VV-C_Z|$nW%axQ4gA=)LU^)@Lwjo?G=PBx ze5&y7wY1l$eGN0JeW#6ihg1k9t2j8~-iw;bhhz*fAl9D&6XL}&)ZkcIg;0E`!9v!dfIpHpxGqpgI0*ZbWl@-Vw(Me>IQdgwKmYI7kNk z#rrydzxXS%kN8L`&_u;v7XMp&C8v5&R}u8gN79*Y+*5NBcFd3LSNUA~rLTCm1Ez~w0YCGf1#Z^zS<)EGiWwq7Zt+*k#c~osZ&q+N4NIlO< zJ)=lHqewji`iS|`TU!p95F4)icbJ*ZR>iN-gI7XHF&GWPJA)UjfPuGayk3D>_W)lA4Wz~HJLSQUI|TY+eJ2v5>b)lv;0 ziN4u6k+W;Pdh`V$fXt1ioezjL5iq+IM%b58g>8;X81N>btTVj?HL z@_4Bc7g>;BwdaUX)|N}FUf=-dum^Iy&ub5E>B)W7o64p^pLZ6YHsa@D9{Ae40% zr&f!{#1JNQK2fa7h>k=?Ty{R3ee+HvlM7d3$H!7ZDt#SJ}|H;tfG#q)o3yd=hAaCUcp)AXUSwxj{TpAuX>(p2I=~E}+v~Wda|NI*@j4*BwhWHF&p+Xq^XQ{3 z*D_P4e!WV$5G~gDvX^(MaI#zh>dT^5#j49JZq;3dHnzjJfWW=n6#90#av7SZ>BnBm zSK;V#l*3-mS6yNIN2|~gC;W;f9+#2m*AF6C$~#flmfR<(wFK#V!(ke-0DwbdSz4?| zlR&Q!Zpx>pvZUB!loY~xA}h>0%d$eaiMyhe*EpbgT+$CDGy!%zwY_*8ItHoQrASL& z8dV43WB@0WL~yI{2Ll%f{Q+Bk3E1`TRzh+N>@v@58W_0anYD#L6+c{g2z2p+LobB* zG$^|_ErLsv!j6HoO*?RygSoReEo#zrU#&Wj$T{HtL?iA{#rz{sW?qGmp9aLQrvdf+ zG$4O9?FzaaAPS`vXy#X;U`r9aPWIBx794mB+90|m2R@{Au(wtH27A@<->QVN8JzI1 zgiOe>^`QhVq&?_|uyOAM{qR_U4>t$7Yi^51a4nFkR+_x&x9N=t)aD@XfrQ%LV$hU- z2aWExSP`34+uDji;}RrR>?*$Z=!g#oMrzC;4hok^H;Fwv|2nZ}fkGLgWypUE!epRS z^jI9Sw>xI!Z#xmEsrqBY5mLjU3$+(hu)4ZlFd=`uNY*WYc0J_NMErFrctg^_!?slH zEZu6yL4331D7STcBQB@v73r;)Rl>6woL{vU^v@UQo@bppQ z^+gLH58lF|12Bzc1&kO2dEj>I3X{JHBi}d>uq*BX5G!lI!%In^fE8CTHI5xLHQoEN z;BI>fN7($MDkSRFsCfFL?oUzE)5zwjE9hiIE9wBauM#0H4b7jf`R(r6*W2}NcH9sA zs736xO90^#_N0NrWdvN>2NeD~M+RK3$;?@iow)!2m-Rdwg;GhxP z0_sK&6mjeF)&Lg}Qqq?EciLU5S5+v>&{BRmkV~nb$&bT7;;A37&)Lt4>HaX>w3~*~0sV z4VpGHK59Hzc*SW!92jibfHu{Fm&s`3-5!}Db-HD>y#h5lvA$f`9Smc-w)4UMzfYb5 zbil^j4Mi3%%3P!+4$g_h!XwN~mtJZrgTzS&aqoYBt!Qurv`r14Z==6%(Lg@DTp7%@ z+;FBhveSma$3Y-U=3YQi6*LLjxYwNR=3rf|~o3M(|U zYVip{S}1|nJ+Nl^a%RFnmGC+LBnJSxZ;&j&5gAcg>k3u-q~$08+6fzUvT+=q`NEyH zhrrB@<3hg7hVa2Rcj(asU20z=W?{QH89-fA^upTJ1%SLwU$HV{rB?O_>Q9S)FpG9` zXf)Z~a58lJ|G|6s4T{0O0X6(ux?Me@&NbGEaE_AzBy3;D7x_C zO@VJC!|;CgMt3u~%UelTTX5jf#G#TEx#yR99?t;fd2dG%bi~6|M~IL;0z$SQ2-&&P zAGHoexPt(qHqf2}4RLS9Qev$ysSu8Na>7JMQ8?BL+;^Cl{3nV~!(8c$3{q(X2o_Qi zFAW<2>Ef+o*jfuf>>h#JI{yLP!ELJK+Y--Spf);*X@~z|+eLd|PKV8^MOzUn2E`I8 zhSL9~-pSHbTT<^6>FRgqBUBs<4TSqyX)Vadfzp}BV$j}hL|DVOE|T^XH->O^|H29m z3)OXkNhME;pc0~!pG04fl}4BXjXT*&#B-$KO~k#8xyR)J0w&*((+ji!@7{$$s2%<|(qUF*Z;rH8xQl z*qD1nu31K;lG>fm=2i&Dr9h(j!A(fvNh=ZV8y?42tZ;huH{J0GR8lsTlP&7wpa&8a z5?WJ4{E&yMu7M-+T9vXNS5a-7Od58ZxFYvfY=`vi(7H4jxG8C*acMAgXVS(=DaoWW zKzBS`l~3GgyI}9>$MviBFgniU?T4s@Kns+{y%qC`3IML)d_pRQkjf{dcBWxZX#=R7 zrzoOxUgcyj-OjXW964`sL;`r(z%7pbP@)FS4wO?Dpx!QWsvSB>xYXM)gRyst=LEM2uHb{8^f2Xa;-f*}gLhz1 zEAYX8VlJT3>#nW6vHCh3cCGHS#(TZbWjwn6CkC|u4}J$`DE3P3mfCAV53t@RJWPF< ze8&_=qq0FVV--k1G}PENR34&r5l*VK*Pd!4VX$AUwfw0X`$E<5ZjGYGMb$x?%;E#p2@Ayz@|C#Khu_(cEi!w+6f z(S`V`TsK}F3U@r1)0Zlq`|owxqaU$8e8Ul&BL`3XaZ>jjk7jXWS9ds*6sFXORZ@NS z-p(R$8l60QENel&UL8W}M4OL{dW41*lf$~?XJgBRb?EL4z@ndi^ja_ME+1Wl#g#e$ z3I><0D>zYZ^Su9E{0siY-3_aCH9ab%ZtUH>(-n_)jvUf+XjETa-|kNspkTH$*l%Eb zsCPiKc0ZtkwV z_b!5sq9Tf5K|llx7VM2;152VbHL)NzuplZ$P*gxvL&)fy9 z$(#4{`@VnPH}2l)J9B5|%$esrr@O?p7d>MKRmV_a_2>~+zAK4*3y)kSG=&;|p2%Vf zT59`E|KzP-W zb!}Kuw3gdcfSXHiLsGrDo}`lk*N!xAdV)OVtvy20rG^?`WO(!X+f&|nWrzkX4QEaz z=ChZ`^SxJbU*lEU2MS$m2fwleRbRzRjw@(iP(@o*MVnMb+f+pxRn>`g;PfugpLUh5 zLqXNoFm*z;+>fT7KvVCbsr_i`6POzFp>z_Ypw`gZQu@^nn22~%W3)DfZqb;qYEv=(1t)nfiqb=6q7eef~et2xz<$V64WR)5NHc8Tb zB(mF^%fPq-=2h|&ZeK<%{%-q7e&l8jXK$m5 ztf3|Wz5I7&my`2tB~8^|K=trb7*q{iUD^3KiTSgr&m2~8paxzJk;w3Cd=fsS(0A$f z5D7N|k3>8|*stOEgDG;{8`WLwlgmKq0mFC$Lr6~ik?;S8Qwm4inS!s97!}s63vk`0S$j} zYv&ChNpwgO-r`21P-UNjSKSoH4L%3}Nf`_*BDuBFDm&RGmDpEiKg*9pG z>F>Et$!(}0J4H@bzP__GyUHR@!`CMyDL0>~WJ@>SgBkfS?Jc|60S`+-6g&N<=vZuA ziSl=oB%}}MWImk8)~TzvFck-)6Q8R}E-g1Vw_7oVU1DizH*YWzIVL^#()8QLkPZj$ z8^a)#%>Or*YyD7O!nMB0BC6;DBin?Ptj&X-m4fUCys^)PJVp2ESIbvu`nxmayXcy! zpix1am$%WdyO~)I(M+)2;NhY{%c9E4x`FoWDQEW5+;N6>^9N{T>-MuQIJ`lX0x*6h z+;g7w*voG6@?lR>y!tMRS0BT*QmpV>zfMVv?F@;yr+xerclE&awi4)}g7Nui89o-= zdDDbGADSlQUj7AdE*eY|qV5((UjxD08`CT%Pn${@#1=L810BIx5D3qLj=}*^JMBnk zI3-vKhQh1xjbbE%+I_Obui+G`(0<3X@FS*=#q_bBNgOZY@gFdl~}bSP&_T>{E!a*HBxcw`l*Iqt3YH4qG(YvA2@w z6i&Gr8pVCB|rI_YU z(UV8Chd_nb*==XTl$qxuQ<9D?pKD{cpzCr}mA=KU;Ji@`2SGOqTyF=?3a;&dy0&6@ zm3I&Psc+F5RHq?2Bnb{F>e@c!FgB@BLQt*7c{j!8CUI>WW2*`!qiM-Qs`OF$r_;0Q z`D2_rC2&Ad5S|wQQVAmC4DvPUKC&bE7T@{}%!{BaInPu%mlsX2UAlVWBF%(_t6e8- z_xt__Wz}9$*xu7|$J990dXk=$%>@4^mW?Kzs<o~0qg%Q3wGO~_F zq5W1cgvp&V>0L$0AMBOZPFg5`DMI;Wbs{{>U~W|rVte@S!SJ0B)83Jg0DOZ(1^y5w zj03sCiJYJY0HqMhBw`Wxa1*ToLa~Sze7Yb|32!x~YlupS`sz2*bnWZ_Cu@Q+Yb?A?hIB1uV_`b zLuo#~Ol`j8L=>CBu}W|V(uIfMykantClQuBkIo!0Z0xHO7aLiGMZ|gkml|_(=hsPNP0e2vW68B7)m}%0ML<7)$zKv8~i87>v=&FjXgIV{Yh$*?VDj(rFpd#|=!XPO)e3maSDR^nrm& z7&r&|pv2osZG*uWeHv5I?2-LyPtdwUAsG$XE~C0hM)YVMUH))I<_MV*WKqZ+@jKrd zjB-MWyd&m|?vMGP3)Z?Bb3z9vXoJu{JzD(hwh;s&e@Y@-NJQP*@eRSK%h(#4Gn@>q zsO?)UAwz#*Yx}-o-xcC6tquH@B|{ZwY76g5-u0!%Gtyx+%B+IRFP517!gBeT+KmQT zV$iRwC8l+|E2+zGO6x#+RlvmxNG#vsuK(+cHC2Y?C`}E*l_WPPJR(Uce_Apz?z%Ge zL`dSH!@j=3YI%OZJx2aCz{AtuMb&MFlZi%NZB$}!rkv&MIYm8wm`GleB}%^FIY(nY z#=#i#n_QdqbIg$d|D$T3a>mzvo$q>;{p#RY&Gp;yB}#eqwZ&)6197EvAOo=#v@QCT z_lDnJ`y4H+EMdRGeBHtH=Klq6MAywiDx4D|> z6K7!y-^>VKn!AZMVNeAetbo0=D-J=Y>Ce~Fz9=86z=q3fv`wG6=J07vV(P_QZ2EP+ z={v>PQ{mUJnyks^6O?C;A5QqNr)so4)zfa?B zw&6>1z0^Cz*kg-lV8@S7oi|gtboDyN^`8FP9`gx4;v1uSo_IbTdn|v?5(7JB62VT%M-cU+9U}ZG5+(nmvf<=Kp$ULMEKagjRR;kCZ`+G8kVB z!wTh<-rROhsJOk=C3d2UG`GQx=Q|CmYC2z;m0fV@%7fELN#VQM7l|U|_q``YI6Qp& z=sq}uQAg-TwvqFsBXJ=c$Y#)V0`~`bhr?3T**@YmGkSYkP!nIBdti;EJR%s0xWn0Z zi5R81ezub*J9~!R_(>Ci3?pMi*n~|znJw0e@0}P#3=a32Wn-?IxjrfdbfQa25TE3o zc4mRq7W^4?o${bXAw(5G^E~}4#b8hlt4c-|L&swIU*6n|S{nr}E($UT8@3I;L3*Fl za0YcNL(rCY8^W~*kuc4>Rl3Bx4}yywVCHk2p&Mb-Go0cxi9=r$hBs^e;F>Gs@4QR) zFd*1wn?hvB&1Gyv+K{$oqo5_|X59F7w`Sx%#(MkG`6j9nb8l8Zxs*_>!TJkN&a>Q& zjeLiV#I`H4pmm-A8`-lIW|l(NVj(x9lj76%eA-@3-aj`Fk(_N6$aB<%$vF^xF-uwL zaH*Y|%&J3cx-QQ}XcX9mc_<=DD5rn|P!k;DG0S<`T3c*ZH2hQsv)x0|^+Ayjh8Yl( zk9v?|c%WF9v?AN%ipwhlWHtCX1HMK*@O9r*p9Dnr9I-z>C2VXQ5gMe45 ziKyZ7b@Z`9)`ze2#i+sjxs!NaS9iNr7M|1F)ZIanG7yvKe5_EMPHu=~v$)0X(O{v! zpIiAYIMnu6oF*2`Wll2j+mqX+|DWx3V=%Sau+m46Q=@d-7CK0fq}t z;)s6B0M{Cq^KV^OR*+$g>fVZFF_;VH=bPdSsRy>E`7jg}p$*yPIo{xdjUz*eix_WJh%ExDFsv13 z)j`NQ-o-#G#N+2+47iZ_PhdV^LJYOlhPEPYI32)*n75TSuPruWs8}|QvI3pqOz^;AgsZ*XcUaYyQJ55 zLGVN#1?i-fLcYugzG6VV=T6o$WyP#ar2JA-%CEC=%IlZIk@9QSP)hmb@yxb>h!3@q z&k6t?W~4~IETBC@zW#pf#NNt5NtQ?erbYs=3oEB6r#mi00LRaYGw< zln-ge$ZWA4Q%wrset`*IJ|NUkTsWp)XFMK%&q5q+i>ogpb_M%yWgPvZ&F^gHYf6n& zQ_fQ(Am|mmgtXZ<<*{kcCfWVcx+u&>_%CGuRBbp|_%4?g1Vi%B4Olw=Pk45y?*D@qg5v zoGe&}hvV<@(lY{)(09mmacm9)y|Rd|2-<=N6VOFWOi3IugE)p_vD*<3WJMT{oDs2O z88Tx6Lghx`-M>io2Ekz6-G1gd70}9`=y}+T zY^UmFmGX4028`l~iO4t5FYthJzu!Lpy=pLtC&r=|!Re_lRBuzq5ay`nA!S-{>+yyl zc|^xfJxSXYnn{kyqAk9gy_H`6oBX}hvOnmI zrAU4W+ZTjJ&4?FRzFPs^MH^AuL3)T}x9G_L9#vgKweBP6q9DmtwcE*XF&S($0tLZN zk48dI4csKjirVdi-fb7l!pY$L+Ln3x$BWn9hoEW~RC~Wdb)nO;#ZGq00qOQIZ9cxC zYa`a!DIHuEk03fzGG4l=2YI4wd9v6Lh9JK{#+{n5A41n3)5r_YojM+SRaxnLg-nW8 zlQyBN!>%af&%{WSukP@%D6_nJU=H4*5Z+;<}MnEK4x zgmqb)^bnXcaBrmbZ4y$O}r9%DlRT`g@gUdm9ubvnHVKO zBY#v41f#Y8?j-n?oXKLzukc)9wInt>J0j-Rtw@(~<6P%V*3js;Wxci%t1*__3`n+|6_x9@ML>Bs#_V zCoOGgn6`etVT5bVxA*gAeQbxXZ6fixCP}T=vBc@Jf~VG!M;{@zWmOnE4TDV3S*U6t^gZ z6Qz=89iTt-d-f}ef1|qpLV8z7rW&_vH?0&`e{pj8@A$rn{fanSTmhy(6owWlMseR3 zk#9L$8!=g6dfFuZNb1S>ur_sHiDgUuN;&;v!QnEvfkj7EN=WCqNND0R!I>~x?c$13 zGDKw7WydxPO+a4wNoX6T2R+VbUwWzpol(hXS1`b&H~DU(x@t4?>w$#SSEzR!b`R|G zVd`6Um{#wICRA^VLSo~KKhis{mNaS{S59FUH)$MSpvG}4L)ss_Z^UaH&$63_po%dc zdR8>47`IauV+E=h-9A?_=JF~=cT_Q2L1o2z72|L_7gRBNqKc8{`Jf8MgA!CQt{LLP z9%)iA4u^EAU|g>xBN`NpPf@|R?gItmIB?T)pBVAnCl4I}WvY)9jOPm7B-1UdJS16K z4RQQqsKL&?MK#3zJEMkJklLsr77~GVqlUN{S{*hhh@&0~Gf_dzt*RuWxga|+Io$W` z@XQnWVW~K3BgB}FR}iPyG%AQoK2s2P=M}_CPd`upb!w_2-qoZcjyeskPDpOue5#UV zq4t)lh>IjtMXaM$5#QCSh)t6St5p%NUoCm2D!uq#Icz^~5U(8e*7W^AIh=*cVI&(u z3N2I)@1n|KTD(>{{JI)WP?FD&mBWudQw~qx;4!~JIXuXo4RdBMqH@@Net+znZIY}8 z3_~L7@m?d`Qw8G+v>M?nY}8#h3F>?4nDBEc=?N5K zdv29Vo_C<6pU)fTQlARRG~>4IwR7nPol98_Qz_=5FpEy5RYhbZKb7_jJ7$s*Tp4jQ zqD`Hg4hlb&vb0m_K2D`BIF;J+Q>k$ra54?$C({I+OlP%|sptF2^ljs0dO#;reClf) zp@zv+B%zZDM~F_QyV}Y0#Szj@riKxEfg|+6WXd|rW;IQw#v%E5GJQNGbTUof;EqGW zPo}0J8E)^=FeLnBq62bJLI-3>9!qDCKR<&S2BdKYH4X^Qpet}4!xkfbpBLEY4}{TgX)^2 zp7$MY6P>^|aw}*)T`af7ot-q_ZaHPBa^w{|=(f*4 z{XNr7ppCblJdof*xC3R~Z$}fqzZw=MQTf+RwB^i}h)8A9iOYG}Ve>5l)fI=3WX$nCQQ=9~+N|5$ zeGB(3*7O(2!o3PX5q~=#Puzn13e-D#^TKJ%lhuasjS7^HpMk*<&F}+Er**aydZ>oj zCf@VVfLT1T6#4G;+q+L0=)d0|>zzQQ)#Bjmm&;X8lP7jLq$%eqS^GaEN)`F4{|KVD zLNmefrpVXZ&&yl6*>8*g7PaiOAB?n5EWWCbVzzt*%GokSB60drd?k;8K39nhIebyg z8qiTpM&lOiCr0DwV5TF=+C5P7OIq1MKT(1?vyC|0gR@v3O=M5RxI@dtvbjrGnVDZP z^v;1^MfylnwYJ9MvHZ6oEcl3_^^Nq39M{;}$W*@Y`L%xd+@ZEbGy0h5MaVcQ?dzf}I9LLuqt>68-4+(~rtqe%Zb^ zP;GN;e5g^F;bY=vP$7B@tHX*h2wZqs-Nq&079Ve~DU5M}c*{er+ShkUQ z&5_8$oUrBC=qY7j#`7k-;+F6=Oi@4!)Gy@ZzXYMhP4bn7%xUCG7KjSNmrt@H(aAp|^7cqXk*bH9PtAE5?4L_m3qUn8Fz&$x&T$f0i2 zR$F;YM{8^|N9@wh62bSJhwvG4ym!TSW-QrD#*w3p&r>m8@ho9}LefPfCZn9$7O)?0 z>JBpjz3^B@7BX8!vXL$l*`!t2fF&#*y1Pr}cBa?kprK}C!XG5NVB!rH<95L`YZ{kX zjB$vuScx~A;NFhKpi1|xlBdw30pW`Q*Kck`_!>;_$j;RorSf$8`tT=j*u-&%TYo^v z{D3_c%aS^9RWvb^|0HT6ESF(%7b!RkQ3=oEgr_BNthTEW+n=nkVVz+41==Ju_mo~l zngs-D$t&RnSJ*^lzc_FeHTQI>^L@Y~3-mnBj|o1sKlCh`dk!Gq*|1|^9p04O+L%gw z#-q7sXEgUbirmc9gtC#F8Ou+)^;3#Ie4{m_{6R7ef)J?n$N8WY5_hdBx2Mzh`a3jO zoPpQjdni-hEq1*-CC5YS#fwaUKLx{LQ8`#rhlwnHL!<$g(7O5qQbhaON$n&!PlLIH zm69-j2~O8HTuLWNhe0@=xH5QAK!*HJ3v4>r)G}vj0{kK>VYOdc8q=hi2p6pJ!tvFn zEUE3&j>TZC?_5nvHS$bD=h~s|Xv#`=4;IdHDQoD%^_w1ScCD-<>xBk(kKInXaTX8t z&pm((4+dAs6VA1!l-M_XOOaGzm*|XjoKd8m9-=eN$R5VYXU$4Gm7ACUE_aRA$PN{A zF}Y}DcK|82#k2kF{TD5Mu2mWWDQ;My;nS1;_^l5GGB$jjjNhiE*0mDX zpnb&yI5S90S60ycL0tz#bhs>`YpgSuf`&`_oh4aG`b*+NYK|qypY}k*rMOzg6T>&M zakVWc^9ibo^%oa!t=WqD22AkVSUS)&V|69=>Hsu2!qBJwbgXIUTS|c_>>&Xqm(l(KO_3e2NGxt^vLI zv;ne-2Z?k z4-~{oVR#=eD@j`|^ZG5^^v=LdMT(dxCNQwBA2}tSx}2FRPCkWNHF%8ldQ{zto0v1C zHZ+DpjxivP)9c52QInMBkoN?4P>8J(u4ea>X^& zg60k{ViNd;t76eQx^UqJIe_!+$>KhT>waKOAw?+_7_!`*23S-hqdX=+R21C`F|q(r zQD>;b3gpx4cp4p6U@UG8m>uz%n49QwzfYB5*)^PR!wZ8cvfNMLoT8hlynHzu!|k~$ zVdO98)4H#vG!#u_xPaRL-kQr!dEx%;B|*0>-98u$Oq|qS5?FJaT5_b<$nP&_ZEC-5 z@>$`{`>Y5)sg~EHU5B$@nNhjKh+lBG*T~)AC2o?|BI;&9NP3VSZwZ5L2Dou45_wcz zOCv>{uC*99?NZSBCF>qYHFTd2rwBy+M6%7t{n$D9p8VgqVR%4l+DcFc=ty@8Q*TOv z44Q-dW?|~WhLy~4;}#a_BN_65gqX*uhyOn#M5dM)`}-t~28ri-Tiy_3Z(tbiM7;6E zCB}ExE^11lZBY(32=^S*wrq3|>oC8qq&+TRE;nGjma~&HKzaQJ9wo-}l%2z11m2Rh zoCYn4%Oku{pyCZIevM}39|39GA{uORg+7vg?m;+MBk$*45f2GNlZ2IxoW5tN^MEw! z9b|dnk_Lp>Mh%Y;Yv2f#wZ-vBVZnk<+`fJ=78(1^&}L!;U6$OQ$PXiFD>8$>0Ru5e za`In*aC|Zq_Y_Ed@w+1|(FNfvCQVw15+9Yt`fwXMN!D~_aSc6JbDVCQ#~#Vw zjz?hs4({q%38vV=-7=;ra1q56xLY%_OEF26lq9=%=l#rc{wt4+K11l`3i2XV~IYO+L2w;L2|F0v!@xa@Syoe@;}j= z!`B5PL4UJ){)W}77b_86`UftFe{Pf@)#$O{Lznhz;G4ZUC7`eTz|(^a%e_rysB<-! zQHY}WhL2qe`7N>001=<#VRXtY|NClt$kL0D;0~M2Mo8!{@qEYy%aP{Pc9~47} z1M|TorGn`mm^7IMGruxUw~UI7yGtl^`+r9yj>3UrWXXL=LzR{8f$U3cl-8C3#at&& z*hzw)ah#>GWMpRvjvllu*;+%5af5LWH0PFK{$g=~)`=7f#U!0dQ1r|4T2ViC67Mnu zWg(b>E?xc$ry=AJ-AH$CE=H~+>vH{bk3f1KBvp7}$sm4O_gZ>Ii9?L>S&j3NMTgHT z&z=f@8K$lvv(dV2j5(1bB%4$|f_!n#$>^Y+n@43a-?jc7#8Hs~91=X5E9tw|^DU9Gr zSzB((WHFgw6*fBNU}Et3qiyPhV%bPk#e7|YK;<#_!RHZzz;2>12?+=Q_}0?2?MC(etxWFzv#}Mboai-^ZDy~v(F_{*P$d8D@rjkT(`UPm?&=bE zZ?k3qD%SK56pcj-FxgZ;upfOFwmsB`!UuTXE(Fw!M3Ytz=;6Cn>0M(e?;s{uNjZb& z&N+~+Alo{Nm(20=nXN&A?gvIT7MnUb3uKjo#QU%j5k!93iXpQuqTi%}c!eenzvlq@ zDv&)$2FZ&_>Evr0N3V6R8azzLSJt&e*{^H`bL3?F!9-PM)S@Zl=PWkX$Sl0e!0r}& zSE_%oYVZpPdMN+x4NO%W_YDeCLYGUqZ_C5x3_q-{!VCYe*U!iz9aY580^KI{BMwhZ z;5+D8P=EujYjm+oPmB4z)>DJ2ZiR|_F^eZ!Ep_hE*XeTd)yr32X=MFS=Vyg)dbgLt zpExT8tQ1|k=pS%iLt2vNW@L~TG17Y}+7H7s5VrIUe4|%dH&KjRMkyHHhM}b>|5`ji z0EI;j8e?xpzWPD8Qy<=$li2StPb8dsBqlajS!I<%`R%Q22CIF|&(F#A(DOreM89>j z?I$SZZwF*dhQVssp$j^pbDU>5FX`LI`Ruhzr(*H42OI6CTOPh-hPC7Babq1%+`1Ni zwn8JDfYr09Fr!reST&N;?5;xO>eo=ESnI!Oqmp!SHt#ZQc1)?KddPabfjpKy5m*%r z$wU}LUvTJMfNg1KVu}|^!qVAqeol{hbeKX{yO}FSI-gBX55M%RCVtkm8IF!UC~y_8 z%Nvoa`8-B+Mk6K^;0N}?mb`K09GjybSQdOAIu^+{a0SH*-wmFATU5@o_aAZ56ecI+ zhSV4zG;klaaDuhf^eCq*%M$gHhqqvvPaI$ zSJ}5uM#QM)Yg})pugy>$I_kgch(;buBJV3UE?cs7j>>F7RMO=mQE?|U5mwhGr8(%y z69<8t!u!ZLUy_0~2b_0kkgNIe?H!|gCk zi_}ZuesLEZL&&%QF;Vc%SrGm4o7y&kLF5TDo2W?#?Cm%Nv?~#dcKr&|7KHOLsS+;^ zQ#in7nCW91-qKl|C?x=*$v(ThciD0xDGnqe#?l~NiHkkDa z`8uaokfVR`!60yuS0NzgYs$^c#P6E%S;t}GwWN6tgcQQ59Q~imSL2;KQsVDdqy(Kka~;7<88c!N zmFJEePd#|V4^d}X;sE#c{_|Dc=h#iaHO(|-))eKuMe7{ZlgFfru7t0jrtVV1;e7c-RCR-B$h84T7EX)c5oLP)NDP0{LdgqoRQ z-`H$iveXu#PZO`rc2F+xSYwTE4+5vgiG70)`9!N;#$LTcaZ@&NH4mwSx6We(TAU>U1X}naass~EbL&=xvT#l+y5dk%R~(@+%1be) z?vzKmm>#08IOMa|mCwxRc+mfu0b-z*1@vWz?zTx&4V5FVOo6Uz)aaLEjib_u_sbDq zLj7{=@0&6PT5sf076JxW+ah%E1&(+1D;~_wM}mje+{hvlEjkvyGyI$qHG#fAs$oVJ z)%wmAZH?M;E?Rm0WNbn1sre>>>e9nZwb$%2Vt_hWE2}=U_Rrntg8e*Z{A1D1^#SWQ zC|CQe*|thOKqOn?2aZ;08Mk4kyFR$q$UQg@Xs1Xcrs4}340>hjCW5cPo(bqKM&Aaz z8DA0U1-qGUs8?%6?3r#8;XBa!DDPs>k4?P*t&0U&HNqoE z2sI}e&k~_E!$5)h<(lVUaG1LG>ayP6qL0eZHlYml%N=78HQ>9?Z~uNJDw!$vp~nT% zNmOw-3Aef@S0{FFaQWpqkk>D_?lX+ETCJHjH&Nuf#c#_NZ-4L2O4;vQ(wDfwhV;ql zF!uIlcm1Pz&_DM`9`wtThmQgyY{}!4ThE`_r1b4;ZPTmgEo=10gLl^1ATNq)T z(zl;B;*lm@*LG!8O3LYo#H*)WZETh=oT0&caFT;uJTq2A-by(ge)a0<#b~j$$W|ja z*MTC~s36^l`vEWb2{xlY$hs6f>_c;^(e~IFNPZ++7}*$bZ@d+bqqoBDrH!}3?h5|u zRptU+=#A|KdSg2u?&6Itnsqkb*e=8y+q92vY(2Eu(2=K)_R5wtT-lO6+-}eyig=$e zl9ITP04@;P3nE~h5HGZYkZEA%CCLYg0Mk3ND>atzpZO&$Im#VQ5>V!>cp-G) z@?0foPj;fci2TPMb?79AEiBoS%BXb`J?ixp!QC+5%;xlwWXd6BcsY3x{6dlNN=p+Z}L zn^Y~{%99(1BxLyxG$H?9lD9v}8GUrzx{wTO-5GJE`vi-*;#D~+dV&z_& z>!hj3wK<9<(mI(!ex3KsvD9~&O74a7FZ$-lF-ty&(8EIg6M}94dv%=|< zc)ZCQ&h=5fd3QMe)E!Q8lRKQ9=nkily2H8Fw?ibx9Ff(0#u`l-{{xo@fUlVSF zLLNW)Dl5M@xyhl?#pwUw(I~#J)}@i$y{}>257;eOJ-RH!Zn@aE$zusdYCEPb5P4qF zH1?g4jBbr{jk;|(!@F(ZzDM8(-c_L+4%)LaVh35t@KdtjKnBdn5W<++VL_4)2MW#R zJ0(H?TLM^~E`;S=r^_r^3fV|>9DnboATka5-k}pzcb9}Lp+%vIX|n#_G^=bdOPBwa z%dHJ%$p(%j3*O`kcjJ759-=d6s7t!RBkkI5B_h3C(H;<9d|iECFPS9cOR^kG`Tf#w zSV+dqbm)~n^A1X)Lm*25%`Tt6b!l1nq(BXdn=ca%goY+4Z_bJ7(S44~l$oI`6E>-- z7&^&o`C?}jL#;2(1ECrQ=@uMWx!iS`$E1nNjz)wX2`!{TXjk3j5ckFNm#m*PbLpYz z@MFQrcvf18HCM-iezN}l+hCGom4@e&fsnORLhMF-)JJfE_K{h#;P*6P&;~2)#pPx< zB(UKGOV*C$$Nd*~G#^FCir_Fy=I;NX|Mt`F8~I7^t)-oZReaKSk7?JzT5Z?ii}#}y90Ag)pf#kH*zh+{0sur7U=`yeU5jjyTi zfMH6KSqYiq3ZI9*`RW^{xr0gvWZW_!NTG$9?ZBU}`)uuKVXZR~B$5J%v$lL_{J=ba zdK-V!0sg~OBy%WaiYguk_#>PCv_a+rjBi;QAORO&xnpDHFC7(tWm={f4>TV%&9sew ze!#;DC1egInc`vo1N=?Z)AP+A7*|``7$B&W)*abD8&y{Dmpin{7T}(qSODR9!j6(S zWX$nJ9(%JwlIZ3QHjNP<3%eGWP&1mF`6)Cf=)IH9$cTiX+;QLl~*Qply|Q>}V=s`Ium8HY|q<*V+TTs_xu z;W~TGXln%0Cl!lIgFT$*xUL*yv^+Xvoo37yrv0&u86a$^e#ITIDZ=|d16p@AQuq|Y z@;n6gca(&qGN^Omo2)zI;m9B{8vPt&@LJ`yH=r9(1+ktgUN*zm*HMEmqoy`=b+at! zmhy8pi1;oWkOz)M(4KbL9xzpmSP+%CTw}hL85o;72Xs`>JoVb6^66JQ*v;L9Mi20f zIQ4ns3=iJ2^ZcNaz3xSta1!q>yoV9AnXv7oJ&eF|>-q%2o^$Tq+w9YjzgSCaw zHc$Q+b{6VTuPBhiX15ab&!;@jIkwm$NS*r=^K{Fc3<}%tG_@0&6ZJ2fir#Q#=_%FE z#zhV?v|VhC9@^d|fx&r2ZupuRGgrC}GoBZ9=|ar82ii)xHI2XM$8yM`KZn?GYZQoY zy_Oshkf3ST!;-YwOw@Yic$)t%2?65Ge$~sWlQz6W%`(9NOV9k3Z*rTWY59m-ntm6Q zdGdE59Z@Cf49#?bO}bK$v?ylyLAs>A3rRZ^5uT#Vn-Nct63Wie%vWt4xj1bDU044K z8NOkm3!2dU0P75eA=#y6^c0jw%B&jkZ*Kf+g>Sn-43_8*j_)q*L5MlC*< z>a8~SX8IktI*~HqtCM~~)8Kx_$;jF+wwySyPxiv{>MPO7XsB90inN}sm@xn3)%Y{f zrA6l#&32mSf*kn#;I*P6!R0h)&R1%lej@{V+$qkJU&pZn0T-+2Z#RM%Xyo^kh`|-3 z$Bz=rz(9?$U|?U;PfZ?@UlmBqlV%MsUGY?~=%~%9eJA!DLkHdwVw9XOD{h2LMOLT# zNxjzEOq;$o`nCZWUSlqhzn+g3VS-B{`a@xIPQ6Y%Jp-=w)^V=} zW2|yIr;8;mhvo9R4(yM_TQPE>{g{m!lfBF@M^j3nrRr^(Q$ItCd8FA&&A`Ah%IjiRo}8%tai+M4)Yn(iO51ts z+~WV`pXst|<1ef_F~M}jLQB+h73-MoWu6^LPQ%3mnkCLMpR(9>@DT!0D~iU*|D+_IpD@ z(!{U_jxi6&5s`dNmWWJmoeb6@AAh_GvGMm|{4XW@pXL`VFl$(2#$&mjxWXhNL)SuB zD1X<1-BXvSxO?(!T*A^&6Q{Xe8`o+qLl|(!DFcP$L|q2>p*hnx;zMB=BhOSILDZCGf)7_C%i@~g~zVFwm0>y{`6PO?E>EwNED zLRk%xe?du47HipiuiAVYleuwi_*hl11yfKJyi=4GoOGs4^&opuFAW(}q8Q||V6OA| zg{2jt5ee58A2;Wx1y~{})_APMiIaj0RzYltzapEHju(?=9j233-sC$yL(x89Z-c>a zFZ6uTTz+OlS2V0FFcSO1i8#R;y0qYX<_ymAKXI7r{?aAvbX-^>W6F7eB*rIS+v8Z)_tQOZKiiZomMNm+mAM> zbN4fo_lGYiQq@GHfLh}tn&RfLV6e(?T-1|l)G3IedFfQrPeW#IR8*XgxqNY6^6Z&g@-&Ss#4UrB`4wfboDBWqmJ)S2VJnH!*Vn+`w5R_l)rcW} zK8C2Ktwa(#U`s)*C#xNfO1p8j0wMl0T=8z}E;09x(_?mt>)vrvrXjlM%dy;QJYEpB zF<}jfa;UGrfq%aL^CD%5-+iBQwZ90ILxCL*YGXYanodL@O#WC=grrVZw;HilYC~X$ zg3{mLz&HQ7Z;`6xzF$B&j`mQZ98Oqc+_m_+Ut!B?=V8mxncurQDVj=i@9MC5B0jdZ zP0^QQ>)bhs0@SE8z6Z)mJ%5ppq2G`Z%2ED3Q5f^}#al7LmJ@Yp8|*T4LdRVdzIVwe zJ0huFzni815ov9%;9PC4@Ek#3a_Rt3`-7VP&ll7!I{JXxk3J~*PmEL(^$w!;!#4{5 zhaW9E1~fb>`A;9BMxEe*Kh=UAf2xH$5bQxB(1Yt}h=8+rNTi<;1V71Hf}eN>i{Rhj z?AmTrZmCt#EuOwXv=I2eaQ&uPtdg^ zBL9Y>z5P%$H5^1nkp5sy`eNu{=tYL<$&70w1rfDHLN151M#q6@EWcfZz53{Egj_9h3y`kyq#5WrLIb2t>rklHA#kp&*+6IrqmWE^} zUe5{9v)id~_E@&u(-}L&^U|`g*+;R6iwJu=atS-*sB_rzOYVBIX|)ptS8HR1+_Y(m zU80L6xi>1)^zh2E>LIl$SB@yb7ogeX8SR#+w~BsWY<-Og5NjS(Z7^l;!8sp8tGxBoUubhu~%9 ziL1pwt6rS9GVEnJw)=RE6^o6+MIDzu^_!x6pt56@$*CLuaBIM0zidn-@1XR!^3|l6k~L;d0sa z+@k22jt0?-qFm$V&zir`b^gMHSq72O5$9qqMLS0e=t#$S zgN5^57tD9kllc{JEwYQt#%1e+sF0K7+$*!ll)tKN-kMYSipPy(&@Z!uYXJwucQToP zx^{Je;@UxI%vmQl63HuG?0g%L`x9Oa>$L0F9|Zu3LGm<^K=YbMe}EvbppE?1wz1oZ za7S0YGVVKsQ=#{!SecWIn<*m;WF$d$6|b*kb=zfiPW=DTzf2j1Ez zBJ=kh-zVO@kDI;k>b~54Y5VllA@l27H1}&EEs|7Ai*~nYQN6oG%RddiLD4r=u9HN4 z3rf%{qC%$)x<@qAnV@5>W3S_aUKH1$hs7P}AMyx#LJUVIl$Ugp(2Hc5KrOICzk@r` z=ip&Mh#(T(N~Q`51m%K9f)|3{n&~u~+sw0>U$Z^U4m68umeDMyS$VTZ&3Tdn)E?mI@8 zX~h^YYNiX*n;FK8W+pJ!j5D)P#hxuOHZWNTF*r< zR4-4js5#qwW^>Qxr<*4?=Oo?G7onZRN#ZZLB)KnnE&W!ilp0B$rC!qG(u>k!>CY{M zEtD;~wJ>jC(ZZ_5lorcc__R3DBB8~N7TGOITfA(+wWw<;ZK-J4sb$}mLt2h&Y2R{5 z%S|nRXt}dxaLeeHu`O@4yxa0o%V#ZLxBLq+-cs3DGFH|@)>k$}W-7Cm&5|vWt(9$- z1;~PAp|Tj+71>Q$wyacE-Go8Za$cqENzs>*PB*0;*mp~G$!w(O?SQt!lhInK9XO%U zdkgfSJegSIDXjyUgDz4jvmjpk9(PBSH*UsF4sCfCsaowoS~#Cn>-t;@ zV>UPVKJgb(zr0#nam?4`e#h(H*c`5dyA(}C@86U1o`R(&lB2A&pQM4|SK1c=omysh zQv?knHDX*3Ryvs7FOilDIUAU-809(^?Vc325B>lqr4pJyOqtpDsQUh4yq$6zT1KzB zO$Ok))SvWyMnt&3S=~WuP>JR`*<&u2Zua%|*{t?n&Mb6yUNu}rT2H(G2k0eLp*P|i zwmpM2m1toqcOOVnBdwIQuZG(sW*FFS5L2|h5qh+FB*n`m-p_-SC)kuWIosta9|fMZ z_qI!8a! zHOqYoXWkmb+)H%PA(B!6C&f%MM0v8vOp4bYQc5z0UdLyLqwT2_Aus~u7m{vn^0^@8 z;Yxv6{TeS+UZvfvDwr8hzB#7pacK34^UCvQPo&;HyWH%sx-yt~>}H!xS|H1W)l|bV zaZd2n8qMo7PZ|V% z3i4gnU{E|wxmFmg-qlZJywry1s--5I=P#M7w7NDQtrARA;~wPAj_s|MA`iLNb+<5$ zm1;dXOro9~=&$6t>2FD-3p|*`o7~o}Q7#PiIR8DC#3D{eDYc-ksI`3kQZ4Fm8|zX~ z5bMo0(yd7w7)iG@`KgvR@RCVy=>K#ZhNaHTkZSqKKK3XlWdgb(9g>u?LPk~NTaE6A z(%hsCzP_cdJa@ZysiPa`REi{9`>Q!=wR}l#Yx&`emzjlesqT3y82Kx%NPP>|-kFo2 z$-T?$wm@j&9498qadNO30(H=|Lyz<`IX2;fgT{0e^8Yr z2F`I*67l$ESG}(oWzlm5rVaa?ZeD3taRw!EcK$>xj zL(|S6cg|?WR}2TZ9*Wo~FSk$)@h01u^>Qdc3BdZq5)`YM!qRe(b#%&5>$c{1T4 z9Iml=g10xfu(+|g*{=&`rF5!bNpI47yhRVSuhFHMrEYpPESReyQWx~k*v*(^Kfi4| zyXf?5XRpH7R1X%U`#joZve~p{#>Uf5=cUHPJVTG#Xlt{QrB!*|fk9YR_3ob_g`&wi z-eji~lm03)(G;y@#uE3phA0pYC@V+psC+;o@`?z?%xdRJ3m#LgcpSfA^qBd!RNny% zi+5V|#;)P!hTDFaMVpmzoTUvqZ0EY5ldr=j!9$LYE+)|i&{71$(7|F4kr|2cH1Zg| z!Klp^k!Sh30{1c_h%rFxqv0gR&B)Wl(-0#zl&!n#QD%w}T|_Vx{WGEkQxQZTEexqT zT+jx4`-Y^p*$K9hg|mSh6X(pek|gR{2tm;B^Am(bq0jGFB8)fgE?#|%q#XD1mvsY-6eN}O7AL-p%#JPz%WNa{tBfj)&4+ds$Zrp~X>Ywo zMD-96i9j2r=c07vw?GWAgp(nn`ej|qQ3`SZ=|(PAo=G`#=fq9SUkrm%p-++EZVjZ@ z2oJz!MLOA>&ysbM5HipjsUujFQwBlDRFSMbdx}LFLih5$U!jd5EoR0|!yOVZi`GUnums)6K z3hSk(E^W|E+{73iOJ4jy^&mC6EW7?=M3bFK4PQ4Jd7angIN)D3)#;Vkcc zqmkR(caIoih%Wye^jhH-0mvitZE4ah~X=o4$T^J0Fqrx)XA{Yo_XEMA?oWwQ%}`39d;+cO$Q( zQjD9d0DsZ-YxFV#r7U(BvDrv$^_XGt{w1O*yy<%wsO^Rre2ER54?P~H4^QO^RjSOti4cJr> z%z>&V=ntA<_HKaw%q903DTTWQ@`QZao#10qJ}IQOhE-x%&$VCzI->%daQd!jjQq^y|BXnJ$(_>p`dJ${WBaL1J_VRhNi)?KP|i8L?6GU>o9* z_Df?9;-+>X)J)RoV}|!<@kNF|DQW3%+Kcp7a?Fk_(UYV&F)|ou1nI{kVt$7w8|S?Fy3w5F5>j+-l0~FlXCAE zsT(>K5TH{5VWUTZCyo9Bq?PDD| zxe;WH_L~e{5AJPpOyRX<*&-=*P{P+RZkd9wK?)Bb7)c`Qb$ZfU3na{tDtg~uz3A6_ z5(S~_f{!#A{15?{8*}58j>cFeqx~}!k0{m4Q_I~ zBi#{l#3xksb8Olp4JYp}mb#_msKlZ_9Vzodlm$i%gorYU5hHDUMWl*9SQ(P3N}>Ds zXGFj2)G57@pibIoQE?_>>jjmxR)Gxdg{?=Tn>`sBq#`pq<3?veOr+X9ApS0ihmq0` z9U(~fy-*-Svw$EQCq+%pMZUOPkV^0Ab7QMwsW_~N>egYN3p}d5k zmQv7p?{1x_8x=eez&Bhi?|x0%p9vNHRh#uWjd_*$A1#HJLp2uoS6{Dv=07oX%xN869UT)LQyrZyIz4HMfB#qi z@ZYD^rmRoE7Npew`uF+jPh*OR`i#F%@uishKfe_E{}NW8){y%fY|lOI_xe2g+4$5D z-}F)cwCO8Nb>PD%?f3d~7+(H9y#8fFc*AGIQ}z24pMR?l`#g+>)PInxsa!s+{%QTs ze2R~1!5nYuU)2BElr|efN}8UuIa5B&*BD2`KL4wK@Ojujht&U}jc@$?ICcH&#^*1` zH^zScS^xI)u=gP!{)+nh@5BH7w@=$s|L)6q|1SK?ssAqY{af{Ey?>YEzYni}^>LoY zn(8ZQc+=A-C)%&skH@~@Yv_E~P-stZn})T%F@60rtpB6kMLX`Fw*_~t z4_4Uv8f^*nRrIsIx;~5ld`|z>5n%|fw~c?a4*FMriT}4@WIr1JmVAQ$!9VqR^;iF? z*!r@6iv4n2{mc5Q`a-&cHumrPbabE6zA@T*wQCHGZ%kVcjj3rL)&J7;gzGH!V@W-~ zD>a5{KkHv<`@Z4dBurUIV?G=ad}?^d>r42!#$M;2Ft+I(ps}C+)j#<(G5;w<+v}gEdOt#68nI7P zf9d&?_KH7Gqb>P^aLEVXKl}Q=MW01|5b#N@AH;nAwf?Wq!~Q-*Tk=1T@`t$_+uQj0 zVcf^x-_PZSv99|#{^O^{^8WdkHm1UNqCr0RxD@Tv`#Jrk*uM+==bHa6S7Z2>)``Zr z|NgW7UH$cc%B4Lo{OeI`HY9?cyM~$@MeEF?hp&JC_fMxMTFUzo`S)f1FH`>0d-1=l zmoFPnZ~yx5ze)Q^q4*n{P{xSA{)A^$w>YwA;o&MpD-}r|oZ@#AYAxu9lM_1M0}ZqEgK_)$yNszl7gz2q8cSha3R{B;gJqhgM(!8BMmw*6_=`ud~7I zYo1Ch<)3&>S^L0>6J*2o|Dbn$9EJ*P%3A>FJN=Zm$@?6z%dk6bQW+GJ;8sq67u9|n z(Ysh&m1jg^Z15fp+Om?~=a)*&Z4lgzAd!j>DOE`o(oaN5TC-X&o0N~%Kf5Lum1j1c zIkrrgs&f<{fld;WAK+ZYX=rCjZ6S3Isi{=R%v84VM!W*eH+Z0Pgt8x_`6e!hEsPC4 z=qff|UAQ+WOE^+3Nci2FqPp zA*#%*s#aW<+BjCl$7aeYSG5h%I0EeuF-eI_k#|u~5oDFas-_@yr-)8HQI&vaWBW@~ zhFH3O`d~_F6$x);6$L?dd>nQMNT;u~7Od2;Er7mb5B32(un_7_y+#sB&-w*|r0kQb zhuf65-j=6_@$V0$47{VQr^ESa?~N+*W2fJ6fBQCVFC(Q)=uy5NVow4JC0d`4fl}?E zFtU(YdJB4%9Z_Z-;j1tx`GEuPyC1lN8aAKGM>VYULx8o|zeaUGfv)L&2wh%evTE%J zRgTE)G;vgaL@W8`gsXX_jK^VTI?b3 zc}pQbil`Vn-n%Hn?gd}(AhYv{?sE?SMl2ZB%aS_&?%=)Z?Us?-z0j8}A~i&FP+YuX zxils<*LgDDr*%9ZSw7D;Pe7$$EFCsFuV&VU_OK(=a%GI)AuX1bO}Z*y083wbUja+6 z=r}%;@%bwiZ%cG2)m>8V(xbU(-SArgd&)=4ddF(%0BtCR_&taWNqwr^M<6wS*atX) z&J)cCJ7YC6)E|H5h*J3)ZB#?WqPe6$zMiT26{s}Anh%FByVCSf$yX``HD|6_dh1!! zS#)fxTcJ(6@B5lShO|hVZ^n9N?XlWSwFBWaE03iW#L&NTQ*iG0%Ol_J&wfs7DuT)$ z^VdAJPBgEebRGJyO8dxKVprEngzS9>{`hqqU;zM%-*}EqiMSMh=y?K{o9KVg$HWT6p z&q-UWgWX>?`4H=)niYyc?KSF!w2=<#tq*eQrI)0p?Jn=LvwR_SEVqW? z?nu`}vFN8Fxv>BGkM5Tu>3nG?a!kI!7GIxqN$clQqfi0`mYpC!2(XiiuCWYf*OzdL z_3s9D;tabH_AO}HxJh^w=iHT`xLoW7dwk0C{)JQRGTRb(S!7%6TosMQ?%Ea>aK0S2 z{o|V~KWcGASPOE_^waBhxtyXFKZ0dLv8d~qcezNny!S1Ez?O83Z<~8;Q($a3c zt}oFo6~^Uz9LmQ18!gKVHg{jctm8LOMt8x_iZE$|z|d8`7-_gwME-kHYpGUHXYmH}$%BPvMa z+o&LjrPfgTNU@)0RM@W!JA)r*U8)+Q*opqXA0HFq%h@3vA2?T5q0eiL(9(2pW?@&w zZ!IRXvosGIy;={l6zy|XmN|;0ZaLhVnl_fDjjUDmR(=Dl4j=ir4(qX`Ve|M{a)P-V z#AIcpWQ~uV^c9LavDk~OAyHXoOm8P(H^nW+3R^1NAAOIB65N8|mZ%8df`;E20%Dik zLh4B~w0?vwEXD27Ntu%6&M!LN?Qxn2&boP+x1I&6TB|gDDCOJ`e%TpH zNX&VY9g$K%U|YtF#p?7~wLGhHjP@MdKFGHj^8$RlVB6I&1s_qJ6qsrgcD*f-<<(S+ zmn}t@GV@q|O0;VF^1;%31x_+#M0}M}8rOt>o0yrOnq%AWxk54jnuQRZ#{aHSZzn&} zZ)WcHOVx@PaIO8OM9aff6*%uUxWB;3t={9dT`k#?l1i~2#!D1d?^fj7QM+r&jji_| zU}T3UT>I{S1sLWE^r`qET6>u4MhoXBZA4>T=kOxv79?VA~|9Bor zMSLQkNR9XmK7$(bbe>L4_&0npHN|gk{*GGkrF=D&@U?s`m76ltjVeqJ(}Q~8S1~Hk zZW%dT&gH06!4*`SJ8%cI+mSm`OYX#-s5N)y&Qzbfa2IOGUAZfjayRZq&A1X{VjUCf zn2Ir`!IZ;8cnBqUC=W&a2tESwVHhjxSdEUgu8y@WMtLFS@*JK+NxqCP!{{&P%PEhq z;43i0xjYx6zml({R(us-MfLb<%%n(XatLNpMzu`2DW^uJ!c>rJI+zZWZ#tTe)ZBD3 zov6fgHl3-^bTM71f$3_xQXA6^^KYv2mtPI($}Ts+$Xak~_<{>panVe1QAcr6sJLjO zxM-)iC{kQBQe0FhE?O!sjN-y5E*dK?aupXjii=#uMULXaC@vB_nnz={vU>Ft7q$2z zz6dMvJFHuK#fzhOIYjZ2uXw4ecxkP8X{&f?pm-_9@2g%z<%*paik+llr>SD6wqmD1 zvC~SiQ>xghuh?m**a2+-JIxh49ZXNtlS+W2CODVDCQjeu{SLo?&eS->dP^e_=0*8M%Wp@|1yzUVYCKx-A~7D zpyi$h*9rH2Eg=O@#T~|2{K^Yxgt}8Bs-z^or*B4e@l{kgb-_upF5Wzp4acv+$T!lA zJH&c4kor>_^pjsB=b%+_P0&NS>r97Xq?KB3;j)DWKe&PAB% zdZ2zh-vv&}ft4~Cu*SPP8 z*@zsei9@L;iL-EVh_3jJqOM`aP&!HDz2S?iNONPfG`n|9T6Qn$m6k*J1?B^NYSYR1 z)ue8?_d9_O2^#Ag+*Ie%QNUe0s!wfEQiyi|mEt#Vt9B!pP*UAHG8{PI(90YAKo}`BADIdxif9R~`H(AN-UHC$A0tl%JNo`jDxtT-p_Kq6zli%(oME zoe0y6f!bE$VgC>&p1b#W)Uw3H&YTO$?bnMWO{L0y8EdxJN*Z6%HNiZZ0FDCr-A_^5 z1G2P_#s*?s2$h;FiO^!yCUGOt|^#0ebQ7@ zq<&NNOVn?N!t>1W(*>sEOljwWnP*L#Vn)n7chU?qdFITn-ApC?O4A#DcQXKf4>NS; z`4eXX=KL8m&GECO?r75tKl9g^atj2iiq67#%bit}!U zOaa!CL&4h!6U`t65t?;jsPvU6@Zrq@Kg`_*IV*6>!cgIyRepJLnctq-9n_l@w(s}T zJ4l}tgj0g>f*^d}4|4_wVE~siBS_B;+HLKp4gNY;$AcMb*e@g0e$8qhj(7NB&W%AB z)Xy31r*p>#;WK`i80m+mUl48%)4Ax+@NVPiNOH|)vnw$)aZ+Ncj6>x;tLDbou_QIpdzQ3P09jp#9ihJNG7S~7 zK?-E8eSl5w1FW+Tux^#G?5@WD<6w6)Lz?C_<(}}1U^QTOo%t(q{S}BkiEt&tC2;HE zB=0@A<#6lZ?uG-MxOc*Vp51wH?~rjHbRUMl3HbUqt){iK4!DE#1DwblKYk11wE=ae zyWM@r-7c$@Hyi0EaoTUeEx82e#@0wbj&vKG8{6W%*dBEW?aYAl>AIe@<}QUBCna!g z1DK;x_eOV$<~2|#$Y!?|+#{OTA%H8TggX`Q0L^U}Q zTG9ml%)$x1h#PV-H{!-X01jvp{KbH#yGGl($&RTL$Ip$aP9n-{cO3 zXca&_PI-<=f0MqPX+y>t54+8E{Cn&xH}H-82mB|PKl07|C+sn|;(x;2#<%kw_|GtZ z#(r}bpwENVsSMVI3Rqw|!t&A?HiWLQAk;K(2KKU9JQFQdqNO>oBU}#K$z0e>u7a)P z8rVqg=D+YgydY~?7I?JOl-j~F(U%AC;XHzW!pHJ){4*ZKC%~#P4%Uo`uwqQfI>IdT zCX;-aD$N<@Ommhw+ni&jnsd!GGu_NM*m>w_1bRBvj5DX1@n(XVi2t@T*_>{s9PB*E zn6v5hnyyX1ky~#z%hm(&dmnNT2 zu1Ky*u1UU^{Lr~C`H4H*o#S5b-tOM#K7#+g^Q!xfyD7OXxg)t7l;t=DPLb2pDRJ64 z9i2+2w=)0~JHk2M8SRV(WuNIhP}< znc~iXOxlx|msgzEIunKfn+2VrWBu=ZE(HP6&8zthev{wgHT*WTskQiTNbmA{{64Se4ZM**;1BWN zkv8$iyqUK^&-#=<axzvn&d;jqcj$Py;U zrkCk$`an}Y%=9z;%>Xmd3^Ip9ZysWXnj_3Gb0p-=Hm+qBrQp40 zv=>q916e6`?{q4ZDzqxpD)cH8D>N%qD|9QAE3_-rEA%TAEHo@sEOacCEVL}t{66Sd zC|PJ(s9ES)C|YP*s9NY+C|hV-sQU}>*EU_-FTrKob$x}_h1!MQh2n+gh3bXwh4O{= zh5Cj5!2!wx!Ue(y!U@6)!VSU?!V$s~!WF_7dEg7-44*fIGlVyUJA^-kLxe|!ON38^ zQ-oK9TZCVPV}xgfYlLrvbA)$3pm_dV7ot2eC)*rXM4HXXoFKcyEv~19Nt;#pD(@{r~Y_A$(@JT=tLi{D>Z_4 z1ZpgDbLcf%NpI6Ti049U{ssLH{=?gEG}VpXq%|m6C+%P_nSypi_(+Rr2Q7)+%V1t( zQE-NVUMH_POZ{`S>|}Ea%A~H0oE1t&lZW>L`X$Y#Uqj{w5)t{ep}+URIk`Wq@`vMx z+mC=H_9$3CZNG&5{94p)+)}q6c7p=!3?Dl8J5M>khKwH%i9g&K z<@CTVGEe$O&3kkPIX+IX0yCibL63lzb{({m0zf5#vN=fS>0MeGa`SO-0h=stEc&3G z{@fo}7{r4B4W7px7`UEl>5Y$rdyuhc?=&8d`>jblnd<6@>p>5?OLRhLn)nraXodH} zZy|BIk{?984L<=tkDq~Go1cZBk2??pz41Bt1^hhxy8HtCLVgi`J$?y(eO?Z~0ly5t zA+LwuQvG7yfOv`ejd&yCt<-PKA0XaZeEPS622ZQS=Td{&b6X>~18Yqo;_Xd6_`Puh zW4N#B4!=JSfIo;2hd-Q0z(0zyGMN3b@Q>l+;QtJFN`^-nSU&j#(+mEorZ@a?rVsoH zrZ4=7<}moD1I0oDWJpzt>bo>hphE2+D;C%&0Dpt9B7^Mw7nc?pSNk7InY9H z*LHKDjozVc=RhmHQ`^shcKT=SBL`aQeC;O(+Ui}}m-I0w?BlYqkITb8t_b^>8}@N! z*vD02A6JKcTod+jt@a^zsMmoW1tYo8c7KnZNbr&iz4v^5 zZdoP51&~$0gtVFsdG%{ZERka(uSAxu!>BXQ7QMi~v3(l+`cqiOz^}rs!mBEiXX0Fu z<$O@nvrRS~0kgSStq-+e8*yOAsLBda3=4H**btjSQZ$3*u{Uh#{a`;Fgd2yUxU(3J zJB*`oZ*e?s!$#rm@Fe_K&apI(#^Y{uGEJc~@gF*;(lnYu=UM4W7ozXq!csT~|F?54 zT}9W>b@>0CH_{*JPc)Bir#opr-AxN($n-WdX}D} z7w9E=nO*^wUx!uT4SEZBUQ6%N`?P^RppWQd+Crbw=kx`ANng=7^eyego$~kO;U+o3 zxtxStk+Y@?30xa9OCr?<^ORehmN@%%CAp{U4Vz70yxlPCen=0%+a0qX1Y6Hwygh-1 zp}18UhPM~6F&s5U;Ozsf%tXBl=^kKWA-#%uzK&5ogmJ!wxva&zgxk0o z52J5%58J`N;$Puk2VTS%(|5R+zm#_2?064-k9}zoM!z1KI(84#Z-J4P!1~%6BNuCZ zJB+&wduj#j`W<1b?u^@-uAyy8ZVr28rQBn1EBjO2L!E#-sFUdw+*_YU6L8CYI-Nmh z(K&Q3O{bq@K6Wp@i2j#;N0-uNbOl{WSJSohd%A)CKsV9NbPL^z|HXO-{h98G(FeH7B?ClC)7d3p#jGuFjNV-cn&EQh^zTFP^r*y@m7) zq>ll2E=C%EqiymL-i!Q?;f{m5mpMHlbo( zNsU1=<@_1yd2sK;$=6V?d3*R%$blyy1(ti;`ANhVQhA~hu*l~f3SX{uN|9cGZ=nXF z-lzD^>T$IFcW)~{?d|60ydBW#iluMutEOQmz<-3XS$Ijm9;FkFF_*T~*oJ~9nL`*( zLV9N`ZOeg6GX(j+rn;sfU<9u+=lu)?=ZcS@zO<{j*$G^11KzP-g3Bty>&OBA>&lw) zr}&+f#rPt2D{T3T@s;IPaL{7>(%4qem7h+^y6c)O#<#9py$#T#DJfXL}g;>*CN|T^} zX!be62Vq)h^=q{6p?&a%(CxtrmB&E;RfWQPywux~5eh#FucU_+7~c-8iSTC)ojDcw z8<*x-7~~DYSFW@1edH|E9e{doQ_~#O=MK=g?m`=Hp}&{m-c{EKr`AgFsOA}bF~WaC z8;0rycrR1DA+^Kzs`)sPmO`&7g?8-l8suLHxZB{0;QGPN09Xyb zMcLa}uYW);x`?Aq^E%pH_a{9C7MAnRb)Le>M$ z;A8+gug&M9fBd#1zXp2Pf>Si^*RXfig%u}>apm)R>|4VB;Bzw^=@=hE`!1$!`1*V& zcu;UP5cE9|?Z|w#P;-+Dd=G(anTtLxKkTA1%Lm}!Ldb$v8sZx&oO+757`)dOeAOKB zMmSwwO^2|9)5{0A1z%1@iPzBASJ(rNz}N?({VCpNGuc~fu7<|he9u}w1>=pC^G|`t zBLP1gW9p6h9f5EN!WzOE(O2eCON1>YOhA?$RCfveB;mV<5sDiTxJd}bEfSZT^gMBh zmnJUpz7NN6iT6J8TER&@X^Y@01E+Nnm+(B*L!pXdkE8_ts)Xfx&RsZKj70cXxK3~< J1P+0H{ttnaWAXq1 literal 0 HcmV?d00001 diff --git a/app/frontend/src/fonts/DegularDisplay-Semibold.otf b/app/frontend/src/fonts/DegularDisplay-Semibold.otf new file mode 100644 index 0000000000000000000000000000000000000000..b042f5123dfe01dc3e2342b8a10e22e79ae718c5 GIT binary patch literal 78648 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�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%0D%ST-=$_W$82i=ehT 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 literal 0 HcmV?d00001 diff --git a/app/frontend/src/fonts/DegularText-Medium.otf b/app/frontend/src/fonts/DegularText-Medium.otf new file mode 100644 index 0000000000000000000000000000000000000000..24e2600b2b2b177ab69879c74f455bb751f45f31 GIT binary patch literal 77788 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 literal 0 HcmV?d00001 diff --git a/app/frontend/src/fonts/DegularText-MediumItalic.otf b/app/frontend/src/fonts/DegularText-MediumItalic.otf new file mode 100644 index 0000000000000000000000000000000000000000..63dfe26d850a33ecb41812143db82773144208cd GIT binary patch literal 80944 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 b&cmdAp!g#Q?Er&}XBee2jPjI*VLtx@5Fkc~ literal 0 HcmV?d00001 diff --git a/app/frontend/src/fonts/RMMono-Regular.otf b/app/frontend/src/fonts/RMMono-Regular.otf new file mode 100644 index 0000000000000000000000000000000000000000..0e9d50789bc707b63230cdb4e69d260a906c8ab5 GIT binary patch literal 43512 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 , -) +); diff --git a/app/frontend/src/pages/ChatUIPage.tsx b/app/frontend/src/pages/ChatUIPage.tsx index 755fbef6..db807d33 100644 --- a/app/frontend/src/pages/ChatUIPage.tsx +++ b/app/frontend/src/pages/ChatUIPage.tsx @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC import ChatComponent from "../components/ChatComponent"; const ChatUI = () => { diff --git a/app/frontend/src/pages/HomePage.tsx b/app/frontend/src/pages/HomePage.tsx index 46dead37..f1e1bdcf 100644 --- a/app/frontend/src/pages/HomePage.tsx +++ b/app/frontend/src/pages/HomePage.tsx @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC import StepperDemo from "../components/SelectionSteps"; const HomePage = () => { @@ -8,7 +10,7 @@ const HomePage = () => { className="absolute pointer-events-none inset-0 flex items-center justify-center dark:bg-black bg-white" style={{ maskImage: - "radial-gradient(ellipse at center, transparent 20%, black 100%)", + "radial-gradient(ellipse at center, transparent 45%, black 100%)", }} >

diff --git a/app/frontend/src/pages/ModelsDeployed.tsx b/app/frontend/src/pages/ModelsDeployed.tsx index 62bec58c..85f9a58b 100644 --- a/app/frontend/src/pages/ModelsDeployed.tsx +++ b/app/frontend/src/pages/ModelsDeployed.tsx @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC import { ModelsDeployedTable } from "../components/ModelsDeployedTable"; const ModelsDeployed = () => { @@ -8,10 +10,10 @@ const ModelsDeployed = () => { className="absolute pointer-events-none inset-0 flex items-center justify-center dark:bg-black bg-white" style={{ maskImage: - "radial-gradient(ellipse at center, transparent 20%, black 100%)", + "radial-gradient(ellipse at center, transparent 65%, black 100%)", }} >
-
+
diff --git a/app/frontend/src/providers/RefreshContext.tsx b/app/frontend/src/providers/RefreshContext.tsx new file mode 100644 index 00000000..cbf28d01 --- /dev/null +++ b/app/frontend/src/providers/RefreshContext.tsx @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC +import { createContext, useContext, useState, ReactNode } from "react"; + +interface RefreshContextType { + refreshTrigger: number; + triggerRefresh: () => void; +} + +const RefreshContext = createContext(undefined); + +export const RefreshProvider = ({ children }: { children: ReactNode }) => { + const [refreshTrigger, setRefreshTrigger] = useState(0); + + // + 1 to trigger a refresh + const triggerRefresh = () => { + setRefreshTrigger((prev) => prev + 1); + }; + + return ( + + {children} + + ); +}; + +export const useRefresh = () => { + console.log("useRefresh called"); + const context = useContext(RefreshContext); + if (!context) { + throw new Error("useRefresh must be used within a RefreshProvider"); + } + return context; +}; diff --git a/app/frontend/src/providers/ThemeProvider.tsx b/app/frontend/src/providers/ThemeProvider.tsx index c51d00e1..33924579 100644 --- a/app/frontend/src/providers/ThemeProvider.tsx +++ b/app/frontend/src/providers/ThemeProvider.tsx @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC import { createContext, useContext, useEffect, useState } from "react"; type Theme = "dark" | "light" | "system"; @@ -27,7 +29,7 @@ export function ThemeProvider({ ...props }: ThemeProviderProps) { const [theme, setTheme] = useState( - () => (localStorage.getItem(storageKey) as Theme) || defaultTheme + () => (localStorage.getItem(storageKey) as Theme) || defaultTheme, ); useEffect(() => { diff --git a/app/frontend/src/routes/index.tsx b/app/frontend/src/routes/index.tsx index d2c16ec5..e63fbae2 100644 --- a/app/frontend/src/routes/index.tsx +++ b/app/frontend/src/routes/index.tsx @@ -1,19 +1,25 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC +import React from "react"; import { BrowserRouter as Router, Routes, Route } from "react-router-dom"; import HomePage from "../pages/HomePage"; import ModelsDeployed from "../pages/ModelsDeployed"; import NavBar from "../components/NavBar"; import ChatUI from "../pages/ChatUIPage"; +import { RefreshProvider } from "../providers/RefreshContext"; const AppRouter = () => { return ( - - - - } /> - } /> - } /> - - + + + + + } /> + } /> + } /> + + + ); }; diff --git a/app/frontend/src/theme/commonThemeClasses.tsx b/app/frontend/src/theme/commonThemeClasses.tsx index 211b997d..720edd72 100644 --- a/app/frontend/src/theme/commonThemeClasses.tsx +++ b/app/frontend/src/theme/commonThemeClasses.tsx @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC import { useMemo } from "react"; import { useTheme } from "../providers/ThemeProvider"; diff --git a/app/frontend/tailwind.config.js b/app/frontend/tailwind.config.js index da1ddca9..9ecc0a69 100644 --- a/app/frontend/tailwind.config.js +++ b/app/frontend/tailwind.config.js @@ -1,10 +1,10 @@ -const { fontFamily } = require("tailwindcss/defaultTheme"); -const svgToDataUri = require("mini-svg-data-uri"); +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC -const colors = require("tailwindcss/colors"); -const { - default: flattenColorPalette, -} = require("tailwindcss/lib/util/flattenColorPalette"); +// import { fontFamily } from "tailwindcss/defaultTheme"; +import svgToDataUri from "mini-svg-data-uri"; +import flattenColorPalette from "tailwindcss/lib/util/flattenColorPalette"; +// import colors from "tailwindcss/colors"; /** @type {import('tailwindcss').Config} */ export default { @@ -38,6 +38,67 @@ export default { DEFAULT: "hsl(var(--secondary))", foreground: "hsl(var(--secondary-foreground))", }, + TT: { + purple: { + DEFAULT: "#BCB3F7", // Primary Purple + accent: "#7C68FA", // Tens Purple + tint1: "#D0C6FF", // Purple Tint 1 (+) + tint2: "#E2DEFC", // Purple Tint 2 (++) + shade: "#4B456E", // Purple Shade (-) + }, + red: { + DEFAULT: "#FF9E8A", // Primary Red + accent: "#FA512E", // Red Accent + tint1: "#EAB1A5", // Red Tint 1 (+) + tint2: "#F4D8D2", // Red Tint 2 (++) + shade: "#BD2914", // Red Shade (-) + }, + blue: { + DEFAULT: "#7584E6", // Primary Blue + accent: "#5164E0", // Blue Accent + tint1: "#9CABF2", // Blue Tint 1 (+) + tint2: "#CCD2F9", // Blue Tint 2 (++) + shade: "#252C5B", // Blue Shade (-) + }, + yellow: { + DEFAULT: "#F6BC42", // Primary Yellow + accent: "#C2A261", // Yellow Accent + tint1: "#F9D08E", // Yellow Tint 1 (+) + tint2: "#F5E2BA", // Yellow Tint 2 (++) + shade: "#B87039", // Yellow Shade (-) + }, + teal: { + DEFAULT: "#74C5DF", // Primary Teal + accent: "#3E87DE", // Teal Accent + tint1: "#90DBF0", // Teal Tint 1 (+) + tint2: "#C7F1FF", // Teal Tint 2 (++) + shade: "#0D4D62", // Teal Shade (-) + }, + green: { + DEFAULT: "#6FABA0", // Primary Green + accent: "#608C84", // Green Accent + tint1: "#92C9BF", // Green Tint 1 (+) + tint2: "#C7EFE8", // Green Tint 2 (++) + shade: "#103525", // Green Shade (-) + }, + sand: { + DEFAULT: "#CDC2A6", // Primary Sand + accent: "#A2987A", // Sand Accent + tint1: "#E5D7B5", // Sand Tint 1 (+) + tint2: "#EEEAE0", // Sand Tint 2 (++) + shade: "#3A3433", // Sand Shade (-) + }, + slate: { + DEFAULT: "#737999", // Primary Slate + accent: "#606891", // Slate Accent + tint1: "#97DDBD", // Slate Tint 1 (+) + tint2: "#EDEFF9", // Slate Tint 2 (++) + shade: "#10163G", // Slate Shade (-) + }, + black: "#202020", // Black + white: "#FFFFFF", // White + }, + // Other color schemes destructive: { DEFAULT: "hsl(var(--destructive))", foreground: "hsl(var(--destructive-foreground))", @@ -65,9 +126,9 @@ export default { sm: "calc(var(--radius) - 4px)", }, fontFamily: { - sans: ["var(--font-sans)", ...fontFamily.sans], - mono: ["Roboto Mono", "monospace"], - tt_a_mono: ["Akkurat-Mono", "Akkurat-Mono"], + degularDisplay: ["Degular Display"], + degularText: ["Degular Text"], + rmMono: ["RM Mono"], }, keyframes: { "accordion-down": { @@ -94,30 +155,34 @@ export default { { "bg-grid": (value) => ({ backgroundImage: `url("${svgToDataUri( - `` + ``, )}")`, }), "bg-grid-small": (value) => ({ backgroundImage: `url("${svgToDataUri( - `` + ``, )}")`, }), "bg-dot": (value) => ({ backgroundImage: `url("${svgToDataUri( - `` + ``, )}")`, }), }, - { values: flattenColorPalette(theme("backgroundColor")), type: "color" } + { + values: flattenColorPalette(theme("backgroundColor")), + type: "color", + }, ); }, + require("daisyui"), ], }; function addVariablesForColors({ addBase, theme }) { let allColors = flattenColorPalette(theme("colors")); let newVars = Object.fromEntries( - Object.entries(allColors).map(([key, val]) => [`--${key}`, val]) + Object.entries(allColors).map(([key, val]) => [`--${key}`, val]), ); addBase({ diff --git a/app/frontend/third-party-licenses.txt b/app/frontend/third-party-licenses.txt new file mode 100644 index 00000000..a974cd1b --- /dev/null +++ b/app/frontend/third-party-licenses.txt @@ -0,0 +1,4950 @@ +This file was generated with the generate-license-file npm package! +https://www.npmjs.com/package/generate-license-file + +The following npm package may be included in this product: + + - source-map-js@1.2.0 + +This package contains the following license and notice below: + +Copyright (c) 2009-2011, Mozilla Foundation and contributors +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the names of the Mozilla Foundation nor the names of project + contributors may be used to endorse or promote products derived from this + software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +----------- + +The following npm package may be included in this product: + + - thenify-all@1.6.0 + +This package contains the following license and notice below: + +The MIT License (MIT) + +Copyright (c) 2014 Jonathan Ong me@jongleberry.com + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - thenify@3.3.1 + +This package contains the following license and notice below: + +The MIT License (MIT) + +Copyright (c) 2014-2016 Jonathan Ong me@jongleberry.com and contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - mz@2.7.0 + +This package contains the following license and notice below: + +The MIT License (MIT) + +Copyright (c) 2014-2016 Jonathan Ong me@jongleberry.com and Contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - @pkgjs/parseargs@0.11.0 + +This package contains the following license and notice below: + +Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +----------- + +The following npm package may be included in this product: + + - ts-interface-checker@0.1.13 + +This package contains the following license and notice below: + +Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +----------- + +The following npm package may be included in this product: + + - @swc/types@0.1.12 + +This package contains the following license and notice below: + +Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +----------- + +The following npm packages may be included in this product: + + - @types/hast@2.3.10 + - @types/node@20.14.11 + - @types/prop-types@15.7.12 + - @types/react-dom@18.3.0 + - @types/react@18.3.3 + - @types/stylis@4.2.5 + - @types/unist@2.0.10 + +These packages each contain the following license and notice below: + +MIT License + + Copyright (c) Microsoft Corporation. + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE + +----------- + +The following npm package may be included in this product: + + - balanced-match@1.0.2 + +This package contains the following license and notice below: + +(MIT) + +Copyright (c) 2013 Julian Gruber <julian@juliangruber.com> + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - commander@4.1.1 + +This package contains the following license and notice below: + +(The MIT License) + +Copyright (c) 2011 TJ Holowaychuk + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - mime-types@2.1.35 + +This package contains the following license and notice below: + +(The MIT License) + +Copyright (c) 2014 Jonathan Ong +Copyright (c) 2015 Douglas Christopher Wilson + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - mime-db@1.52.0 + +This package contains the following license and notice below: + +(The MIT License) + +Copyright (c) 2014 Jonathan Ong +Copyright (c) 2015-2022 Douglas Christopher Wilson + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - util-deprecate@1.0.2 + +This package contains the following license and notice below: + +(The MIT License) + +Copyright (c) 2014 Nathan Rajlich + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +----------- + +The following npm packages may be included in this product: + + - parse-entities@2.0.0 + - property-information@5.6.0 + +These packages each contain the following license and notice below: + +(The MIT License) + +Copyright (c) 2015 Titus Wormer + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +----------- + +The following npm packages may be included in this product: + + - character-entities-legacy@1.1.4 + - character-entities@1.2.4 + - character-reference-invalid@1.1.4 + - fault@1.0.4 + +These packages each contain the following license and notice below: + +(The MIT License) + +Copyright (c) 2015 Titus Wormer + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +----------- + +The following npm packages may be included in this product: + + - comma-separated-tokens@1.0.8 + - hast-util-parse-selector@2.2.5 + - hastscript@6.0.0 + - is-alphabetical@1.0.4 + - is-alphanumerical@1.0.4 + - is-decimal@1.0.4 + - is-hexadecimal@1.0.4 + - lowlight@1.20.0 + - space-separated-tokens@1.1.5 + +These packages each contain the following license and notice below: + +(The MIT License) + +Copyright (c) 2016 Titus Wormer + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - refractor@3.6.0 + +This package contains the following license and notice below: + +(The MIT License) + +Copyright (c) 2017 Titus Wormer + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - path-scurry@1.11.1 + +This package contains the following license and notice below: + +# Blue Oak Model License + +Version 1.0.0 + +## Purpose + +This license gives everyone as much permission to work with +this software as possible, while protecting contributors +from liability. + +## Acceptance + +In order to receive this license, you must agree to its +rules. The rules of this license are both obligations +under that agreement and conditions to your license. +You must not do anything with this software that triggers +a rule that you cannot or will not follow. + +## Copyright + +Each contributor licenses you to do everything with this +software that would otherwise infringe that contributor's +copyright in it. + +## Notices + +You must ensure that everyone who gets a copy of +any part of this software from you, with or without +changes, also gets the text of this license or a link to +. + +## Excuse + +If anyone notifies you in writing that you have not +complied with [Notices](#notices), you can keep your +license by taking all practical steps to comply within 30 +days after the notice. If you do not do so, your license +ends immediately. + +## Patent + +Each contributor licenses you to do everything with this +software that would otherwise infringe any patent claims +they can license or become able to license. + +## Reliability + +No contributor can revoke this license. + +## No Liability + +***As far as the law allows, this software comes as is, +without any warranty or condition, and no contributor +will be liable to anyone for any damages related to this +software or this license, under any kind of legal claim.*** + +----------- + +The following npm package may be included in this product: + + - jackspeak@3.4.3 + +This package contains the following license and notice below: + +# Blue Oak Model License + +Version 1.0.0 + +## Purpose + +This license gives everyone as much permission to work with +this software as possible, while protecting contributors +from liability. + +## Acceptance + +In order to receive this license, you must agree to its +rules. The rules of this license are both obligations +under that agreement and conditions to your license. +You must not do anything with this software that triggers +a rule that you cannot or will not follow. + +## Copyright + +Each contributor licenses you to do everything with this +software that would otherwise infringe that contributor's +copyright in it. + +## Notices + +You must ensure that everyone who gets a copy of +any part of this software from you, with or without +changes, also gets the text of this license or a link to +. + +## Excuse + +If anyone notifies you in writing that you have not +complied with [Notices](#notices), you can keep your +license by taking all practical steps to comply within 30 +days after the notice. If you do not do so, your license +ends immediately. + +## Patent + +Each contributor licenses you to do everything with this +software that would otherwise infringe any patent claims +they can license or become able to license. + +## Reliability + +No contributor can revoke this license. + +## No Liability + +**_As far as the law allows, this software comes as is, +without any warranty or condition, and no contributor +will be liable to anyone for any damages related to this +software or this license, under any kind of legal claim._** + +----------- + +The following npm package may be included in this product: + + - axios@1.7.4 + +This package contains the following license and notice below: + +# Copyright (c) 2014-present Matt Zabriskie & Collaborators + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - didyoumean@1.2.2 + +This package contains the following license and notice below: + +## License + +didYouMean.js copyright (c) 2013 Dave Porter. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License +[here](http://www.apache.org/licenses/LICENSE-2.0). + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +----------- + +The following npm package may be included in this product: + + - package-json-from-dist@1.0.0 + +This package contains the following license and notice below: + +All packages under `src/` are licensed according to the terms in +their respective `LICENSE` or `LICENSE.md` files. + +The remainder of this project is licensed under the Blue Oak +Model License, as follows: + +----- + +# Blue Oak Model License + +Version 1.0.0 + +## Purpose + +This license gives everyone as much permission to work with +this software as possible, while protecting contributors +from liability. + +## Acceptance + +In order to receive this license, you must agree to its +rules. The rules of this license are both obligations +under that agreement and conditions to your license. +You must not do anything with this software that triggers +a rule that you cannot or will not follow. + +## Copyright + +Each contributor licenses you to do everything with this +software that would otherwise infringe that contributor's +copyright in it. + +## Notices + +You must ensure that everyone who gets a copy of +any part of this software from you, with or without +changes, also gets the text of this license or a link to +. + +## Excuse + +If anyone notifies you in writing that you have not +complied with [Notices](#notices), you can keep your +license by taking all practical steps to comply within 30 +days after the notice. If you do not do so, your license +ends immediately. + +## Patent + +Each contributor licenses you to do everything with this +software that would otherwise infringe any patent claims +they can license or become able to license. + +## Reliability + +No contributor can revoke this license. + +## No Liability + +***As far as the law allows, this software comes as is, +without any warranty or condition, and no contributor +will be liable to anyone for any damages related to this +software or this license, under any kind of legal claim.*** + +----------- + +The following npm package may be included in this product: + + - typescript@5.5.4 + +This package contains the following license and notice below: + +Apache License + +Version 2.0, January 2004 + +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. + +"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: + +You must give any other recipients of the Work or Derivative Works a copy of this License; and + +You must cause any modified files to carry prominent notices stating that You changed the files; and + +You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and + +If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +----------- + +The following npm packages may be included in this product: + + - @swc/core@1.7.14 + - @swc/counter@0.1.3 + - class-variance-authority@0.7.0 + +These packages each contain the following license and notice below: + +Apache-2.0 + +----------- + +The following npm packages may be included in this product: + + - @swc/core-darwin-arm64@1.7.14 + - @swc/core-linux-arm64-gnu@1.7.14 + - @swc/core-linux-arm64-musl@1.7.14 + +These packages each contain the following license and notice below: + +Apache-2.0 AND MIT + +----------- + +The following npm package may be included in this product: + + - highlight.js@10.7.3 + +This package contains the following license and notice below: + +BSD 3-Clause License + +Copyright (c) 2006, Ivan Sagalaev. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +----------- + +The following npm packages may be included in this product: + + - combined-stream@1.0.8 + - delayed-stream@1.0.0 + +These packages each contain the following license and notice below: + +Copyright (c) 2011 Debuggable Limited + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - color-convert@2.0.1 + +This package contains the following license and notice below: + +Copyright (c) 2011-2016 Heather Arthur + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - form-data@4.0.0 + +This package contains the following license and notice below: + +Copyright (c) 2012 Felix Geisendörfer (felix@debuggable.com) and contributors + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - function-bind@1.1.2 + +This package contains the following license and notice below: + +Copyright (c) 2013 Raynos. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - any-promise@1.3.0 + +This package contains the following license and notice below: + +Copyright (C) 2014-2016 Kevin Beaty + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - fastq@1.17.1 + +This package contains the following license and notice below: + +Copyright (c) 2015-2020, Matteo Collina + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - @isaacs/cliui@8.0.2 + +This package contains the following license and notice below: + +Copyright (c) 2015, Contributors + +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice +appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE +LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES +OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - csstype@3.1.3 + +This package contains the following license and notice below: + +Copyright (c) 2017-2018 Fredrik Nicol + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - postcss-selector-parser@6.1.1 + +This package contains the following license and notice below: + +Copyright (c) Ben Briggs (http://beneb.info) + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - postcss-value-parser@4.2.0 + +This package contains the following license and notice below: + +Copyright (c) Bogdan Chadkin + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +----------- + +The following npm packages may be included in this product: + + - tslib@2.6.2 + - tslib@2.6.3 + +These packages each contain the following license and notice below: + +Copyright (c) Microsoft Corporation. + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - make-error@1.3.6 + +This package contains the following license and notice below: + +Copyright 2014 Julien Fontanet + +Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - follow-redirects@1.15.6 + +This package contains the following license and notice below: + +Copyright 2014–present Olivier Lalonde , James Talmage , Ruben Verborgh + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - @jridgewell/resolve-uri@3.1.2 + +This package contains the following license and notice below: + +Copyright 2019 Justin Ridgewell + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------- + +The following npm packages may be included in this product: + + - @jridgewell/gen-mapping@0.3.5 + - @jridgewell/set-array@1.2.1 + +These packages each contain the following license and notice below: + +Copyright 2022 Justin Ridgewell + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------- + +The following npm packages may be included in this product: + + - @jridgewell/trace-mapping@0.3.25 + - @jridgewell/trace-mapping@0.3.9 + +These packages each contain the following license and notice below: + +Copyright 2022 Justin Ridgewell + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - yaml@2.4.5 + +This package contains the following license and notice below: + +Copyright Eemeli Aro + +Permission to use, copy, modify, and/or distribute this software for any purpose +with or without fee is hereby granted, provided that the above copyright notice +and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS +OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + +----------- + +The following npm packages may be included in this product: + + - cssesc@3.0.0 + - emoji-regex@8.0.0 + - emoji-regex@9.2.2 + +These packages each contain the following license and notice below: + +Copyright Mathias Bynens + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - format@0.2.2 + +This package contains the following license and notice below: + +http://sjs.mit-license.org + +----------- + +The following npm package may be included in this product: + + - css-color-keywords@1.0.0 + +This package contains the following license and notice below: + +ISC License + +Copyright (c) 2017, Jakob Krigovsky + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - picocolors@1.0.1 + +This package contains the following license and notice below: + +ISC License + +Copyright (c) 2021 Alexey Raspopov, Kostiantyn Denysov, Anton Verinov + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - lucide-react@0.378.0 + +This package contains the following license and notice below: + +ISC License + +Copyright (c) for portions of Lucide are held by Cole Bemis 2013-2022 as part of Feather (MIT). All other copyright (c) for Lucide are held by Lucide Contributors 2022. + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +----------- + +The following npm packages may be included in this product: + + - @radix-ui/number@1.1.0 + - @radix-ui/primitive@1.0.1 + - @radix-ui/primitive@1.1.0 + - @radix-ui/react-accordion@1.2.0 + - @radix-ui/react-arrow@1.1.0 + - @radix-ui/react-aspect-ratio@1.1.0 + - @radix-ui/react-collapsible@1.1.0 + - @radix-ui/react-collection@1.1.0 + - @radix-ui/react-compose-refs@1.0.1 + - @radix-ui/react-compose-refs@1.1.0 + - @radix-ui/react-context@1.0.1 + - @radix-ui/react-context@1.1.0 + - @radix-ui/react-dialog@1.0.5 + - @radix-ui/react-dialog@1.1.1 + - @radix-ui/react-direction@1.1.0 + - @radix-ui/react-dismissable-layer@1.0.5 + - @radix-ui/react-dismissable-layer@1.1.0 + - @radix-ui/react-dropdown-menu@2.1.1 + - @radix-ui/react-focus-guards@1.0.1 + - @radix-ui/react-focus-guards@1.1.0 + - @radix-ui/react-focus-scope@1.0.4 + - @radix-ui/react-focus-scope@1.1.0 + - @radix-ui/react-id@1.0.1 + - @radix-ui/react-id@1.1.0 + - @radix-ui/react-label@2.1.0 + - @radix-ui/react-menu@2.1.1 + - @radix-ui/react-menubar@1.1.1 + - @radix-ui/react-navigation-menu@1.2.0 + - @radix-ui/react-popover@1.1.1 + - @radix-ui/react-popper@1.2.0 + - @radix-ui/react-portal@1.0.4 + - @radix-ui/react-portal@1.1.1 + - @radix-ui/react-presence@1.0.1 + - @radix-ui/react-presence@1.1.0 + - @radix-ui/react-primitive@1.0.3 + - @radix-ui/react-primitive@2.0.0 + - @radix-ui/react-progress@1.1.0 + - @radix-ui/react-roving-focus@1.1.0 + - @radix-ui/react-scroll-area@1.1.0 + - @radix-ui/react-select@2.1.1 + - @radix-ui/react-separator@1.1.0 + - @radix-ui/react-slot@1.0.2 + - @radix-ui/react-slot@1.1.0 + - @radix-ui/react-tooltip@1.1.2 + - @radix-ui/react-use-callback-ref@1.0.1 + - @radix-ui/react-use-callback-ref@1.1.0 + - @radix-ui/react-use-controllable-state@1.0.1 + - @radix-ui/react-use-controllable-state@1.1.0 + - @radix-ui/react-use-escape-keydown@1.0.3 + - @radix-ui/react-use-escape-keydown@1.1.0 + - @radix-ui/react-use-layout-effect@1.0.1 + - @radix-ui/react-use-layout-effect@1.1.0 + - @radix-ui/react-use-previous@1.1.0 + - @radix-ui/react-use-rect@1.1.0 + - @radix-ui/react-use-size@1.1.0 + - @radix-ui/react-visually-hidden@1.1.0 + - @radix-ui/rect@1.1.0 + - dlv@1.1.3 + - eastasianwidth@0.2.0 + - react-remove-scroll-bar@2.3.6 + - react-style-singleton@2.2.1 + - undici-types@5.26.5 + +These packages each contain the following license and notice below: + +MIT + +----------- + +The following npm package may be included in this product: + + - resolve@1.22.8 + +This package contains the following license and notice below: + +MIT License + +Copyright (c) 2012 James Halliday + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------- + +The following npm packages may be included in this product: + + - prismjs@1.27.0 + - prismjs@1.29.0 + +These packages each contain the following license and notice below: + +MIT LICENSE + +Copyright (c) 2012 Lea Verou + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - readdirp@3.6.0 + +This package contains the following license and notice below: + +MIT License + +Copyright (c) 2012-2019 Thorsten Lorenz, Paul Miller (https://paulmillr.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - acorn-walk@8.3.3 + +This package contains the following license and notice below: + +MIT License + +Copyright (C) 2012-2020 by various contributors (see AUTHORS) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - acorn@8.12.1 + +This package contains the following license and notice below: + +MIT License + +Copyright (C) 2012-2022 by various contributors (see AUTHORS) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - brace-expansion@2.0.1 + +This package contains the following license and notice below: + +MIT License + +Copyright (c) 2013 Julian Gruber + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - invariant@2.2.4 + +This package contains the following license and notice below: + +MIT License + +Copyright (c) 2013-present, Facebook, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - @babel/runtime@7.24.8 + +This package contains the following license and notice below: + +MIT License + +Copyright (c) 2014-present Sebastian McKenzie and other contributors + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - regenerator-runtime@0.14.1 + +This package contains the following license and notice below: + +MIT License + +Copyright (c) 2014-present, Facebook, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - css-to-react-native@3.2.0 + +This package contains the following license and notice below: + +MIT License + +Copyright (c) 2016 Jacob Parker and Maximilian Stoiber + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - pirates@4.0.6 + +This package contains the following license and notice below: + +MIT License + +Copyright (c) 2016-2018 Ari Porad + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - styled-components@6.1.12 + +This package contains the following license and notice below: + +MIT License + +Copyright (c) 2016-present Glen Maddern and Maximilian Stoiber + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - stylis@4.3.2 + +This package contains the following license and notice below: + +MIT License + +Copyright (c) 2016-present Sultan Tarimo + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - shallowequal@1.1.0 + +This package contains the following license and notice below: + +MIT License + +Copyright (c) 2017 Alberto Leal (github.com/dashed) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------- + +The following npm packages may be included in this product: + + - aria-hidden@1.2.4 + - react-remove-scroll@2.5.5 + - react-remove-scroll@2.5.7 + - use-callback-ref@1.3.2 + - use-sidecar@1.1.2 + +These packages each contain the following license and notice below: + +MIT License + +Copyright (c) 2017 Anton Korzunov + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - detect-node-es@1.1.0 + +This package contains the following license and notice below: + +MIT License + +Copyright (c) 2017 Ilya Kantor + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - arg@4.1.3 + +This package contains the following license and notice below: + +MIT License + +Copyright (c) 2017-2019 Zeit, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - mini-svg-data-uri@1.4.4 + +This package contains the following license and notice below: + +MIT License + +Copyright (c) 2018 Taylor Hunt + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - react-syntax-highlighter@15.5.0 + +This package contains the following license and notice below: + +MIT License + +Copyright (c) 2019 Conor Hastings + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - goober@2.1.14 + +This package contains the following license and notice below: + +MIT License + +Copyright (c) 2019 Cristian Bote + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - is-binary-path@2.1.0 + +This package contains the following license and notice below: + +MIT License + +Copyright (c) 2019 Sindre Sorhus (https://sindresorhus.com), Paul Miller (https://paulmillr.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +----------- + +The following npm packages may be included in this product: + + - @hookform/resolvers@3.9.0 + - react-hook-form@7.52.1 + +These packages each contain the following license and notice below: + +MIT License + +Copyright (c) 2019-present Beier(Bill) Luo + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - create-require@1.1.1 + +This package contains the following license and notice below: + +MIT License + +Copyright (c) 2020 + +Maël Nison +Paul Soporan +Pooya Parsa + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - get-nonce@1.0.1 + +This package contains the following license and notice below: + +MIT License + +Copyright (c) 2020 Anton Korzunov + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - zod@3.23.8 + +This package contains the following license and notice below: + +MIT License + +Copyright (c) 2020 Colin McDonnell + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - tailwindcss-animate@1.0.7 + +This package contains the following license and notice below: + +MIT License + +Copyright (c) 2020 Jamie Kyle + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - react-code-blocks@0.1.6 + +This package contains the following license and notice below: + +MIT License + +Copyright (c) 2020 Raj Singh + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - react-hot-toast@2.4.1 + +This package contains the following license and notice below: + +MIT License + +Copyright (c) 2020 Timo Lins + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - tailwind-merge@2.4.0 + +This package contains the following license and notice below: + +MIT License + +Copyright (c) 2021 Dany Castillo + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------- + +The following npm packages may be included in this product: + + - @floating-ui/core@1.6.5 + - @floating-ui/dom@1.6.8 + - @floating-ui/react-dom@2.1.1 + - @floating-ui/utils@0.2.5 + +These packages each contain the following license and notice below: + +MIT License + +Copyright (c) 2021-present Floating UI contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +----------- + +The following npm packages may be included in this product: + + - @tanstack/query-core@5.51.9 + - @tanstack/react-query@5.51.11 + +These packages each contain the following license and notice below: + +MIT License + +Copyright (c) 2021-present Tanner Linsley + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------- + +The following npm packages may be included in this product: + + - lilconfig@2.1.0 + - lilconfig@3.1.2 + +These packages each contain the following license and notice below: + +MIT License + +Copyright (c) 2022 Anton Kastritskiy + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - supports-preserve-symlinks-flag@1.0.0 + +This package contains the following license and notice below: + +MIT License + +Copyright (c) 2022 Inspect JS + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - cmdk@1.0.0 + +This package contains the following license and notice below: + +MIT License + +Copyright (c) 2022 Paco Coursey + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - @radix-ui/react-icons@1.3.0 + +This package contains the following license and notice below: + +MIT License + +Copyright (c) 2022 WorkOS + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - vaul@0.9.1 + +This package contains the following license and notice below: + +MIT License + +Copyright (c) 2023 Emil Kowalski + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +----------- + +The following npm packages may be included in this product: + + - @emotion/is-prop-valid@1.2.2 + - @emotion/memoize@0.8.1 + - @emotion/unitless@0.8.1 + +These packages each contain the following license and notice below: + +MIT License + +Copyright (c) Emotion team and other contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------- + +The following npm packages may be included in this product: + + - react-dom@18.3.1 + - react@18.3.1 + - scheduler@0.23.2 + +These packages each contain the following license and notice below: + +MIT License + +Copyright (c) Facebook, Inc. and its affiliates. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - hasown@2.0.2 + +This package contains the following license and notice below: + +MIT License + +Copyright (c) Jordan Harband and contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - shebang-command@2.0.0 + +This package contains the following license and notice below: + +MIT License + +Copyright (c) Kevin Mårtensson (github.com/kevva) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +----------- + +The following npm packages may be included in this product: + + - clsx@2.0.0 + - clsx@2.1.1 + +These packages each contain the following license and notice below: + +MIT License + +Copyright (c) Luke Edwards (lukeed.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +----------- + +The following npm packages may be included in this product: + + - @tsconfig/node10@1.0.11 + - @tsconfig/node12@1.0.11 + - @tsconfig/node14@1.0.3 + - @tsconfig/node16@1.0.4 + +These packages each contain the following license and notice below: + +MIT License + +Copyright (c) Microsoft Corporation. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE + +----------- + +The following npm package may be included in this product: + + - jiti@1.21.6 + +This package contains the following license and notice below: + +MIT License + +Copyright (c) Pooya Parsa + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------- + +The following npm packages may be included in this product: + + - @remix-run/router@1.18.0 + - react-router-dom@6.25.1 + - react-router@6.25.1 + +These packages each contain the following license and notice below: + +MIT License + +Copyright (c) React Training LLC 2015-2019 +Copyright (c) Remix Software Inc. 2020-2021 +Copyright (c) Shopify Inc. 2022-2023 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------- + +The following npm packages may be included in this product: + + - ansi-regex@6.0.1 + - ansi-styles@6.2.1 + - string-width@5.1.2 + - strip-ansi@7.1.0 + - wrap-ansi@7.0.0 + - wrap-ansi@8.1.0 + +These packages each contain the following license and notice below: + +MIT License + +Copyright (c) Sindre Sorhus (https://sindresorhus.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - binary-extensions@2.3.0 + +This package contains the following license and notice below: + +MIT License + +Copyright (c) Sindre Sorhus (https://sindresorhus.com) +Copyright (c) Paul Miller (https://paulmillr.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +----------- + +The following npm packages may be included in this product: + + - @alloc/quick-lru@5.2.0 + - ansi-regex@5.0.1 + - ansi-styles@4.3.0 + - is-fullwidth-code-point@3.0.0 + - path-key@3.1.1 + - shebang-regex@3.0.0 + - string-width@4.2.3 + - strip-ansi@6.0.1 + - yn@3.1.1 + +These packages each contain the following license and notice below: + +MIT License + +Copyright (c) Sindre Sorhus (sindresorhus.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - tailwindcss@3.4.6 + +This package contains the following license and notice below: + +MIT License + +Copyright (c) Tailwind Labs, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - fsevents@2.3.3 + +This package contains the following license and notice below: + +MIT License +----------- + +Copyright (C) 2010-2020 by Philipp Dunkel, Ben Noordhuis, Elan Shankar, Paul Miller + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - diff@4.0.2 + +This package contains the following license and notice below: + +Software License Agreement (BSD License) + +Copyright (c) 2009-2015, Kevin Decker + +All rights reserved. + +Redistribution and use of this software in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of Kevin Decker nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER +IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +----------- + +The following npm package may be included in this product: + + - glob@10.4.5 + +This package contains the following license and notice below: + +The ISC License + +Copyright (c) 2009-2023 Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - lru-cache@10.4.3 + +This package contains the following license and notice below: + +The ISC License + +Copyright (c) 2010-2023 Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - minimatch@9.0.5 + +This package contains the following license and notice below: + +The ISC License + +Copyright (c) 2011-2023 Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - signal-exit@4.1.0 + +This package contains the following license and notice below: + +The ISC License + +Copyright (c) 2015-2023 Benjamin Coe, Isaac Z. Schlueter, and Contributors + +Permission to use, copy, modify, and/or distribute this software +for any purpose with or without fee is hereby granted, provided +that the above copyright notice and this permission notice +appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE +LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES +OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - foreground-child@3.2.1 + +This package contains the following license and notice below: + +The ISC License + +Copyright (c) 2015-2023 Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - glob-parent@5.1.2 + +This package contains the following license and notice below: + +The ISC License + +Copyright (c) 2015, 2019 Elan Shanker + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - glob-parent@6.0.2 + +This package contains the following license and notice below: + +The ISC License + +Copyright (c) 2015, 2019 Elan Shanker, 2021 Blaine Bublitz , Eric Schoffstall and other contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - minipass@7.1.2 + +This package contains the following license and notice below: + +The ISC License + +Copyright (c) 2017-2023 npm, Inc., Isaac Z. Schlueter, and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - anymatch@3.1.3 + +This package contains the following license and notice below: + +The ISC License + +Copyright (c) 2019 Elan Shanker, Paul Miller (https://paulmillr.com) + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +----------- + +The following npm packages may be included in this product: + + - isexe@2.0.0 + - which@2.0.2 + +These packages each contain the following license and notice below: + +The ISC License + +Copyright (c) Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - @jridgewell/sourcemap-codec@1.5.0 + +This package contains the following license and notice below: + +The MIT License + +Copyright (c) 2015 Rich Harris + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - proxy-from-env@1.1.0 + +This package contains the following license and notice below: + +The MIT License + +Copyright (C) 2016-2018 Rob Wu + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - sucrase@3.35.0 + +This package contains the following license and notice below: + +The MIT License (MIT) + +Copyright (c) 2012-2018 various contributors (see AUTHORS) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - chokidar@3.6.0 + +This package contains the following license and notice below: + +The MIT License (MIT) + +Copyright (c) 2012-2019 Paul Miller (https://paulmillr.com), Elan Shanker + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the “Software”), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - ts-node@10.9.2 + +This package contains the following license and notice below: + +The MIT License (MIT) + +Copyright (c) 2014 Blake Embrey (hello@blakeembrey.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - is-core-module@2.15.0 + +This package contains the following license and notice below: + +The MIT License (MIT) + +Copyright (c) 2014 Dave Justice + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - @cspotcode/source-map-support@0.8.1 + +This package contains the following license and notice below: + +The MIT License (MIT) + +Copyright (c) 2014 Evan Wallace + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - postcss-import@15.1.0 + +This package contains the following license and notice below: + +The MIT License (MIT) + +Copyright (c) 2014 Maxime Thirouin, Jason Campbell & Kevin Mårtensson + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - object-hash@3.0.0 + +This package contains the following license and notice below: + +The MIT License (MIT) + +Copyright (c) 2014 object-hash contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - is-extglob@2.1.1 + +This package contains the following license and notice below: + +The MIT License (MIT) + +Copyright (c) 2014-2016, Jon Schlinkert + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - is-glob@4.0.3 + +This package contains the following license and notice below: + +The MIT License (MIT) + +Copyright (c) 2014-2017, Jon Schlinkert. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - normalize-path@3.0.0 + +This package contains the following license and notice below: + +The MIT License (MIT) + +Copyright (c) 2014-2018, Jon Schlinkert. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - merge2@1.4.1 + +This package contains the following license and notice below: + +The MIT License (MIT) + +Copyright (c) 2014-2020 Teambition + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------- + +The following npm packages may be included in this product: + + - braces@3.0.3 + - fill-range@7.1.1 + - is-number@7.0.0 + - micromatch@4.0.8 + +These packages each contain the following license and notice below: + +The MIT License (MIT) + +Copyright (c) 2014-present, Jon Schlinkert. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - js-tokens@4.0.0 + +This package contains the following license and notice below: + +The MIT License (MIT) + +Copyright (c) 2014, 2015, 2016, 2017, 2018 Simon Lydell + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - loose-envify@1.4.0 + +This package contains the following license and notice below: + +The MIT License (MIT) + +Copyright (c) 2015 Andres Suarez + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - lines-and-columns@1.2.4 + +This package contains the following license and notice below: + +The MIT License (MIT) + +Copyright (c) 2015 Brian Donovan + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - path-parse@1.0.7 + +This package contains the following license and notice below: + +The MIT License (MIT) + +Copyright (c) 2015 Javier Blanco + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - reusify@1.0.4 + +This package contains the following license and notice below: + +The MIT License (MIT) + +Copyright (c) 2015 Matteo Collina + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - to-regex-range@5.0.1 + +This package contains the following license and notice below: + +The MIT License (MIT) + +Copyright (c) 2015-present, Jon Schlinkert. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - asynckit@0.4.0 + +This package contains the following license and notice below: + +The MIT License (MIT) + +Copyright (c) 2016 Alex Indigo + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - picomatch@2.3.1 + +This package contains the following license and notice below: + +The MIT License (MIT) + +Copyright (c) 2017-present, Jon Schlinkert. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - framer-motion@11.3.12 + +This package contains the following license and notice below: + +The MIT License (MIT) + +Copyright (c) 2018 Framer B.V. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - cross-spawn@7.0.3 + +This package contains the following license and notice below: + +The MIT License (MIT) + +Copyright (c) 2018 Made With MOXY Lda + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - v8-compile-cache-lib@3.0.1 + +This package contains the following license and notice below: + +The MIT License (MIT) + +Copyright (c) 2019 Andres Suarez + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - arg@5.0.2 + +This package contains the following license and notice below: + +The MIT License (MIT) + +Copyright (c) 2021 Vercel, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------- + +The following npm packages may be included in this product: + + - @nodelib/fs.scandir@2.1.5 + - @nodelib/fs.stat@2.0.5 + - @nodelib/fs.walk@1.2.8 + - fast-glob@3.3.2 + +These packages each contain the following license and notice below: + +The MIT License (MIT) + +Copyright (c) Denis Malinochkin + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------- + +The following npm packages may be included in this product: + + - queue-microtask@1.2.3 + - run-parallel@1.2.0 + +These packages each contain the following license and notice below: + +The MIT License (MIT) + +Copyright (c) Feross Aboukhadijeh + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +----------- + +The following npm packages may be included in this product: + + - object-assign@4.1.1 + - pify@2.3.0 + +These packages each contain the following license and notice below: + +The MIT License (MIT) + +Copyright (c) Sindre Sorhus (sindresorhus.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - camelcase-css@2.0.1 + +This package contains the following license and notice below: + +The MIT License (MIT) + +Copyright (c) Steven Vachon (svachon.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +----------- + +The following npm packages may be included in this product: + + - postcss@8.4.38 + - postcss@8.4.41 + +These packages each contain the following license and notice below: + +The MIT License (MIT) + +Copyright 2013 Andrey Sitnik + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - postcss-nested@6.2.0 + +This package contains the following license and notice below: + +The MIT License (MIT) + +Copyright 2014 Andrey Sitnik + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - postcss-js@4.0.1 + +This package contains the following license and notice below: + +The MIT License (MIT) + +Copyright 2015 Andrey Sitnik + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - read-cache@1.0.0 + +This package contains the following license and notice below: + +The MIT License (MIT) + +Copyright 2016 Bogdan Chadkin + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - nanoid@3.3.7 + +This package contains the following license and notice below: + +The MIT License (MIT) + +Copyright 2017 Andrey Sitnik + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - postcss-load-config@4.0.2 + +This package contains the following license and notice below: + +The MIT License (MIT) + +Copyright Michael Ciniawsky + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - xtend@4.0.2 + +This package contains the following license and notice below: + +The MIT License (MIT) +Copyright (c) 2012-2014 Raynos. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - color-name@1.1.4 + +This package contains the following license and notice below: + +The MIT License (MIT) +Copyright (c) 2015 Dmitry Ivanov + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - camelize@1.0.1 + +This package contains the following license and notice below: + +This software is released under the MIT license: + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +----------- + +This file was generated with the generate-license-file npm package! +https://www.npmjs.com/package/generate-license-file diff --git a/app/frontend/vite.config.ts b/app/frontend/vite.config.ts index a84af69d..a64521bb 100644 --- a/app/frontend/vite.config.ts +++ b/app/frontend/vite.config.ts @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC import { defineConfig, ProxyOptions } from "vite"; import react from "@vitejs/plugin-react-swc"; import path from "path"; @@ -18,27 +20,49 @@ const proxyConfig: Record = Object.fromEntries( changeOrigin: true, secure: true, // debug logging - configure: (proxy: any, _options: any) => { - proxy.on("error", (err: any, _req: any, _res: any) => { + configure: (proxy) => { + proxy.on("error", (err) => { console.log("proxy error", err); }); - proxy.on("proxyReq", (proxyReq: any, req: any, _res: any) => { + proxy.on("proxyReq", (proxyReq, req) => { console.log("Sending Request to the Target:", req.method, req.url); }); - proxy.on("proxyRes", (proxyRes: any, req: any, _res: any) => { + proxy.on("proxyRes", (proxyRes, req) => { console.log( "Received Response from the Target:", proxyRes.statusCode, - req.url + req.url, ); }); }, rewrite: (path: string) => path.replace(new RegExp(`^/${proxyPath}`), `/${actualPath}`), }, - ]) + ]), ); +// Add specific proxy configuration for the /reset-board endpoint +proxyConfig["/reset-board"] = { + target: VITE_BACKEND_URL, + changeOrigin: true, + secure: true, + configure: (proxy) => { + proxy.on("error", (err) => { + console.log("proxy error", err); + }); + proxy.on("proxyReq", (proxyReq, req) => { + console.log("Sending Request to the Target:", req.method, req.url); + }); + proxy.on("proxyRes", (proxyRes, req) => { + console.log( + "Received Response from the Target:", + proxyRes.statusCode, + req.url, + ); + }); + }, +}; + // https://vitejs.dev/config/ export default defineConfig({ plugins: [react()], diff --git a/startup.sh b/startup.sh index f145bc2b..36a6f1b6 100644 --- a/startup.sh +++ b/startup.sh @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + #!/bin/bash # step 0: detect OS From 59fad382d835cee83f684057e75c265f75653e1f Mon Sep 17 00:00:00 2001 From: Greg Hatt Date: Tue, 20 Aug 2024 16:17:30 -0300 Subject: [PATCH 03/61] Initial Backend Work Docker Compose - Adds chroma service - Adds health checks - Adds port mappings - Adds storage configuration API - Adds endpoints for CRUD for vector DB collections - Adds endpoint for inserting documents - Adds URL configuration - Adds endpoint for querying collection Docker - Adds image changes to support ChromaDB wheels --- app/api/Dockerfile | 21 +++-- app/api/api/settings.py | 20 +++-- app/api/api/urls.py | 1 + app/api/requirements.txt | 23 +++++- app/api/vector_db_control/__init__.py | 1 + app/api/vector_db_control/apps.py | 34 ++++++++ app/api/vector_db_control/chroma.py | 105 +++++++++++++++++++++++++ app/api/vector_db_control/data.py | 29 +++++++ app/api/vector_db_control/documents.py | 13 +++ app/api/vector_db_control/urls.py | 11 +++ app/api/vector_db_control/views.py | 83 +++++++++++++++++++ app/docker-compose.yml | 36 ++++++++- app/frontend/vite.config.ts | 1 + 13 files changed, 359 insertions(+), 19 deletions(-) create mode 100644 app/api/vector_db_control/__init__.py create mode 100644 app/api/vector_db_control/apps.py create mode 100644 app/api/vector_db_control/chroma.py create mode 100644 app/api/vector_db_control/data.py create mode 100644 app/api/vector_db_control/documents.py create mode 100644 app/api/vector_db_control/urls.py create mode 100644 app/api/vector_db_control/views.py diff --git a/app/api/Dockerfile b/app/api/Dockerfile index afac3518..20a5ea24 100644 --- a/app/api/Dockerfile +++ b/app/api/Dockerfile @@ -1,22 +1,27 @@ # SPDX-License-Identifier: Apache-2.0 -# +# # SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC +FROM python:3.12.5-slim-bookworm + FROM python:3.12.1-slim-bullseye ENV PYTHONUNBUFFERED=1 EXPOSE 8000 # debug tools RUN apt-get update && \ - apt-get install -y \ - procps \ - net-tools \ - iputils-ping \ - dnsutils && \ - rm -rf /var/lib/apt/lists/* + apt-get install -y \ + procps \ + net-tools \ + iputils-ping \ + python3-dev \ + build-essential \ + libsqlite3-dev \ + dnsutils && \ + rm -rf /var/lib/apt/lists/* RUN apt-get update && \ - apt-get install -y \ + apt-get install -y \ git \ curl \ cargo diff --git a/app/api/api/settings.py b/app/api/api/settings.py index 275a0fce..bd630ad8 100644 --- a/app/api/api/settings.py +++ b/app/api/api/settings.py @@ -13,16 +13,14 @@ For the full list of settings and their values, see https://docs.djangoproject.com/en/4.2/ref/settings/ """ - -from pathlib import Path import os +from pathlib import Path from shared_config.backend_config import backend_config # Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = Path(__file__).resolve().parent.parent - # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/4.2/howto/deployment/checklist/ @@ -56,6 +54,7 @@ "django.contrib.staticfiles", "docker_control", "model_control", + "vector_db_control", "corsheaders", ] @@ -89,7 +88,7 @@ ] WSGI_APPLICATION = "api.wsgi.application" - +SESSIONS_ENGINE = 'django.contrib.sessions.backends.cache' # Database # https://docs.djangoproject.com/en/4.2/ref/settings/#databases @@ -126,7 +125,6 @@ }, ] - # Internationalization # https://docs.djangoproject.com/en/4.2/topics/i18n/ @@ -138,7 +136,6 @@ USE_TZ = True - # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/4.2/howto/static-files/ @@ -148,3 +145,14 @@ # https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField" + +CHROMA_DB_PORT = int(os.environ.get('CHROMA_DB_PORT', 8111)) +CHROMA_DB_HOST = os.environ.get('CHROMA_DB_HOST', 'tt_studio_chromadb') +CHROMA_DB_EMBED_MODEL = "all-MiniLM-L6-v2" +PREPOPULATE_VECTOR_DB = True + +REST_FRAMEWORK = { + 'DEFAULT_AUTHENTICATION_CLASSES': [], + 'DEFAULT_PERMISSION_CLASSES': [], + 'UNAUTHENTICATED_USER': None, +} diff --git a/app/api/api/urls.py b/app/api/api/urls.py index 8a4e5a1e..0319ba2a 100644 --- a/app/api/api/urls.py +++ b/app/api/api/urls.py @@ -27,4 +27,5 @@ path("docker/", include("docker_control.urls")), path("models/", include("model_control.urls")), path('reset_board/', include('docker_control.urls')), + path("collections/", include("vector_db_control.urls")), ] diff --git a/app/api/requirements.txt b/app/api/requirements.txt index 0d49d481..88ee87b7 100644 --- a/app/api/requirements.txt +++ b/app/api/requirements.txt @@ -1,9 +1,24 @@ Django==5.0.4 -docker==7.0.0 -djangorestframework==3.14.0 +PyJWT==2.7.0 django-cors-headers==4.3.1 -requests==2.31.0 -pyjwt==2.7.0 +djangorestframework==3.14.0 +docker==7.0.0 gunicorn==22.0.0 +numpy==1.26.4 +pyjwt==2.7.0 +pypdf==4.3.1 +requests==2.29.0 + # dev pytest==8.2.2 + +# Chroma loader dependencies +chromadb==0.5.3 +langchain==0.2.14 +langchain-core==0.2.33 +langchain-text-splitters==0.2.2 +langchain-chroma==0.1.3 +sentence-transformers==2.7.0 +chroma-hnswlib==0.7.3 +--no-binary=chroma-hnswlib +pysqlite3==0.5.3 diff --git a/app/api/vector_db_control/__init__.py b/app/api/vector_db_control/__init__.py new file mode 100644 index 00000000..8167b597 --- /dev/null +++ b/app/api/vector_db_control/__init__.py @@ -0,0 +1 @@ +default_app_config = 'api.apps.vector_db.apps.VectorDbConfig' diff --git a/app/api/vector_db_control/apps.py b/app/api/vector_db_control/apps.py new file mode 100644 index 00000000..a8f93c44 --- /dev/null +++ b/app/api/vector_db_control/apps.py @@ -0,0 +1,34 @@ +from django.apps import AppConfig + +from shared_config.logger_config import get_logger +from vector_db_control.chroma import get_chroma_client + +logger = get_logger(__name__) +logger.info(f"importing {__name__}") +prepopulated_db = False + +class VectorDbConfig(AppConfig): + name = 'vector_db_control' + default_auto_field = "django.db.models.BigAutoField" + + def ready(self): + from django.conf import settings + from chromadb.utils import embedding_functions + from vector_db_control.data import SAMPLE_DATA + prepopulated_db_name = "prepopulated_db" + chroma_db_host = settings.CHROMA_DB_HOST + chroma_db_port = settings.CHROMA_DB_PORT + global prepopulated_db + if bool(settings.PREPOPULATE_VECTOR_DB) and not prepopulated_db: + client = get_chroma_client(host=chroma_db_host, port=chroma_db_port) + embedding_func = embedding_functions.SentenceTransformerEmbeddingFunction( + model_name=settings.CHROMA_DB_EMBED_MODEL, + ) + documents = SAMPLE_DATA + ids = [str(i) for i in range(0, len(documents))] + collection = client.get_or_create_collection( + name=prepopulated_db_name, + embedding_function=embedding_func, + ) + collection.upsert(documents=documents, ids=ids, metadatas=None) + prepopulated_db = True diff --git a/app/api/vector_db_control/chroma.py b/app/api/vector_db_control/chroma.py new file mode 100644 index 00000000..c14a8335 --- /dev/null +++ b/app/api/vector_db_control/chroma.py @@ -0,0 +1,105 @@ +from datetime import datetime +from itertools import batched +from typing import List + +import chromadb +from chromadb import ClientAPI +from chromadb.config import Settings +from chromadb.types import Collection +from chromadb.utils import embedding_functions + +from shared_config.logger_config import get_logger + +chromadb_client = None + +logger = get_logger(__name__) + + +def get_chroma_client(host: str, port: int, username=None, password=None): + global chromadb_client + logger.info(f"Attempting to connect to ChromaDB at {host}:{port}") + if not chromadb_client: + chromadb_client = chromadb.HttpClient(host=host, port=port, + settings=Settings()) + return chromadb_client + + +def list_collections(chroma_client: ClientAPI, filter_func=None): + chroma_collections = chroma_client.list_collections() + if filter_func: + return filter(filter_func, chroma_collections) + return chroma_collections + + +def get_collection(chroma_client: ClientAPI, collection_name: str, embedding_func_name: str): + embedding_func = embedding_functions.SentenceTransformerEmbeddingFunction( + model_name=embedding_func_name + ) + return chroma_client.get_collection(name=collection_name, embedding_function=embedding_func) + + +def create_collection(chroma_client: ClientAPI, collection_name: str, embedding_func_name: str, + metadata=None, distance_func_name: str = "cosine"): + # Metadata could be used in the future to filter our collections. + # For instance - ` metadata = { 'target_models' : "X, Y, Z" } + embedding_func = embedding_functions.SentenceTransformerEmbeddingFunction( + model_name=embedding_func_name + ) + metadata = metadata or {} + metadata.update({"hnsw:space": distance_func_name, "embedding_func_name": embedding_func_name}) + metadata.update({"created_at": datetime.now()}) + return chroma_client.create_collection(name=collection_name, embedding_function=embedding_func, metadata=metadata) + + +def delete_collection(chroma_client: ClientAPI, collection_name: str): + if not chroma_client.get_collection(collection_name): + raise ValueError('Collection does not exist') + chroma_client.delete_collection(collection_name) + + +def query_collection(chroma_client: ClientAPI, collection_name: str, embedding_func_name: str, + query_texts: List[str]): + embedding_func = embedding_functions.SentenceTransformerEmbeddingFunction( + model_name=embedding_func_name + ) + target_collection = chroma_client.get_collection(name=collection_name, embedding_function=embedding_func) + return target_collection.query(query_texts=query_texts) + + +def serialize_collection(collection: Collection): + return { + "id": str(collection.id), + "metadata": collection.metadata, + "name": collection.name, + } + + +def insert_to_chroma_collection( + chroma_client: ClientAPI, + collection_name: str, + embedding_func_name: str, + ids: list[str], + documents: list[str], + metadatas: list[dict], + +): + embedding_func = embedding_functions.SentenceTransformerEmbeddingFunction( + model_name=embedding_func_name + ) + + target_collection = chroma_client.get_collection( + name=collection_name, + embedding_function=embedding_func, + ) + + document_indices = list(range(len(documents))) + + for batch in batched(document_indices, 166): + start_idx = batch[0] + end_idx = batch[-1] + 1 + metadatas = metadatas[start_idx:end_idx] if metadatas and len(metadatas) else None + target_collection.add( + ids=ids[start_idx:end_idx], + documents=documents[start_idx:end_idx], + metadatas=metadatas, + ) diff --git a/app/api/vector_db_control/data.py b/app/api/vector_db_control/data.py new file mode 100644 index 00000000..671d1f13 --- /dev/null +++ b/app/api/vector_db_control/data.py @@ -0,0 +1,29 @@ +LINCOLN_TOWN_CAR = """ +The Lincoln Town Car is a model line of full-size luxury sedans that was marketed by the Lincoln division of the American automaker Ford Motor Company. Deriving its name from a limousine body style, Lincoln marketed the Town Car from 1981 to 2011, with the nameplate previously serving as the flagship trim of the Lincoln Continental. Produced across three generations for thirty model years, the Town Car was marketed directly against luxury sedans from Cadillac and Chrysler.[1] +Marketed nearly exclusively as a four-door sedan (a two-door sedan was offered for 1981 only), many examples of the Town Car were used for fleet and livery (limousine) service. From 1983 to its 2011 discontinuation, the Town Car was the longest car produced by Ford worldwide, becoming the longest mass-production car sold in North America from 1997 to 2011. While not a direct successor of the Town Car, the Lincoln MKS would become the longest American sedan until 2016 (overtaken by the Cadillac CT6). +From 1980 until 2007, the Lincoln Town Car was assembled in Wixom, Michigan, (Wixom Assembly) alongside the Lincoln Continental, LS, and Mark VI, VII, and VIII. After Wixom's closure, Town Car production moved to Southwold, Ontario, (St. Thomas Assembly) alongside the similar Ford Crown Victoria and the Mercury Grand Marquis. The final Lincoln Town Car was produced on August 29, 2011.[2] +Within the Lincoln model line, the Town Car was not directly replaced; the nameplate was used from 2012 to 2019 to denote livery/limousine/hearse variants of the Lincoln MKT. For 2017, the revived Continental replaced the MKS, closely matching the Town Car in wheelbase and width. +""" + +APPLES = """ +An apple is a round, edible fruit produced by an apple tree (Malus spp., among them the domestic or orchard apple; Malus domestica). Apple trees are cultivated worldwide and are the most widely grown species in the genus Malus. The tree originated in Central Asia, where its wild ancestor, Malus sieversii, is still found. Apples have been grown for thousands of years in Eurasia and were introduced to North America by European colonists. Apples have religious and mythological significance +in many cultures, including Norse, Greek, and European Christian tradition. +Apples grown from seed tend to be very different from those of their parents, and the resultant fruit frequently lacks desired characteristics. For commercial purposes, including botanical evaluation, apple cultivars are propagated by clonal grafting onto rootstocks. Apple trees grown without rootstocks tend to be larger and much slower to fruit after planting. Rootstocks are used to control the speed of growth and the size of the resulting tree, allowing for easier harvesting. +There are more than 7,500 cultivars of apples. Different cultivars are bred for various tastes and uses, including cooking, eating raw, and cider or apple juice production. Trees and fruit are prone to fungal, bacterial, and pest problems, which can be controlled by a number of organic and non-organic means. In 2010, the fruit's genome was sequenced as part of research on disease control and selective breeding in apple production. +""" + + +HEBREW = """ +Hebrew (Hebrew alphabet: עִבְרִית‎, ʿĪvrīt, pronounced [ivˈʁit] ⓘ or [ʕivˈrit] ⓘ; Samaritan script: ࠏࠨࠁࠬࠓࠪࠉࠕ‎ ʿÎbrit) is a Northwest Semitic language within the Afroasiatic language family. A regional dialect of the Canaanite languages, it was natively spoken by the Israelites and remained in regular use as a first language until after 200 CE and as the liturgical language of Judaism (since the Second Temple period) and Samaritanism.[14] The language was revived as a spoken language in the 19th century, and is the only successful large-scale example of linguistic revival. It is the only Canaanite language, as well as one of only two Northwest Semitic languages, with the other being Aramaic, still spoken today.[15][16] +The earliest examples of written Paleo-Hebrew date back to the 10th century BCE.[17] Nearly all of the Hebrew Bible is written in Biblical Hebrew, with much of its present form in the dialect that scholars believe flourished around the 6th century BCE, during the time of the Babylonian captivity. For this reason, Hebrew has been referred to by Jews as Lashon Hakodesh (לְשׁוֹן הַקֹּדֶש, lit. 'the holy tongue' or 'the tongue [of] holiness') since ancient times. The language was not referred to by the name Hebrew in the Bible, but as Yehudit (transl. 'Judean') or Səpaṯ Kəna'an (transl. "the language of Canaan").[1][note 2] Mishnah Gittin 9:8 refers to the language as Ivrit, meaning Hebrew; however, Mishnah Megillah refers + to the language as Ashurit, meaning Assyrian, which is derived from the name of the alphabet used, in contrast to Ivrit, meaning the Paleo-Hebrew alphabet.[18] +Hebrew ceased to be a regular spoken language sometime between 200 and 400 CE, as it declined in the aftermath of the unsuccessful Bar Kokhba revolt, which was carried out against the Roman Empire by the Jews of Judaea.[19][20][note 3] Aramaic and, to a lesser extent, Greek were already in use as international languages, especially among societal elites and immigrants.[22] Hebrew survived into the medieval period as the language of Jewish liturgy, rabbinic literature, intra-Jewish commerce, and Jewish poetic literature. The first dated book printed in Hebrew was published by Abraham Garton in Reggio (Calabria, Italy) in 1475.[23] +With the rise of Zionism in the 19th century, the Hebrew language experienced a full-scale revival as a spoken and literary language. The creation of a modern version of the ancient language was led by Eliezer Ben-Yehuda. Modern Hebrew (Ivrit) became the main language of the Yishuv in Palestine, and subsequently the official language of the State of Israel. Estimates of worldwide usage include five million speakers in 1998,[4] and over nine million people in 2013.[24] After Israel, the United States has the largest Hebrew-speaking population, with approximately 220,000 fluent speakers (see Israeli Americans and Jewish Americans).[25] +Modern Hebrew is the official language of the State of Israel,[26][27] while pre-revival forms of Hebrew are used for prayer or study in Jewish and Samaritan communities around the world today; the latter group utilizes the Samaritan dialect as their liturgical tongue. As a non-first language, it is studied mostly by non-Israeli Jews and students in Israel, by archaeologists and linguists specializing in the Middle East and its civilizations, and by theologians in Christian seminaries. +""" + +SAMPLE_DATA = [ + LINCOLN_TOWN_CAR, + HEBREW, + APPLES, +] diff --git a/app/api/vector_db_control/documents.py b/app/api/vector_db_control/documents.py new file mode 100644 index 00000000..ae6fca93 --- /dev/null +++ b/app/api/vector_db_control/documents.py @@ -0,0 +1,13 @@ +from langchain_core.documents import Document +from langchain_text_splitters import RecursiveCharacterTextSplitter + + +def chunk_pdf_document(loaded_document, extraction_mode="layout", chunk_size=1000, chunk_overlap=100): + loaded_documents = [] + metadata = loaded_document.metadata + for page in loaded_document.pages: + loaded_documents.append( + Document(page_content=page.extract_text(extraction_mode=extraction_mode), metadata=metadata)) + text_splitter = RecursiveCharacterTextSplitter(chunk_size=chunk_size, chunk_overlap=chunk_overlap) + chunked_document = text_splitter.split_documents(loaded_documents) + return chunked_document diff --git a/app/api/vector_db_control/urls.py b/app/api/vector_db_control/urls.py new file mode 100644 index 00000000..090bbf8b --- /dev/null +++ b/app/api/vector_db_control/urls.py @@ -0,0 +1,11 @@ +from django.urls import path +from rest_framework import routers + +from .views import VectorCollectionsAPIView + +app_name = "rag" + +router = routers.DefaultRouter(trailing_slash=False) +router.register("", VectorCollectionsAPIView, basename="collections") + +urlpatterns = router.urls diff --git a/app/api/vector_db_control/views.py b/app/api/vector_db_control/views.py new file mode 100644 index 00000000..ad33db52 --- /dev/null +++ b/app/api/vector_db_control/views.py @@ -0,0 +1,83 @@ +import uuid +from typing import List + +import pypdf +import requests +from chromadb.types import Collection +from django.conf import settings +from rest_framework import status +from rest_framework.decorators import action +from rest_framework.response import Response +from rest_framework.viewsets import ViewSet + +from vector_db_control.chroma import list_collections, create_collection, get_collection, query_collection, \ + get_chroma_client, insert_to_chroma_collection, serialize_collection +from vector_db_control.documents import chunk_pdf_document + + +class VectorCollectionsAPIView(ViewSet): + EMBED_MODEL = None + chromadb_client = None + query_results_limit = 2 + + def __init__(self, **kwargs): + super().__init__(**kwargs) + self.chromadb_client = get_chroma_client( + port=settings.CHROMA_DB_PORT, + host=settings.CHROMA_DB_HOST, + ) + if hasattr(settings, 'CHROMA_DB_EMBED_MODEL'): + self.EMBED_MODEL = settings.CHROMA_DB_EMBED_MODEL + + def list(self, request): + collections: List[Collection] = list_collections(chroma_client=self.chromadb_client) + return Response(data=map(serialize_collection, collections)) + + def post(self, request): + name = request.data['name'] + collection = create_collection(chroma_client=self.chromadb_client, collection_name=name, + embedding_func_name=self.EMBED_MODEL, + metadata=request.data.get('metadata', dict())) + return Response(data=serialize_collection(collection)) + + def retrieve(self, request, pk=None): + if not pk: + return self.list(request) + collection = get_collection(chroma_client=self.chromadb_client, collection_name=pk, + embedding_func_name=self.EMBED_MODEL) + return Response(data=serialize_collection(collection)) + + @action(methods=["DELETE"], detail=True) + def delete(self, request, pk=None): + if not pk: + return Response(status=status.HTTP_500_INTERNAL_SERVER_ERROR, data={"error": "No collection name provided"}) + self.chromadb_client.delete_collection(name=pk) + return Response(status=200) + + @action(methods=["POST"], detail=True) + def insert_document(self, request, pk=None): + file = request.FILES["file"] + loaded_document = pypdf.PdfReader(stream=file) + chunks = chunk_pdf_document(loaded_document) + ids = [str(uuid.uuid4()) for i in range(0, len(chunks))] + documents = [chunk.page_content for chunk in chunks] + insert_to_chroma_collection( + collection_name=pk, + chroma_client=self.chromadb_client, + documents=documents, + ids=ids, + metadatas=[], + embedding_func_name=self.EMBED_MODEL + ) + + return Response(status=200) + + @action(methods=["GET"], detail=True, url_path='query') + def query(self, request, pk=None): + query = request.query_params.get('query') + if isinstance(query, str): + query = [query] + query_result = query_collection(chroma_client=self.chromadb_client, collection_name=pk, + embedding_func_name=self.EMBED_MODEL, + query_texts=query) + return Response(data=query_result) diff --git a/app/docker-compose.yml b/app/docker-compose.yml index 31536885..d00e5881 100644 --- a/app/docker-compose.yml +++ b/app/docker-compose.yml @@ -23,10 +23,15 @@ services: # command: ./manage.py runserver 0.0.0.0:8000 # gunicorn is used from production, supports streaming command: gunicorn --workers 3 --bind 0.0.0.0:8000 --timeout 1200 api.wsgi:application + depends_on: + tt_studio_chroma: + condition: service_healthy stdin_open: true tty: true environment: # env vars are defined in .env file, use .env.default as template + - CHROMA_DB_HOST=tt_studio_chroma + - CHROMA_DB_PORT=8111 - TT_STUDIO_ROOT - HOST_PERSISTENT_STORAGE_VOLUME - INTERNAL_PERSISTENT_STORAGE_VOLUME @@ -34,7 +39,8 @@ services: - JWT_SECRET volumes: # mounting docker unix socket allows for backend container to run docker cmds - - /var/run/docker.sock:/var/run/docker.sock + - /run/user/1000/docker.sock:/var/run/docker.sock + - /dev/hugepages-1G:/dev/hugepages-1g - ${HOST_PERSISTENT_STORAGE_VOLUME}:${INTERNAL_PERSISTENT_STORAGE_VOLUME} # for development mount api changes - ./api:/api @@ -54,6 +60,34 @@ services: # command: sh command: bash -c "npm i && npm run dev" + tt_studio_chroma: + image: chromadb/chroma:0.5.3 + volumes: + # Be aware that indexed data are located in "/chroma/chroma/" + # Default configuration for persist_directory in chromadb/config.py + # Read more about deployments: https://docs.trychroma.com/deployment + - ${HOST_PERSISTENT_STORAGE_VOLUME}/chroma:/chroma/chroma + command: "--workers 1 --host 0.0.0.0 --port 8111 --proxy-headers --log-config chromadb/log_config.yml --timeout-keep-alive 30" + environment: + - IS_PERSISTENT=TRUE + # - CHROMA_AUTH_TOKEN_TRANSPORT_HEADER=${CHROMA_AUTH_TOKEN_TRANSPORT_HEADER} + # - PERSIST_DIRECTORY=${INTERNAL_PERSISTENT_STORAGE_VOLUME}/chroma + - CHROMA_SERVER_CORS_ALLOW_ORIGINS=["http://localhost:3000", "http://tt_studio_frontend", "http://localhost:8000"] + restart: unless-stopped # possible values are: "no", always", "on-failure", "unless-stopped" + ports: + - "8111:8111" + healthcheck: + # Adjust below to match your container port + test: ["CMD", "curl", "-f", "http://localhost:8111/api/v1/heartbeat"] + interval: 10s + timeout: 10s + retries: 3 + container_name: tt_studio_chroma + + networks: + - llm_studio_network + + networks: llm_studio_network: # need external flag to allow for the backend to manage the docker network diff --git a/app/frontend/vite.config.ts b/app/frontend/vite.config.ts index a64521bb..d8fc8df3 100644 --- a/app/frontend/vite.config.ts +++ b/app/frontend/vite.config.ts @@ -10,6 +10,7 @@ const VITE_BACKEND_PROXY_MAPPING: { [key: string]: string } = { "docker-api": "docker", "models-api": "models", "app-api": "app", + "collections-api": "collections", }; const proxyConfig: Record = Object.fromEntries( From 2f24916d8901ea5f0b622379d2593b705f4f10f1 Mon Sep 17 00:00:00 2001 From: Greg Hatt Date: Thu, 5 Sep 2024 15:24:03 -0300 Subject: [PATCH 04/61] Adds depends_on for backend --- app/docker-compose.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/docker-compose.yml b/app/docker-compose.yml index d00e5881..5582fc98 100644 --- a/app/docker-compose.yml +++ b/app/docker-compose.yml @@ -50,6 +50,9 @@ services: hostname: tt-studio-frontend image: ghcr.io/tenstorrent/tt-studio/frontend:v0.0.0 build: ./frontend + depends_on: + tt_studio_backend: + condition: service_started networks: - llm_studio_network ports: @@ -87,7 +90,6 @@ services: networks: - llm_studio_network - networks: llm_studio_network: # need external flag to allow for the backend to manage the docker network From 94b8455db9eb808a647deb5a0bc53dec79476b4f Mon Sep 17 00:00:00 2001 From: Greg Hatt Date: Fri, 6 Sep 2024 12:00:36 -0300 Subject: [PATCH 05/61] Changes PDF parsing to use plain strategy --- app/api/vector_db_control/documents.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/api/vector_db_control/documents.py b/app/api/vector_db_control/documents.py index ae6fca93..abe72c07 100644 --- a/app/api/vector_db_control/documents.py +++ b/app/api/vector_db_control/documents.py @@ -2,7 +2,7 @@ from langchain_text_splitters import RecursiveCharacterTextSplitter -def chunk_pdf_document(loaded_document, extraction_mode="layout", chunk_size=1000, chunk_overlap=100): +def chunk_pdf_document(loaded_document, extraction_mode="plain", chunk_size=1000, chunk_overlap=100): loaded_documents = [] metadata = loaded_document.metadata for page in loaded_document.pages: From 1a0f4e2a387d47c6590683834113b2df031368bc Mon Sep 17 00:00:00 2001 From: Greg Hatt Date: Fri, 6 Sep 2024 12:04:43 -0300 Subject: [PATCH 06/61] Removes WIP prepopulate code --- app/api/api/settings.py | 1 - app/api/vector_db_control/apps.py | 28 ---------------------------- 2 files changed, 29 deletions(-) diff --git a/app/api/api/settings.py b/app/api/api/settings.py index bd630ad8..b49debb0 100644 --- a/app/api/api/settings.py +++ b/app/api/api/settings.py @@ -149,7 +149,6 @@ CHROMA_DB_PORT = int(os.environ.get('CHROMA_DB_PORT', 8111)) CHROMA_DB_HOST = os.environ.get('CHROMA_DB_HOST', 'tt_studio_chromadb') CHROMA_DB_EMBED_MODEL = "all-MiniLM-L6-v2" -PREPOPULATE_VECTOR_DB = True REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': [], diff --git a/app/api/vector_db_control/apps.py b/app/api/vector_db_control/apps.py index a8f93c44..777cae04 100644 --- a/app/api/vector_db_control/apps.py +++ b/app/api/vector_db_control/apps.py @@ -1,34 +1,6 @@ from django.apps import AppConfig -from shared_config.logger_config import get_logger -from vector_db_control.chroma import get_chroma_client - -logger = get_logger(__name__) -logger.info(f"importing {__name__}") -prepopulated_db = False - class VectorDbConfig(AppConfig): name = 'vector_db_control' default_auto_field = "django.db.models.BigAutoField" - def ready(self): - from django.conf import settings - from chromadb.utils import embedding_functions - from vector_db_control.data import SAMPLE_DATA - prepopulated_db_name = "prepopulated_db" - chroma_db_host = settings.CHROMA_DB_HOST - chroma_db_port = settings.CHROMA_DB_PORT - global prepopulated_db - if bool(settings.PREPOPULATE_VECTOR_DB) and not prepopulated_db: - client = get_chroma_client(host=chroma_db_host, port=chroma_db_port) - embedding_func = embedding_functions.SentenceTransformerEmbeddingFunction( - model_name=settings.CHROMA_DB_EMBED_MODEL, - ) - documents = SAMPLE_DATA - ids = [str(i) for i in range(0, len(documents))] - collection = client.get_or_create_collection( - name=prepopulated_db_name, - embedding_function=embedding_func, - ) - collection.upsert(documents=documents, ids=ids, metadatas=None) - prepopulated_db = True From 9ec83d0c3891b3077e9481ef813f2d9588cf3ee7 Mon Sep 17 00:00:00 2001 From: Greg Hatt Date: Fri, 6 Sep 2024 12:13:38 -0300 Subject: [PATCH 07/61] Removes duplicate pyjwt dependency --- app/api/requirements.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/app/api/requirements.txt b/app/api/requirements.txt index 88ee87b7..34ad2291 100644 --- a/app/api/requirements.txt +++ b/app/api/requirements.txt @@ -1,5 +1,4 @@ Django==5.0.4 -PyJWT==2.7.0 django-cors-headers==4.3.1 djangorestframework==3.14.0 docker==7.0.0 From 68c549e27d5dd7d0ca715bc752996114797fa555 Mon Sep 17 00:00:00 2001 From: Greg Hatt Date: Fri, 6 Sep 2024 12:18:57 -0300 Subject: [PATCH 08/61] Restores docker-compose.yml to match staging --- app/docker-compose.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/docker-compose.yml b/app/docker-compose.yml index 5582fc98..8c095a53 100644 --- a/app/docker-compose.yml +++ b/app/docker-compose.yml @@ -39,8 +39,7 @@ services: - JWT_SECRET volumes: # mounting docker unix socket allows for backend container to run docker cmds - - /run/user/1000/docker.sock:/var/run/docker.sock - - /dev/hugepages-1G:/dev/hugepages-1g + - /var/run/docker.sock:/var/run/docker.sock - ${HOST_PERSISTENT_STORAGE_VOLUME}:${INTERNAL_PERSISTENT_STORAGE_VOLUME} # for development mount api changes - ./api:/api From 62151e3e2ac705eb3da6073947ac8743773a4a03 Mon Sep 17 00:00:00 2001 From: Greg Hatt Date: Mon, 9 Sep 2024 12:26:18 -0300 Subject: [PATCH 09/61] Adds singletons for Chroma client and embedding function --- app/api/vector_db_control/singletons.py | 46 +++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 app/api/vector_db_control/singletons.py diff --git a/app/api/vector_db_control/singletons.py b/app/api/vector_db_control/singletons.py new file mode 100644 index 00000000..ffad698c --- /dev/null +++ b/app/api/vector_db_control/singletons.py @@ -0,0 +1,46 @@ +from threading import Lock +from typing import Optional + +from chromadb import HttpClient, Settings, ClientAPI +from chromadb.utils import embedding_functions + +from shared_config.logger_config import get_logger + +logger = get_logger(__name__) + +# Dictionary to store singleton instances +_instances = {} +# Lock for thread safety during initialization +_lock = Lock() + + +def get_embedding_function(model_name: str): + """ + Returns the singleton instance of the SentenceTransformer model. + Ensures that the model is loaded only once in a thread-safe manner. + """ + + # Check if the model instance already exists + if model_name not in _instances: + with _lock: # Ensure that only one thread can initialize the model + # Double-check pattern to avoid race condition + if model_name not in _instances: + _instances[model_name] = embedding_functions.SentenceTransformerEmbeddingFunction( + model_name=model_name + ) + + return _instances[model_name] + + +class ChromaClient: + _instance: Optional[ClientAPI] = None + _lock = Lock() + + def __new__(cls, host=None, port=None): + if cls._instance is None: + with cls._lock: + if cls._instance is None: + logger.info(f"Initializing ChromaDB connection {host}:{port}") + cls._instance = HttpClient(host=host, port=port, + settings=Settings()) + return cls._instance From 93465af9319c17529a7106132bc03cf4e946ddc9 Mon Sep 17 00:00:00 2001 From: Greg Hatt Date: Mon, 9 Sep 2024 12:26:48 -0300 Subject: [PATCH 10/61] Initializes Chroma/embed model in apps ready call --- app/api/vector_db_control/apps.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/app/api/vector_db_control/apps.py b/app/api/vector_db_control/apps.py index 777cae04..110da1b4 100644 --- a/app/api/vector_db_control/apps.py +++ b/app/api/vector_db_control/apps.py @@ -1,6 +1,16 @@ from django.apps import AppConfig +from shared_config.logger_config import get_logger +logger = get_logger(__name__) +from vector_db_control.singletons import ChromaClient, get_embedding_function class VectorDbConfig(AppConfig): name = 'vector_db_control' default_auto_field = "django.db.models.BigAutoField" + def ready(self): + from django.conf import settings + logger.info(f"{__name__} ready.") + # Preload the singleton to initialize the model at startup + get_embedding_function(model_name=settings.CHROMA_DB_EMBED_MODEL) + ChromaClient(host=settings.CHROMA_DB_HOST, port=settings.CHROMA_DB_PORT) + From a051f771a5c38e299741e497840abf34a479f468 Mon Sep 17 00:00:00 2001 From: Greg Hatt Date: Mon, 9 Sep 2024 12:27:12 -0300 Subject: [PATCH 11/61] Updates views/chroma to use new singletons --- app/api/vector_db_control/chroma.py | 54 ++++++++++++----------------- app/api/vector_db_control/views.py | 22 +++++------- 2 files changed, 30 insertions(+), 46 deletions(-) diff --git a/app/api/vector_db_control/chroma.py b/app/api/vector_db_control/chroma.py index c14a8335..21cdd3c4 100644 --- a/app/api/vector_db_control/chroma.py +++ b/app/api/vector_db_control/chroma.py @@ -2,67 +2,58 @@ from itertools import batched from typing import List -import chromadb -from chromadb import ClientAPI -from chromadb.config import Settings from chromadb.types import Collection -from chromadb.utils import embedding_functions +# your_app/singleton.py from shared_config.logger_config import get_logger -chromadb_client = None - logger = get_logger(__name__) +from vector_db_control.singletons import ChromaClient, get_embedding_function -def get_chroma_client(host: str, port: int, username=None, password=None): - global chromadb_client - logger.info(f"Attempting to connect to ChromaDB at {host}:{port}") - if not chromadb_client: - chromadb_client = chromadb.HttpClient(host=host, port=port, - settings=Settings()) - return chromadb_client - - -def list_collections(chroma_client: ClientAPI, filter_func=None): - chroma_collections = chroma_client.list_collections() +def list_collections(filter_func=None): + chroma_collections = ChromaClient().list_collections() if filter_func: return filter(filter_func, chroma_collections) return chroma_collections -def get_collection(chroma_client: ClientAPI, collection_name: str, embedding_func_name: str): - embedding_func = embedding_functions.SentenceTransformerEmbeddingFunction( +def delete_collection(collection_name: str): + ChromaClient().delete_collection(name=collection_name) + + +def get_collection(collection_name: str, embedding_func_name: str): + embedding_func = get_embedding_function( model_name=embedding_func_name ) - return chroma_client.get_collection(name=collection_name, embedding_function=embedding_func) + return ChromaClient().get_collection(name=collection_name, embedding_function=embedding_func) -def create_collection(chroma_client: ClientAPI, collection_name: str, embedding_func_name: str, +def create_collection(collection_name: str, embedding_func_name: str, metadata=None, distance_func_name: str = "cosine"): # Metadata could be used in the future to filter our collections. # For instance - ` metadata = { 'target_models' : "X, Y, Z" } - embedding_func = embedding_functions.SentenceTransformerEmbeddingFunction( + embedding_func = get_embedding_function( model_name=embedding_func_name ) metadata = metadata or {} metadata.update({"hnsw:space": distance_func_name, "embedding_func_name": embedding_func_name}) metadata.update({"created_at": datetime.now()}) - return chroma_client.create_collection(name=collection_name, embedding_function=embedding_func, metadata=metadata) + return ChromaClient().create_collection(name=collection_name, embedding_function=embedding_func, metadata=metadata) -def delete_collection(chroma_client: ClientAPI, collection_name: str): - if not chroma_client.get_collection(collection_name): +def delete_collection(collection_name: str): + if not ChromaClient().get_collection(collection_name): raise ValueError('Collection does not exist') - chroma_client.delete_collection(collection_name) + ChromaClient().delete_collection(collection_name) -def query_collection(chroma_client: ClientAPI, collection_name: str, embedding_func_name: str, +def query_collection(collection_name: str, embedding_func_name: str, query_texts: List[str]): - embedding_func = embedding_functions.SentenceTransformerEmbeddingFunction( + embedding_func = get_embedding_function( model_name=embedding_func_name ) - target_collection = chroma_client.get_collection(name=collection_name, embedding_function=embedding_func) + target_collection = ChromaClient().get_collection(name=collection_name, embedding_function=embedding_func) return target_collection.query(query_texts=query_texts) @@ -75,7 +66,6 @@ def serialize_collection(collection: Collection): def insert_to_chroma_collection( - chroma_client: ClientAPI, collection_name: str, embedding_func_name: str, ids: list[str], @@ -83,11 +73,11 @@ def insert_to_chroma_collection( metadatas: list[dict], ): - embedding_func = embedding_functions.SentenceTransformerEmbeddingFunction( + embedding_func = get_embedding_function( model_name=embedding_func_name ) - target_collection = chroma_client.get_collection( + target_collection = ChromaClient().get_collection( name=collection_name, embedding_function=embedding_func, ) diff --git a/app/api/vector_db_control/views.py b/app/api/vector_db_control/views.py index ad33db52..1072b1fe 100644 --- a/app/api/vector_db_control/views.py +++ b/app/api/vector_db_control/views.py @@ -2,7 +2,6 @@ from typing import List import pypdf -import requests from chromadb.types import Collection from django.conf import settings from rest_framework import status @@ -11,7 +10,7 @@ from rest_framework.viewsets import ViewSet from vector_db_control.chroma import list_collections, create_collection, get_collection, query_collection, \ - get_chroma_client, insert_to_chroma_collection, serialize_collection + insert_to_chroma_collection, serialize_collection, delete_collection from vector_db_control.documents import chunk_pdf_document @@ -22,28 +21,24 @@ class VectorCollectionsAPIView(ViewSet): def __init__(self, **kwargs): super().__init__(**kwargs) - self.chromadb_client = get_chroma_client( - port=settings.CHROMA_DB_PORT, - host=settings.CHROMA_DB_HOST, - ) if hasattr(settings, 'CHROMA_DB_EMBED_MODEL'): self.EMBED_MODEL = settings.CHROMA_DB_EMBED_MODEL def list(self, request): - collections: List[Collection] = list_collections(chroma_client=self.chromadb_client) + collections: List[Collection] = list_collections() return Response(data=map(serialize_collection, collections)) def post(self, request): name = request.data['name'] - collection = create_collection(chroma_client=self.chromadb_client, collection_name=name, - embedding_func_name=self.EMBED_MODEL, - metadata=request.data.get('metadata', dict())) + collection = create_collection(collection_name=name, + metadata=request.data.get('metadata', dict()), + embedding_func_name=self.EMBED_MODEL) return Response(data=serialize_collection(collection)) def retrieve(self, request, pk=None): if not pk: return self.list(request) - collection = get_collection(chroma_client=self.chromadb_client, collection_name=pk, + collection = get_collection(collection_name=pk, embedding_func_name=self.EMBED_MODEL) return Response(data=serialize_collection(collection)) @@ -51,7 +46,7 @@ def retrieve(self, request, pk=None): def delete(self, request, pk=None): if not pk: return Response(status=status.HTTP_500_INTERNAL_SERVER_ERROR, data={"error": "No collection name provided"}) - self.chromadb_client.delete_collection(name=pk) + delete_collection(collection_name=pk) return Response(status=200) @action(methods=["POST"], detail=True) @@ -63,7 +58,6 @@ def insert_document(self, request, pk=None): documents = [chunk.page_content for chunk in chunks] insert_to_chroma_collection( collection_name=pk, - chroma_client=self.chromadb_client, documents=documents, ids=ids, metadatas=[], @@ -77,7 +71,7 @@ def query(self, request, pk=None): query = request.query_params.get('query') if isinstance(query, str): query = [query] - query_result = query_collection(chroma_client=self.chromadb_client, collection_name=pk, + query_result = query_collection(collection_name=pk, embedding_func_name=self.EMBED_MODEL, query_texts=query) return Response(data=query_result) From 4425474ff2b8c50567b586487ec97ba5e9092963 Mon Sep 17 00:00:00 2001 From: Greg Hatt Date: Wed, 11 Sep 2024 10:56:05 -0300 Subject: [PATCH 12/61] Fixes base image version issue from rebase --- app/api/Dockerfile | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/app/api/Dockerfile b/app/api/Dockerfile index 20a5ea24..1a0a33b2 100644 --- a/app/api/Dockerfile +++ b/app/api/Dockerfile @@ -4,7 +4,6 @@ FROM python:3.12.5-slim-bookworm -FROM python:3.12.1-slim-bullseye ENV PYTHONUNBUFFERED=1 EXPOSE 8000 @@ -21,10 +20,10 @@ RUN apt-get update && \ rm -rf /var/lib/apt/lists/* RUN apt-get update && \ - apt-get install -y \ - git \ - curl \ - cargo + apt-get install -y \ + git \ + curl \ + cargo # Install Rust RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y @@ -34,10 +33,10 @@ ENV PATH="/root/.cargo/bin:${PATH}" # Clone and install tt-smi RUN git clone https://github.com/tenstorrent/tt-smi /tmp/tt-smi && \ - cd /tmp/tt-smi && \ - pip3 install . + cd /tmp/tt-smi && \ + pip3 install . WORKDIR /api COPY ./requirements.txt /api RUN pip3 install -r requirements.txt --no-cache-dir -COPY . /api \ No newline at end of file +COPY . /api From 63999f2a5fcdf6b4eebf314df2d3c692be286a1e Mon Sep 17 00:00:00 2001 From: Greg Hatt Date: Wed, 11 Sep 2024 11:20:17 -0300 Subject: [PATCH 13/61] Fixes issue of first-run failure --- app/docker-compose.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/app/docker-compose.yml b/app/docker-compose.yml index 8c095a53..9af6e74f 100644 --- a/app/docker-compose.yml +++ b/app/docker-compose.yml @@ -11,8 +11,8 @@ services: build: ./api # uncomment devices to use Tenstorrent hardware # devices: - # mount all tenstorrent devices to backend container - # - /dev/tenstorrent:/dev/tenstorrent + # mount all tenstorrent devices to backend container + # - /dev/tenstorrent:/dev/tenstorrent # note that `network_mode: host` does not work on mac OS networks: - llm_studio_network @@ -22,7 +22,8 @@ services: # dev server can be used for breakpoint debugging, does not support streaming # command: ./manage.py runserver 0.0.0.0:8000 # gunicorn is used from production, supports streaming - command: gunicorn --workers 3 --bind 0.0.0.0:8000 --timeout 1200 api.wsgi:application + + command: gunicorn --workers 3 --bind 0.0.0.0:8000 --preload --timeout 1200 api.wsgi:application depends_on: tt_studio_chroma: condition: service_healthy From 8cba590913806567876029b993a9adc178dda0ff Mon Sep 17 00:00:00 2001 From: Greg Hatt Date: Wed, 11 Sep 2024 11:43:29 -0300 Subject: [PATCH 14/61] Adds an up status endpoint --- app/api/api/urls.py | 2 ++ app/api/api/views.py | 6 ++++++ 2 files changed, 8 insertions(+) create mode 100644 app/api/api/views.py diff --git a/app/api/api/urls.py b/app/api/api/urls.py index 0319ba2a..28e6d331 100644 --- a/app/api/api/urls.py +++ b/app/api/api/urls.py @@ -20,10 +20,12 @@ """ from django.contrib import admin +from api.views import UpStatusView from django.urls import include, path urlpatterns = [ path("admin/", admin.site.urls), + path("up/", UpStatusView.as_view()), path("docker/", include("docker_control.urls")), path("models/", include("model_control.urls")), path('reset_board/', include('docker_control.urls')), diff --git a/app/api/api/views.py b/app/api/api/views.py new file mode 100644 index 00000000..395fada7 --- /dev/null +++ b/app/api/api/views.py @@ -0,0 +1,6 @@ +from rest_framework.views import APIView +from rest_framework.response import Response + +class UpStatusView(APIView): + def get(self, request, *args, **kwargs): + return Response(status=200) \ No newline at end of file From 8ed3932cc8e75de1c1cff6b72053057b47f9cff5 Mon Sep 17 00:00:00 2001 From: Greg Hatt Date: Wed, 11 Sep 2024 11:44:30 -0300 Subject: [PATCH 15/61] Adds service healthy check for backend API --- app/docker-compose.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/docker-compose.yml b/app/docker-compose.yml index 9af6e74f..e0bfb9b3 100644 --- a/app/docker-compose.yml +++ b/app/docker-compose.yml @@ -44,6 +44,12 @@ services: - ${HOST_PERSISTENT_STORAGE_VOLUME}:${INTERNAL_PERSISTENT_STORAGE_VOLUME} # for development mount api changes - ./api:/api + healthcheck: + # Adjust below to match your container port + test: ["CMD", "curl", "-f", "http://localhost:8000/up"] + interval: 10s + timeout: 10s + retries: 3 tt_studio_frontend: container_name: tt_studio_frontend @@ -52,7 +58,7 @@ services: build: ./frontend depends_on: tt_studio_backend: - condition: service_started + condition: service_healthy networks: - llm_studio_network ports: From f55bbd1e7990ae3925636d97fe24a8d96c694f1f Mon Sep 17 00:00:00 2001 From: Greg Hatt Date: Mon, 16 Sep 2024 10:59:28 -0300 Subject: [PATCH 16/61] Changes backend API healthcheck to be more tolerant --- app/docker-compose.yml | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/app/docker-compose.yml b/app/docker-compose.yml index e0bfb9b3..2f783e90 100644 --- a/app/docker-compose.yml +++ b/app/docker-compose.yml @@ -44,12 +44,15 @@ services: - ${HOST_PERSISTENT_STORAGE_VOLUME}:${INTERNAL_PERSISTENT_STORAGE_VOLUME} # for development mount api changes - ./api:/api + healthcheck: - # Adjust below to match your container port - test: ["CMD", "curl", "-f", "http://localhost:8000/up"] + # On first application load resources for transformers/etc + # are downloaded. The UI should not start until these resources + # have been downloaded. Adjust timeout if on a very slow connection + test: ["CMD", "curl", "-f", "http://localhost:8000/up/"] + timeout: 120s interval: 10s - timeout: 10s - retries: 3 + retries: 5 tt_studio_frontend: container_name: tt_studio_frontend From bc6ad3678109167402c1906d02157ab812742f30 Mon Sep 17 00:00:00 2001 From: Greg Hatt Date: Fri, 6 Sep 2024 11:44:18 -0300 Subject: [PATCH 17/61] Adds react-query, alert-dialog to packages --- app/frontend/package-lock.json | 147 +++++++++++++++++++++++++++++---- app/frontend/package.json | 1 + 2 files changed, 133 insertions(+), 15 deletions(-) diff --git a/app/frontend/package-lock.json b/app/frontend/package-lock.json index 2214b56e..225d640e 100644 --- a/app/frontend/package-lock.json +++ b/app/frontend/package-lock.json @@ -10,6 +10,7 @@ "dependencies": { "@hookform/resolvers": "^3.3.4", "@radix-ui/react-accordion": "^1.2.0", + "@radix-ui/react-alert-dialog": "^1.1.1", "@radix-ui/react-aspect-ratio": "^1.1.0", "@radix-ui/react-collapsible": "^1.0.3", "@radix-ui/react-dialog": "^1.0.5", @@ -38,6 +39,7 @@ "react-dom": "^18.2.0", "react-hook-form": "^7.51.4", "react-hot-toast": "^2.4.1", + "react-query": "^3.39.3", "react-router-dom": "^6.23.0", "tailwind-merge": "^2.3.0", "tailwindcss-animate": "^1.0.7", @@ -1308,6 +1310,33 @@ } } }, + "node_modules/@radix-ui/react-alert-dialog": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-alert-dialog/-/react-alert-dialog-1.1.1.tgz", + "integrity": "sha512-wmCoJwj7byuVuiLKqDLlX7ClSUU0vd9sdCeM+2Ls+uf13+cpSJoMgwysHq1SGVVkJj5Xn0XWi1NoRCdkMpr6Mw==", + "dependencies": { + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-dialog": "1.1.1", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-slot": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-arrow": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.0.tgz", @@ -3279,6 +3308,14 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, + "node_modules/big-integer": { + "version": "1.6.52", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz", + "integrity": "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==", + "engines": { + "node": ">=0.6" + } + }, "node_modules/binary-extensions": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", @@ -3320,6 +3357,21 @@ "node": ">=8" } }, + "node_modules/broadcast-channel": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/broadcast-channel/-/broadcast-channel-3.7.0.tgz", + "integrity": "sha512-cIAKJXAxGJceNZGTZSBzMxzyOn72cVgPnKx4dc6LRjQgbaJUQqhy5rzL3zbMxkMWsGKkv2hSFkPRMEXfoMZ2Mg==", + "dependencies": { + "@babel/runtime": "^7.7.2", + "detect-node": "^2.1.0", + "js-sha3": "0.8.0", + "microseconds": "0.2.0", + "nano-time": "1.0.0", + "oblivious-set": "1.0.0", + "rimraf": "3.0.2", + "unload": "2.2.0" + } + }, "node_modules/browserslist": { "version": "4.23.2", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.2.tgz", @@ -4041,8 +4093,7 @@ "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, "node_modules/cosmiconfig": { "version": "9.0.0", @@ -4205,6 +4256,11 @@ "node": ">=0.4.0" } }, + "node_modules/detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==" + }, "node_modules/detect-node-es": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", @@ -4860,8 +4916,7 @@ "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, "node_modules/fsevents": { "version": "2.3.3", @@ -4957,7 +5012,6 @@ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -4988,7 +5042,6 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -4998,7 +5051,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -5251,7 +5303,6 @@ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", - "dev": true, "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -5260,8 +5311,7 @@ "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "node_modules/ini": { "version": "4.1.3", @@ -5462,6 +5512,11 @@ "jiti": "bin/jiti.js" } }, + "node_modules/js-sha3": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -5693,6 +5748,15 @@ "node": "^16.14.0 || >=18.0.0" } }, + "node_modules/match-sorter": { + "version": "6.3.4", + "resolved": "https://registry.npmjs.org/match-sorter/-/match-sorter-6.3.4.tgz", + "integrity": "sha512-jfZW7cWS5y/1xswZo8VBOdudUiSd9nifYRWphc9M5D/ee4w4AoXLgBEdRbgVaxbMuagBPeUC5y2Hi8DO6o9aDg==", + "dependencies": { + "@babel/runtime": "^7.23.8", + "remove-accents": "0.5.0" + } + }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -5713,6 +5777,11 @@ "node": ">=8.6" } }, + "node_modules/microseconds": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/microseconds/-/microseconds-0.2.0.tgz", + "integrity": "sha512-n7DHHMjR1avBbSpsTBj6fmMGh2AGrifVV4e+WYc3Q9lO+xnSZ3NyhcBND3vzzatt05LFhoKFRxrIyklmLlUtyA==" + }, "node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", @@ -5925,6 +5994,14 @@ "thenify-all": "^1.0.0" } }, + "node_modules/nano-time": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/nano-time/-/nano-time-1.0.0.tgz", + "integrity": "sha512-flnngywOoQ0lLQOTRNexn2gGSNuM9bKj9RZAWSzhQ+UJYaAFG9bac4DW9VHjUAzrOaIcajHybCTHe/bkvozQqA==", + "dependencies": { + "big-integer": "^1.6.16" + } + }, "node_modules/nanoid": { "version": "3.3.7", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", @@ -6187,11 +6264,15 @@ "node": ">= 6" } }, + "node_modules/oblivious-set": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/oblivious-set/-/oblivious-set-1.0.0.tgz", + "integrity": "sha512-z+pI07qxo4c2CulUHCDf9lcqDlMSo72N/4rLUpRXf6fu+q8vjt8y0xS+Tlf8NTJDdTXHbdeO1n3MlbctwEoXZw==" + }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, "dependencies": { "wrappy": "1" } @@ -6412,7 +6493,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -6848,6 +6928,31 @@ "react-dom": ">=16" } }, + "node_modules/react-query": { + "version": "3.39.3", + "resolved": "https://registry.npmjs.org/react-query/-/react-query-3.39.3.tgz", + "integrity": "sha512-nLfLz7GiohKTJDuT4us4X3h/8unOh+00MLb2yJoGTPjxKs2bc1iDhkNx2bd5MKklXnOD3NrVZ+J2UXujA5In4g==", + "dependencies": { + "@babel/runtime": "^7.5.5", + "broadcast-channel": "^3.4.1", + "match-sorter": "^6.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + } + } + }, "node_modules/react-remove-scroll": { "version": "2.5.7", "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.7.tgz", @@ -7042,6 +7147,11 @@ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" }, + "node_modules/remove-accents": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/remove-accents/-/remove-accents-0.5.0.tgz", + "integrity": "sha512-8g3/Otx1eJaVD12e31UbJj1YzdtVvzH85HV7t+9MJYk/u3XmkOUJ5Ys9wQrf9PCPK8+xn4ymzqYCiZl6QWKn+A==" + }, "node_modules/resolve": { "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", @@ -7109,7 +7219,6 @@ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, "dependencies": { "glob": "^7.1.3" }, @@ -7939,6 +8048,15 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, + "node_modules/unload": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/unload/-/unload-2.2.0.tgz", + "integrity": "sha512-B60uB5TNBLtN6/LsgAf3udH9saB5p7gqJwcFfbOEZ8BcBHnGwCf6G/TGiEqkRAxX7zAFIUtzdrXQSdL3Q/wqNA==", + "dependencies": { + "@babel/runtime": "^7.6.2", + "detect-node": "^2.0.4" + } + }, "node_modules/update-browserslist-db": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", @@ -8245,8 +8363,7 @@ "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "node_modules/write-file-atomic": { "version": "5.0.1", diff --git a/app/frontend/package.json b/app/frontend/package.json index 3debca3f..8f1ee687 100644 --- a/app/frontend/package.json +++ b/app/frontend/package.json @@ -41,6 +41,7 @@ "react-dom": "^18.2.0", "react-hook-form": "^7.51.4", "react-hot-toast": "^2.4.1", + "react-query": "^3.39.3", "react-router-dom": "^6.23.0", "tailwind-merge": "^2.3.0", "tailwindcss-animate": "^1.0.7", From 5dbec2172e6f3c81ab04cf840f4ea1998ec7d56b Mon Sep 17 00:00:00 2001 From: Greg Hatt Date: Fri, 6 Sep 2024 11:44:46 -0300 Subject: [PATCH 18/61] Updates vite config to match TS config `@` alias --- app/frontend/vite.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/frontend/vite.config.ts b/app/frontend/vite.config.ts index d8fc8df3..d2dcb55f 100644 --- a/app/frontend/vite.config.ts +++ b/app/frontend/vite.config.ts @@ -69,7 +69,7 @@ export default defineConfig({ plugins: [react()], resolve: { alias: { - "@": path.resolve(__dirname, "./src"), + "@": path.resolve(__dirname), }, }, server: { From 8d24a0c4c885fad73a68a8e3c61798eb99a9c53d Mon Sep 17 00:00:00 2001 From: Greg Hatt Date: Fri, 6 Sep 2024 11:47:02 -0300 Subject: [PATCH 19/61] Adds Axios functions for rag management --- app/frontend/src/pages/rag/index.ts | 39 +++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 app/frontend/src/pages/rag/index.ts diff --git a/app/frontend/src/pages/rag/index.ts b/app/frontend/src/pages/rag/index.ts new file mode 100644 index 00000000..64132df8 --- /dev/null +++ b/app/frontend/src/pages/rag/index.ts @@ -0,0 +1,39 @@ +import axios from "axios"; + +const collectionsAPIURL = "/collections-api"; + +export const fetchCollections = async () => { + const response = await axios.get(`${collectionsAPIURL}/`); + console.log(response); + if (response?.data) { + return response.data; + } + return []; +}; + +export const createCollection = ({ + collectionName, +}: { + collectionName: string; +}) => axios.post(`${collectionsAPIURL}/`, { name: collectionName }); + +export const deleteCollection = async ({ + collectionName, +}: { + collectionName: string; +}) => { + return axios.delete(`${collectionsAPIURL}/${collectionName}`); +}; + +export const uploadDocument = async ({ + file, + collectionName, +}: { + file: File; + collectionName: string; +}) => { + return axios.postForm( + `${collectionsAPIURL}/${collectionName}/insert_document`, + { file } + ); +}; From 7a43652929379cb45f983b78195d48849c513ba2 Mon Sep 17 00:00:00 2001 From: Greg Hatt Date: Fri, 6 Sep 2024 11:53:16 -0300 Subject: [PATCH 20/61] Adds react-query provider --- app/frontend/src/App.tsx | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/app/frontend/src/App.tsx b/app/frontend/src/App.tsx index 11c2dc32..be57984f 100644 --- a/app/frontend/src/App.tsx +++ b/app/frontend/src/App.tsx @@ -3,12 +3,20 @@ import "./App.css"; import { ThemeProvider } from "./providers/ThemeProvider"; import AppRouter from "./routes/index.tsx"; +import { QueryClient, QueryClientProvider } from "react-query"; function App() { + + const client = new QueryClient({ + defaultOptions: {}, + }); + return ( <> {/*
*/} - + + + {/*
*/}
From c4d27014f945109022f10db7822c62abb19af9de Mon Sep 17 00:00:00 2001 From: Greg Hatt Date: Fri, 6 Sep 2024 11:54:02 -0300 Subject: [PATCH 21/61] Adds confirm dialog component --- app/frontend/package.json | 1 + app/frontend/src/components/ConfirmDialog.tsx | 44 ++++++ .../src/components/ui/alert-dialog.tsx | 139 ++++++++++++++++++ 3 files changed, 184 insertions(+) create mode 100644 app/frontend/src/components/ConfirmDialog.tsx create mode 100644 app/frontend/src/components/ui/alert-dialog.tsx diff --git a/app/frontend/package.json b/app/frontend/package.json index 8f1ee687..a89bc6a0 100644 --- a/app/frontend/package.json +++ b/app/frontend/package.json @@ -13,6 +13,7 @@ "dependencies": { "@hookform/resolvers": "^3.3.4", "@radix-ui/react-accordion": "^1.2.0", + "@radix-ui/react-alert-dialog": "^1.1.1", "@radix-ui/react-aspect-ratio": "^1.1.0", "@radix-ui/react-collapsible": "^1.0.3", "@radix-ui/react-dialog": "^1.0.5", diff --git a/app/frontend/src/components/ConfirmDialog.tsx b/app/frontend/src/components/ConfirmDialog.tsx new file mode 100644 index 00000000..871e5ff7 --- /dev/null +++ b/app/frontend/src/components/ConfirmDialog.tsx @@ -0,0 +1,44 @@ +import { + AlertDialog, + AlertDialogAction, + AlertDialogCancel, + AlertDialogContent, + AlertDialogDescription, + AlertDialogFooter, + AlertDialogHeader, + AlertDialogTitle, + AlertDialogTrigger, +} from "@/src/components/ui/alert-dialog"; +export function ConfirmDialog({ + alertTrigger, + dialogTitle, + dialogDescription, + onConfirm, + cancelText, + confirmText, + }: { + cancelText?: string, + confirmText?: string, + dialogTitle: string, + dialogDescription: string, + alertTrigger: React.ReactNode; + onConfirm: React.MouseEventHandler; + }) { + return ( + + {alertTrigger} + + + {dialogTitle} + + {dialogDescription} + + + + {cancelText || 'Cancel'} + {confirmText || 'Continue'} + + + + ); + } \ No newline at end of file diff --git a/app/frontend/src/components/ui/alert-dialog.tsx b/app/frontend/src/components/ui/alert-dialog.tsx new file mode 100644 index 00000000..7e9f7a52 --- /dev/null +++ b/app/frontend/src/components/ui/alert-dialog.tsx @@ -0,0 +1,139 @@ +import * as React from "react" +import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog" + +import { cn } from "@/src/lib/utils" +import { buttonVariants } from "@/src/components/ui/button" + +const AlertDialog = AlertDialogPrimitive.Root + +const AlertDialogTrigger = AlertDialogPrimitive.Trigger + +const AlertDialogPortal = AlertDialogPrimitive.Portal + +const AlertDialogOverlay = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +AlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName + +const AlertDialogContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + + + + +)) +AlertDialogContent.displayName = AlertDialogPrimitive.Content.displayName + +const AlertDialogHeader = ({ + className, + ...props +}: React.HTMLAttributes) => ( +
+) +AlertDialogHeader.displayName = "AlertDialogHeader" + +const AlertDialogFooter = ({ + className, + ...props +}: React.HTMLAttributes) => ( +
+) +AlertDialogFooter.displayName = "AlertDialogFooter" + +const AlertDialogTitle = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +AlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName + +const AlertDialogDescription = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +AlertDialogDescription.displayName = + AlertDialogPrimitive.Description.displayName + +const AlertDialogAction = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +AlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName + +const AlertDialogCancel = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +AlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName + +export { + AlertDialog, + AlertDialogPortal, + AlertDialogOverlay, + AlertDialogTrigger, + AlertDialogContent, + AlertDialogHeader, + AlertDialogFooter, + AlertDialogTitle, + AlertDialogDescription, + AlertDialogAction, + AlertDialogCancel, +} From 4b07ac0233dfe117b88d7c8d30d7dded6e784e24 Mon Sep 17 00:00:00 2001 From: Greg Hatt Date: Fri, 6 Sep 2024 11:55:41 -0300 Subject: [PATCH 22/61] Adds form for creating new data source --- .../src/pages/rag/RagDataSourceForm.tsx | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 app/frontend/src/pages/rag/RagDataSourceForm.tsx diff --git a/app/frontend/src/pages/rag/RagDataSourceForm.tsx b/app/frontend/src/pages/rag/RagDataSourceForm.tsx new file mode 100644 index 00000000..8261c09e --- /dev/null +++ b/app/frontend/src/pages/rag/RagDataSourceForm.tsx @@ -0,0 +1,46 @@ +import { Button } from "@/src/components/ui/button"; +import { Input } from "@/src/components/ui/input"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { useForm } from "react-hook-form"; +import { z } from "zod"; + +const RagDataSourceForm = ({ + onSubmit, +}: { + onSubmit: ({ collectionName }: { collectionName: string }) => void; +}) => { + const formSchema = z.object({ + name: z + .string() + .min(2, { + message: "Collection name must be at least 2 characters.", + }) + .regex(new RegExp(/^\S+$/), { + message: "Collection name can not contain spaces", + }), + }); + + const { + register, + handleSubmit, + formState: { errors }, + } = useForm>({ + resolver: zodResolver(formSchema), + defaultValues: { name: "" }, + }); + + return ( +
+
onSubmit({ collectionName: d.name }))} + > + + +
+
{errors.name?.message &&

{errors.name?.message}

}
+
+ ); +}; + +export default RagDataSourceForm; From 64f479cc7e167b7fd8d43a22a1fa0fd470f24605 Mon Sep 17 00:00:00 2001 From: Greg Hatt Date: Fri, 6 Sep 2024 11:55:56 -0300 Subject: [PATCH 23/61] Adds route for RAG management --- app/frontend/src/routes/index.tsx | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/app/frontend/src/routes/index.tsx b/app/frontend/src/routes/index.tsx index e63fbae2..d9fef55d 100644 --- a/app/frontend/src/routes/index.tsx +++ b/app/frontend/src/routes/index.tsx @@ -7,18 +7,20 @@ import ModelsDeployed from "../pages/ModelsDeployed"; import NavBar from "../components/NavBar"; import ChatUI from "../pages/ChatUIPage"; import { RefreshProvider } from "../providers/RefreshContext"; +import RagManagement from "../pages/rag/RagManagement"; const AppRouter = () => { return ( - - - - } /> - } /> - } /> - - + + + + } /> + } /> + } /> + } /> + + ); }; From 4826bf946c00d786c3bb2f82d454f6e7a8182003 Mon Sep 17 00:00:00 2001 From: Greg Hatt Date: Fri, 6 Sep 2024 11:58:23 -0300 Subject: [PATCH 24/61] Adds page for managing RAG data sources --- app/frontend/src/pages/rag/RagManagement.tsx | 291 +++++++++++++++++++ 1 file changed, 291 insertions(+) create mode 100644 app/frontend/src/pages/rag/RagManagement.tsx diff --git a/app/frontend/src/pages/rag/RagManagement.tsx b/app/frontend/src/pages/rag/RagManagement.tsx new file mode 100644 index 00000000..6070a624 --- /dev/null +++ b/app/frontend/src/pages/rag/RagManagement.tsx @@ -0,0 +1,291 @@ +import { Button } from "@/src/components/ui/button"; +import { useMutation, useQuery, useQueryClient } from "react-query"; +import { Card } from "@/src/components/ui/card"; +import { ScrollArea, ScrollBar } from "@/src/components/ui/scroll-area"; +import { + Table, + TableBody, + TableCaption, + TableCell, + TableHead, + TableHeader, + TableRow, +} from "@/src/components/ui/table"; +import CopyableText from "@/src/components/CopyableText"; +import { useTheme } from "@/src/providers/ThemeProvider"; +import CustomToaster, { customToast } from "@/src/components/CustomToaster"; +import { useRef, useState } from "react"; +import RagDataSourceForm from "./RagDataSourceForm"; +import { Spinner } from "@/src/components/ui/spinner"; +import { ConfirmDialog } from "@/src/components/ConfirmDialog"; +import { + fetchCollections, + deleteCollection, + createCollection, + uploadDocument, +} from "."; + +interface RagDataSource { + id: string; + name: string; + metadata: Record; +} + +const TableWrapper = ({ children }: { children: React.ReactNode }) => { + return ( +
+
+
+ {children} +
+
+ ); +}; + +export default function RagManagement() { + const inputFile = useRef(null); + const queryClient = useQueryClient(); + + // Used to associate the hidden file input w/ the target collection + const [targetCollection, setTargetCollection] = useState< + RagDataSource | undefined + >(undefined); + + // Track which collections are being uploaded to + const [collectionsUploading, setCollectionsUploading] = useState( + [] + ); + + const { theme } = useTheme(); + + // Fetch collections + const { + data: ragDataSources, + // error, + // isLoading, + } = useQuery("collectionsList", { + queryFn: fetchCollections, + onError: () => customToast.error("Failed to fetch collections"), + }); + + // Delete mutation + const deleteCollectionMutation = useMutation({ + mutationFn: deleteCollection, + onError(error: Error, variables: { collectionName: string }) { + const { collectionName } = variables; + customToast.error(`Error deleting ${collectionName}: ${error}`); + }, + onSuccess: (_data, variables: { collectionName: string }) => { + customToast.success(`Deleted collection ${variables.collectionName}`); + queryClient.invalidateQueries(["collectionsList"]); + }, + }); + + // Create collection + const createCollectionMutation = useMutation({ + mutationFn: createCollection, + onSuccess: (_data, variables) => { + customToast.success( + `Created new collection: ${variables.collectionName}` + ); + queryClient.invalidateQueries(["collectionsList"]); + }, + }); + + // Upload to collection + const { mutate: uploadDocumentMutate } = useMutation({ + mutationFn: uploadDocument, + onMutate: ({ collectionName }) => { + setCollectionsUploading([...collectionsUploading, collectionName]); + customToast.success("Uploading document"); + }, + onError: (_error, { file, collectionName }) => { + customToast.error( + `Error uploading document ${file.name} to ${collectionName}` + ); + }, + onSuccess: (_data, { file, collectionName }) => { + setCollectionsUploading( + collectionsUploading.filter((e) => e !== collectionName) + ); + customToast.success( + `Uploaded document ${file.name} to ${collectionName}` + ); + }, + onSettled: () => { + setTargetCollection(undefined); + }, + }); + + // TODO Add loading screen + // if (isLoading) { + // return
Loading
; + // } + + // TODO Add error component + // if (error) { + // return
Errors: {JSON.stringify(error)}
; + // } + + const onFileSelected = (e: React.ChangeEvent) => { + if (!e.target.files || !targetCollection) { + return; + } + const file = e.target.files[0]; + uploadDocumentMutate({ + file, + collectionName: targetCollection.name, + }); + }; + + const renderRow = ({ + theme, + item, + isUploading, + onDelete, + onUploadClick, + }: { + theme: string; + isUploading?: boolean; + item: RagDataSource; + onDelete: (rds: RagDataSource) => void; + onUploadClick: (rds: RagDataSource) => void; + }) => ( + + + + + + + + + +
+ { + onDelete(item); + }} + alertTrigger={ + + } + > + + +
+ +
+
+
+
+ ); + + return ( + <> + + {/* All rows share a single file input control */} + + + + + + createCollectionMutation.mutate({ + collectionName: d.collectionName, + }) + } + /> + + + Manage Rag Datasources + + + + {["Name", "ID", "Manage"].map((f: string) => ( + + {f} + + ))} + + + + {ragDataSources.map((rds: RagDataSource) => + renderRow({ + item: rds, + theme: theme, + isUploading: collectionsUploading.indexOf(rds.name) !== -1, + onUploadClick: (rds) => { + setTargetCollection(rds); + inputFile?.current?.click(); + }, + onDelete: (rds) => + deleteCollectionMutation.mutate({ + collectionName: rds.name, + }), + }) + )} + +
+ +
+
+
+ + ); +} From 4e2e1d3cea144edb0c2ce78345c07849a3b3c2f7 Mon Sep 17 00:00:00 2001 From: Greg Hatt Date: Fri, 6 Sep 2024 11:59:15 -0300 Subject: [PATCH 25/61] Adds data source selector to ChatComponent --- app/frontend/src/components/ChatComponent.tsx | 92 +++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/app/frontend/src/components/ChatComponent.tsx b/app/frontend/src/components/ChatComponent.tsx index 0a47293a..0293a63b 100644 --- a/app/frontend/src/components/ChatComponent.tsx +++ b/app/frontend/src/components/ChatComponent.tsx @@ -32,10 +32,27 @@ import { DropdownMenuTrigger, } from "./ui/dropdown-menu"; import { fetchModels } from "../api/modelsDeployedApis"; +import axios from "axios"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "./ui/select"; +import { useQuery } from "react-query"; +import { fetchCollections } from "@/src/pages/rag"; interface InferenceRequest { deploy_id: string; text: string; + rag_context?: { documents: string[] }; +} + +interface RagDataSource { + id: string; + name: string; + metadata: Record; } interface ChatMessage { @@ -51,6 +68,17 @@ interface Model { const ChatComponent: React.FC = () => { const location = useLocation(); const [textInput, setTextInput] = useState(""); + + const [ragDatasource, setRagDatasource] = useState< + RagDataSource | undefined + >(); + + // Fetch collections + const { data: ragDataSources } = useQuery("collectionsList", { + queryFn: fetchCollections, + initialData: [], + }); + const [chatHistory, setChatHistory] = useState([]); const [modelID, setModelID] = useState(null); const [modelName, setModelName] = useState(null); @@ -97,8 +125,33 @@ const ChatComponent: React.FC = () => { } }; + const getRagContext = async (request: InferenceRequest) => { + const ragContext: { documents: string[] } = { + documents: [], + }; + + const response = await axios + .get(`/collections-api/${ragDatasource?.name}/query`, { + params: { query: request.text }, + }) + .catch((e) => { + console.error(`Error fetching RAG context ${e}`); + }); + + if (!response?.data) { + return ragContext; + } + + ragContext.documents = response.data.documents; + return ragContext; + }; + const runInference = async (request: InferenceRequest) => { try { + if (ragDatasource) { + request.rag_context = await getRagContext(request); + } + setIsStreaming(true); const response = await fetch(`/models-api/inference/`, { method: "POST", @@ -178,6 +231,33 @@ const ChatComponent: React.FC = () => { runInference(inferenceRequest); }; + const RagContextSelector = ({ + collections, + onChange, + activeCollection, + }: { + collections: RagDataSource[]; + activeCollection?: RagDataSource; + onChange: (v: string) => void; + }) => ( +
+
Select RAG Data Source
+ + +
+ ); + const handleKeyPress = (e: React.KeyboardEvent) => { if (e.key === "Enter" && !e.shiftKey) { e.preventDefault(); @@ -235,6 +315,18 @@ const ChatComponent: React.FC = () => {
+ { + const dataSource = ragDataSources.find((rds: RagDataSource) => { + return rds.name == v; + }); + if (dataSource) { + setRagDatasource(dataSource); + } + }} + activeCollection={ragDatasource} + /> {chatHistory.length === 0 && (
Date: Fri, 6 Sep 2024 11:59:41 -0300 Subject: [PATCH 26/61] Adds RAG management link to Navbar --- app/frontend/src/components/NavBar.tsx | 31 ++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/app/frontend/src/components/NavBar.tsx b/app/frontend/src/components/NavBar.tsx index e781a14e..a5289636 100644 --- a/app/frontend/src/components/NavBar.tsx +++ b/app/frontend/src/components/NavBar.tsx @@ -8,7 +8,13 @@ import { NavigationMenuItem, NavigationMenuList, } from "./ui/navigation-menu"; +<<<<<<< HEAD import { Home, BrainCog, BotMessageSquare } from "lucide-react"; +||||||| parent of d87929d (Adds RAG management link to Navbar) +import { Home, BrainCog, BotMessageSquare } from "lucide-react"; // Import BotMessageSquare +======= +import { Home, BrainCog, BotMessageSquare, Notebook } from "lucide-react"; // Import BotMessageSquare +>>>>>>> d87929d (Adds RAG management link to Navbar) import ModeToggle from "./DarkModeToggle"; import HelpIcon from "./HelpIcon"; import { Separator } from "./ui/separator"; @@ -94,6 +100,7 @@ export default function NavBar() {

+<<<<<<< HEAD LLM Studio

)} @@ -104,6 +111,30 @@ export default function NavBar() { isChatUI ? "flex-col items-center space-y-4" : "justify-between" }`} > +||||||| parent of d87929d (Adds RAG management link to Navbar) + + {!isChatUI && Models Deployed} + + + {isChatUI && ( +======= + + {!isChatUI && Models Deployed} + + + + getNavLinkClass(isActive)} + > + + {!isChatUI && RAG Management} + + + {isChatUI && ( +>>>>>>> d87929d (Adds RAG management link to Navbar) From 5ed2303053290ad35caffca8c53ff0b6e3de2805 Mon Sep 17 00:00:00 2001 From: Greg Hatt Date: Fri, 6 Sep 2024 12:08:43 -0300 Subject: [PATCH 27/61] Fixes import path to fetch collections function --- app/frontend/src/components/ChatComponent.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/frontend/src/components/ChatComponent.tsx b/app/frontend/src/components/ChatComponent.tsx index 0293a63b..0dc63a8c 100644 --- a/app/frontend/src/components/ChatComponent.tsx +++ b/app/frontend/src/components/ChatComponent.tsx @@ -41,7 +41,7 @@ import { SelectValue, } from "./ui/select"; import { useQuery } from "react-query"; -import { fetchCollections } from "@/src/pages/rag"; +import { fetchCollections } from "@/src/pages/rag/"; interface InferenceRequest { deploy_id: string; From 3dd8ba737f905587e52e2727a935b191acf19eee Mon Sep 17 00:00:00 2001 From: Greg Hatt Date: Fri, 6 Sep 2024 12:09:04 -0300 Subject: [PATCH 28/61] Adds initial value for data source collections --- app/frontend/src/pages/rag/RagManagement.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/frontend/src/pages/rag/RagManagement.tsx b/app/frontend/src/pages/rag/RagManagement.tsx index 6070a624..06c4846e 100644 --- a/app/frontend/src/pages/rag/RagManagement.tsx +++ b/app/frontend/src/pages/rag/RagManagement.tsx @@ -23,7 +23,7 @@ import { deleteCollection, createCollection, uploadDocument, -} from "."; +} from "@/src/pages/rag"; interface RagDataSource { id: string; @@ -72,6 +72,7 @@ export default function RagManagement() { } = useQuery("collectionsList", { queryFn: fetchCollections, onError: () => customToast.error("Failed to fetch collections"), + initialData: [], }); // Delete mutation From df7ce33128cef56c689f902b42c0b48b8d419c87 Mon Sep 17 00:00:00 2001 From: Greg Hatt Date: Mon, 9 Sep 2024 14:34:38 -0300 Subject: [PATCH 29/61] Fixes TS errors in Vite config --- app/frontend/vite.config.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/app/frontend/vite.config.ts b/app/frontend/vite.config.ts index d2dcb55f..5bdf94af 100644 --- a/app/frontend/vite.config.ts +++ b/app/frontend/vite.config.ts @@ -1,8 +1,10 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC -import { defineConfig, ProxyOptions } from "vite"; +/* eslint-disable @typescript-eslint/no-unused-vars */ +import { defineConfig, HttpProxy, ProxyOptions } from "vite"; import react from "@vitejs/plugin-react-swc"; import path from "path"; +import { ClientRequest, IncomingMessage, ServerResponse } from "http"; const VITE_BACKEND_URL = "http://tt-studio-backend-api:8000"; // define mapping of backend apis proxy strings -> routes @@ -21,14 +23,14 @@ const proxyConfig: Record = Object.fromEntries( changeOrigin: true, secure: true, // debug logging - configure: (proxy) => { - proxy.on("error", (err) => { + configure: (proxy: HttpProxy.Server) => { + proxy.on("error", (err: Error, _req: IncomingMessage, _res: ServerResponse) => { console.log("proxy error", err); }); - proxy.on("proxyReq", (proxyReq, req) => { + proxy.on("proxyReq", (proxyReq: ClientRequest, req: IncomingMessage, _res: ServerResponse) => { console.log("Sending Request to the Target:", req.method, req.url); }); - proxy.on("proxyRes", (proxyRes, req) => { + proxy.on("proxyRes", (proxyRes: IncomingMessage, req: IncomingMessage, _res: ServerResponse) => { console.log( "Received Response from the Target:", proxyRes.statusCode, From 4a886ff1ac95bd06400ba8cff29c67f8901deeb5 Mon Sep 17 00:00:00 2001 From: Greg Hatt Date: Mon, 9 Sep 2024 14:58:44 -0300 Subject: [PATCH 30/61] Fixes TS errors in existing components --- app/frontend/src/components/StepperFormActions.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/frontend/src/components/StepperFormActions.tsx b/app/frontend/src/components/StepperFormActions.tsx index 494d35b3..62a51fca 100644 --- a/app/frontend/src/components/StepperFormActions.tsx +++ b/app/frontend/src/components/StepperFormActions.tsx @@ -9,7 +9,7 @@ export function StepperFormActions({ removeDynamicSteps, isSubmitting, }: { - form: unknown; + form: HTMLFormElement; removeDynamicSteps: () => void; isSubmitting?: boolean; }) { From 0c6d63f8efa6842fdc3039c7c8f063fe41b8299d Mon Sep 17 00:00:00 2001 From: Greg Hatt Date: Tue, 10 Sep 2024 13:25:52 -0300 Subject: [PATCH 31/61] Fixes Navbar after rebase --- app/frontend/src/components/NavBar.tsx | 50 ++++++++++---------------- 1 file changed, 19 insertions(+), 31 deletions(-) diff --git a/app/frontend/src/components/NavBar.tsx b/app/frontend/src/components/NavBar.tsx index a5289636..dc587d97 100644 --- a/app/frontend/src/components/NavBar.tsx +++ b/app/frontend/src/components/NavBar.tsx @@ -8,13 +8,7 @@ import { NavigationMenuItem, NavigationMenuList, } from "./ui/navigation-menu"; -<<<<<<< HEAD -import { Home, BrainCog, BotMessageSquare } from "lucide-react"; -||||||| parent of d87929d (Adds RAG management link to Navbar) -import { Home, BrainCog, BotMessageSquare } from "lucide-react"; // Import BotMessageSquare -======= import { Home, BrainCog, BotMessageSquare, Notebook } from "lucide-react"; // Import BotMessageSquare ->>>>>>> d87929d (Adds RAG management link to Navbar) import ModeToggle from "./DarkModeToggle"; import HelpIcon from "./HelpIcon"; import { Separator } from "./ui/separator"; @@ -100,7 +94,6 @@ export default function NavBar() {

-<<<<<<< HEAD LLM Studio

)} @@ -111,30 +104,6 @@ export default function NavBar() { isChatUI ? "flex-col items-center space-y-4" : "justify-between" }`} > -||||||| parent of d87929d (Adds RAG management link to Navbar) - - {!isChatUI && Models Deployed} - -
- {isChatUI && ( -======= - - {!isChatUI && Models Deployed} - - - - getNavLinkClass(isActive)} - > - - {!isChatUI && RAG Management} - - - {isChatUI && ( ->>>>>>> d87929d (Adds RAG management link to Navbar) @@ -154,6 +123,25 @@ export default function NavBar() { orientation="vertical" /> )} + + getNavLinkClass(isActive)} + > + + {!isChatUI && Rag Management} + + + {!isChatUI && ( + + )} From d6ff74f64d9185f2875198eb771437a77dd48f6b Mon Sep 17 00:00:00 2001 From: Greg Hatt Date: Tue, 10 Sep 2024 13:30:33 -0300 Subject: [PATCH 32/61] Changes table description to match existing table --- app/frontend/src/pages/rag/RagManagement.tsx | 30 +++++++------------- 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/app/frontend/src/pages/rag/RagManagement.tsx b/app/frontend/src/pages/rag/RagManagement.tsx index 06c4846e..32b9dc21 100644 --- a/app/frontend/src/pages/rag/RagManagement.tsx +++ b/app/frontend/src/pages/rag/RagManagement.tsx @@ -179,11 +179,10 @@ export default function RagManagement() { alertTrigger={ @@ -192,11 +191,10 @@ export default function RagManagement() { @@ -224,10 +222,9 @@ export default function RagManagement() { @@ -241,22 +238,15 @@ export default function RagManagement() { } /> - + Manage Rag Datasources {["Name", "ID", "Manage"].map((f: string) => ( From 335ca7b26ad33b71ff7514b817c2e34d5fc500b6 Mon Sep 17 00:00:00 2001 From: Greg Hatt Date: Tue, 10 Sep 2024 13:30:45 -0300 Subject: [PATCH 33/61] Updates package-lock.json --- app/frontend/package-lock.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/app/frontend/package-lock.json b/app/frontend/package-lock.json index 225d640e..72ad382c 100644 --- a/app/frontend/package-lock.json +++ b/app/frontend/package-lock.json @@ -3293,6 +3293,14 @@ } ] }, + "node_modules/big-integer": { + "version": "1.6.52", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz", + "integrity": "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==", + "engines": { + "node": ">=0.6" + } + }, "node_modules/bin-links": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/bin-links/-/bin-links-4.0.4.tgz", @@ -3308,14 +3316,6 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/big-integer": { - "version": "1.6.52", - "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz", - "integrity": "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==", - "engines": { - "node": ">=0.6" - } - }, "node_modules/binary-extensions": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", From 73b8c5ff0b1fff62ffcf8fbea1d5b4cf6d1994d6 Mon Sep 17 00:00:00 2001 From: Greg Hatt Date: Tue, 10 Sep 2024 15:14:30 -0300 Subject: [PATCH 34/61] Fixes missing list key error --- app/frontend/src/components/ChatComponent.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/frontend/src/components/ChatComponent.tsx b/app/frontend/src/components/ChatComponent.tsx index 0dc63a8c..bece6b35 100644 --- a/app/frontend/src/components/ChatComponent.tsx +++ b/app/frontend/src/components/ChatComponent.tsx @@ -251,7 +251,11 @@ const ChatComponent: React.FC = () => { {collections.map((c) => { - return {c.name}; + return ( + + {c.name} + + ); })} From 929de5de85aeaebcce88141dbbade4caa26bec36 Mon Sep 17 00:00:00 2001 From: Greg Hatt Date: Tue, 10 Sep 2024 15:58:50 -0300 Subject: [PATCH 35/61] Adds header information to files --- app/frontend/src/pages/rag/RagManagement.tsx | 2 ++ app/frontend/src/pages/rag/index.ts | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/app/frontend/src/pages/rag/RagManagement.tsx b/app/frontend/src/pages/rag/RagManagement.tsx index 32b9dc21..c1ceaaf2 100644 --- a/app/frontend/src/pages/rag/RagManagement.tsx +++ b/app/frontend/src/pages/rag/RagManagement.tsx @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC import { Button } from "@/src/components/ui/button"; import { useMutation, useQuery, useQueryClient } from "react-query"; import { Card } from "@/src/components/ui/card"; diff --git a/app/frontend/src/pages/rag/index.ts b/app/frontend/src/pages/rag/index.ts index 64132df8..7c45e1ec 100644 --- a/app/frontend/src/pages/rag/index.ts +++ b/app/frontend/src/pages/rag/index.ts @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC import axios from "axios"; const collectionsAPIURL = "/collections-api"; @@ -34,6 +36,6 @@ export const uploadDocument = async ({ }) => { return axios.postForm( `${collectionsAPIURL}/${collectionName}/insert_document`, - { file } + { file }, ); }; From a1d311fc77712606080685649b712c5e6d0e39c1 Mon Sep 17 00:00:00 2001 From: Greg Hatt Date: Mon, 16 Sep 2024 11:38:08 -0300 Subject: [PATCH 36/61] Updates button colors to match models deployed table --- app/frontend/src/pages/rag/RagManagement.tsx | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/app/frontend/src/pages/rag/RagManagement.tsx b/app/frontend/src/pages/rag/RagManagement.tsx index c1ceaaf2..f4e56cb3 100644 --- a/app/frontend/src/pages/rag/RagManagement.tsx +++ b/app/frontend/src/pages/rag/RagManagement.tsx @@ -181,10 +181,7 @@ export default function RagManagement() { alertTrigger={ @@ -192,11 +189,9 @@ export default function RagManagement() { > @@ -246,8 +241,8 @@ export default function RagManagement() { {["Name", "ID", "Manage"].map((f: string) => ( From 9346a00b75c37e04f0fbb858d2627405b82c9d4b Mon Sep 17 00:00:00 2001 From: Greg Hatt Date: Mon, 16 Sep 2024 12:29:26 -0300 Subject: [PATCH 37/61] Change RAG data source form to text --- app/frontend/src/pages/rag/RagDataSourceForm.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/frontend/src/pages/rag/RagDataSourceForm.tsx b/app/frontend/src/pages/rag/RagDataSourceForm.tsx index 8261c09e..c71b0e07 100644 --- a/app/frontend/src/pages/rag/RagDataSourceForm.tsx +++ b/app/frontend/src/pages/rag/RagDataSourceForm.tsx @@ -35,7 +35,7 @@ const RagDataSourceForm = ({ className="flex space-x-4 items-center" onSubmit={handleSubmit((d) => onSubmit({ collectionName: d.name }))} > - +
{errors.name?.message &&

{errors.name?.message}

}
From c4ba97be7449168d88bb07eacaeb3eb0ce069c3e Mon Sep 17 00:00:00 2001 From: Greg Hatt Date: Mon, 16 Sep 2024 12:39:10 -0300 Subject: [PATCH 38/61] Adds help text for RAG management --- app/frontend/src/components/SideBar.tsx | 46 +++++++++++++++++++------ 1 file changed, 35 insertions(+), 11 deletions(-) diff --git a/app/frontend/src/components/SideBar.tsx b/app/frontend/src/components/SideBar.tsx index b492a990..ebaf8404 100644 --- a/app/frontend/src/components/SideBar.tsx +++ b/app/frontend/src/components/SideBar.tsx @@ -19,9 +19,8 @@ const Sidebar = forwardRef((_, ref) => { }; const getHelpContent = () => { - const baseStyles = `shadow-lg rounded-lg p-6 my-4 ${ - theme === "dark" ? "bg-TT-slate text-white" : "bg-white text-tt-black" - }`; + const baseStyles = `shadow-lg rounded-lg p-6 my-4 ${theme === "dark" ? "bg-TT-slate text-white" : "bg-white text-tt-black" + }`; return ( { @@ -65,6 +64,34 @@ const Sidebar = forwardRef((_, ref) => { ), + "/rag-management": ( + + + + RAG Management + + + +

+ The "RAG Management" page allows you to create additional Datasources + to augment the responses provided by the models you have deployed. You can select + a datasource to use from the dropdown menu at the top of the chat window. +

+
    +
  • + Create New RAG Datasource: RAG datasources must have a unique name of at least two characters and no spaces. + Enter the name of your datasource and click the create button to create the datasource.
  • +
  • + Upload Document: Select a document to upload and embed into the RAG datasource. +
  • +
  • + Delete: Delete your RAG datasource. This action is permanent and irreversible. +
  • +
+
+
+ ), + "/chat-ui": ( @@ -130,11 +157,9 @@ const Sidebar = forwardRef((_, ref) => { return (
@@ -155,9 +180,8 @@ const Sidebar = forwardRef((_, ref) => {
From 3bfdbce4bfed6981badb6ef865e20d2c918ebd4e Mon Sep 17 00:00:00 2001 From: Greg Hatt Date: Mon, 16 Sep 2024 12:39:35 -0300 Subject: [PATCH 39/61] Fixes consistence of 'datasource' spelling --- app/frontend/src/components/ChatComponent.tsx | 2 +- app/frontend/src/pages/rag/RagManagement.tsx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/frontend/src/components/ChatComponent.tsx b/app/frontend/src/components/ChatComponent.tsx index bece6b35..feaf1b39 100644 --- a/app/frontend/src/components/ChatComponent.tsx +++ b/app/frontend/src/components/ChatComponent.tsx @@ -241,7 +241,7 @@ const ChatComponent: React.FC = () => { onChange: (v: string) => void; }) => (
-
Select RAG Data Source
+
Select RAG Datasource
diff --git a/app/frontend/third-party-licenses.txt b/app/frontend/third-party-licenses.txt index a974cd1b..2fb4ffcb 100644 --- a/app/frontend/third-party-licenses.txt +++ b/app/frontend/third-party-licenses.txt @@ -1326,6 +1326,216 @@ software or this license, under any kind of legal claim.*** ----------- +The following npm package may be included in this product: + + - unload@2.2.0 + +This package contains the following license and notice below: + +Apache License +Version 2.0, January 2004 +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, +and distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by +the copyright owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all +other entities that control, are controlled by, or are under common +control with that entity. For the purposes of this definition, +"control" means (i) the power, direct or indirect, to cause the +direction or management of such entity, whether by contract or +otherwise, or (ii) ownership of fifty percent (50%) or more of the +outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity +exercising permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, +including but not limited to software source code, documentation +source, and configuration files. + +"Object" form shall mean any form resulting from mechanical +transformation or translation of a Source form, including but +not limited to compiled object code, generated documentation, +and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or +Object form, made available under the License, as indicated by a +copyright notice that is included in or attached to the work +(an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object +form, that is based on (or derived from) the Work and for which the +editorial revisions, annotations, elaborations, or other modifications +represent, as a whole, an original work of authorship. For the purposes +of this License, Derivative Works shall not include works that remain +separable from, or merely link (or bind by name) to the interfaces of, +the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including +the original version of the Work and any modifications or additions +to that Work or Derivative Works thereof, that is intentionally +submitted to Licensor for inclusion in the Work by the copyright owner +or by an individual or Legal Entity authorized to submit on behalf of +the copyright owner. For the purposes of this definition, "submitted" +means any form of electronic, verbal, or written communication sent +to the Licensor or its representatives, including but not limited to +communication on electronic mailing lists, source code control systems, +and issue tracking systems that are managed by, or on behalf of, the +Licensor for the purpose of discussing and improving the Work, but +excluding communication that is conspicuously marked or otherwise +designated in writing by the copyright owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity +on behalf of whom a Contribution has been received by Licensor and +subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of +this License, each Contributor hereby grants to You a perpetual, +worldwide, non-exclusive, no-charge, royalty-free, irrevocable +copyright license to reproduce, prepare Derivative Works of, +publicly display, publicly perform, sublicense, and distribute the +Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of +this License, each Contributor hereby grants to You a perpetual, +worldwide, non-exclusive, no-charge, royalty-free, irrevocable +(except as stated in this section) patent license to make, have made, +use, offer to sell, sell, import, and otherwise transfer the Work, +where such license applies only to those patent claims licensable +by such Contributor that are necessarily infringed by their +Contribution(s) alone or by combination of their Contribution(s) +with the Work to which such Contribution(s) was submitted. If You +institute patent litigation against any entity (including a +cross-claim or counterclaim in a lawsuit) alleging that the Work +or a Contribution incorporated within the Work constitutes direct +or contributory patent infringement, then any patent licenses +granted to You under this License for that Work shall terminate +as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the +Work or Derivative Works thereof in any medium, with or without +modifications, and in Source or Object form, provided that You +meet the following conditions: + +(a) You must give any other recipients of the Work or +Derivative Works a copy of this License; and + +(b) You must cause any modified files to carry prominent notices +stating that You changed the files; and + +(c) You must retain, in the Source form of any Derivative Works +that You distribute, all copyright, patent, trademark, and +attribution notices from the Source form of the Work, +excluding those notices that do not pertain to any part of +the Derivative Works; and + +(d) If the Work includes a "NOTICE" text file as part of its +distribution, then any Derivative Works that You distribute must +include a readable copy of the attribution notices contained +within such NOTICE file, excluding those notices that do not +pertain to any part of the Derivative Works, in at least one +of the following places: within a NOTICE text file distributed +as part of the Derivative Works; within the Source form or +documentation, if provided along with the Derivative Works; or, +within a display generated by the Derivative Works, if and +wherever such third-party notices normally appear. The contents +of the NOTICE file are for informational purposes only and +do not modify the License. You may add Your own attribution +notices within Derivative Works that You distribute, alongside +or as an addendum to the NOTICE text from the Work, provided +that such additional attribution notices cannot be construed +as modifying the License. + +You may add Your own copyright statement to Your modifications and +may provide additional or different license terms and conditions +for use, reproduction, or distribution of Your modifications, or +for any such Derivative Works as a whole, provided Your use, +reproduction, and distribution of the Work otherwise complies with +the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, +any Contribution intentionally submitted for inclusion in the Work +by You to the Licensor shall be under the terms and conditions of +this License, without any additional terms or conditions. +Notwithstanding the above, nothing herein shall supersede or modify +the terms of any separate license agreement you may have executed +with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade +names, trademarks, service marks, or product names of the Licensor, +except as required for reasonable and customary use in describing the +origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or +agreed to in writing, Licensor provides the Work (and each +Contributor provides its Contributions) on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +implied, including, without limitation, any warranties or conditions +of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A +PARTICULAR PURPOSE. You are solely responsible for determining the +appropriateness of using or redistributing the Work and assume any +risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, +whether in tort (including negligence), contract, or otherwise, +unless required by applicable law (such as deliberate and grossly +negligent acts) or agreed to in writing, shall any Contributor be +liable to You for damages, including any direct, indirect, special, +incidental, or consequential damages of any character arising as a +result of this License or out of the use or inability to use the +Work (including but not limited to damages for loss of goodwill, +work stoppage, computer failure or malfunction, or any and all +other commercial damages or losses), even if such Contributor +has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing +the Work or Derivative Works thereof, You may choose to offer, +and charge a fee for, acceptance of support, warranty, indemnity, +or other liability obligations and/or rights consistent with this +License. However, in accepting such obligations, You may act only +on Your own behalf and on Your sole responsibility, not on behalf +of any other Contributor, and only if You agree to indemnify, +defend, and hold each Contributor harmless for any liability +incurred by, or claims asserted against, such Contributor by reason +of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + +To apply the Apache License to your work, attach the following +boilerplate notice, with the fields enclosed by brackets "[]" +replaced with your own identifying information. (Don't include +the brackets!) The text should be enclosed in the appropriate +comment syntax for the file format. We also recommend that a +file or class name and description of purpose be included on the +same "printed page" as the copyright notice for easier +identification within third-party archives. + +Copyright 2015-2016 Netflix, Inc., Microsoft Corp. and contributors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +----------- + The following npm package may be included in this product: - typescript@5.5.4 @@ -1404,7 +1614,6 @@ Apache-2.0 The following npm packages may be included in this product: - - @swc/core-darwin-arm64@1.7.14 - @swc/core-linux-arm64-gnu@1.7.14 - @swc/core-linux-arm64-musl@1.7.14 @@ -1751,20 +1960,6 @@ PERFORMANCE OF THIS SOFTWARE. ----------- -The following npm package may be included in this product: - - - make-error@1.3.6 - -This package contains the following license and notice below: - -Copyright 2014 Julien Fontanet - -Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - ------------ - The following npm package may be included in this product: - follow-redirects@1.15.6 @@ -1792,6 +1987,35 @@ IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ----------- +The following npm package may be included in this product: + + - js-sha3@0.8.0 + +This package contains the following license and notice below: + +Copyright 2015-2018 Chen, Yi-Cyuan + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +----------- + The following npm package may be included in this product: - @jridgewell/resolve-uri@3.1.2 @@ -1849,12 +2073,11 @@ SOFTWARE. ----------- -The following npm packages may be included in this product: +The following npm package may be included in this product: - @jridgewell/trace-mapping@0.3.25 - - @jridgewell/trace-mapping@0.3.9 -These packages each contain the following license and notice below: +This package contains the following license and notice below: Copyright 2022 Justin Ridgewell @@ -1941,6 +2164,16 @@ http://sjs.mit-license.org ----------- +The following npm package may be included in this product: + + - nano-time@1.0.0 + +This package contains the following license and notice below: + +ISC + +----------- + The following npm package may be included in this product: - css-color-keywords@1.0.0 @@ -2019,6 +2252,7 @@ The following npm packages may be included in this product: - @radix-ui/primitive@1.0.1 - @radix-ui/primitive@1.1.0 - @radix-ui/react-accordion@1.2.0 + - @radix-ui/react-alert-dialog@1.1.1 - @radix-ui/react-arrow@1.1.0 - @radix-ui/react-aspect-ratio@1.1.0 - @radix-ui/react-collapsible@1.1.0 @@ -2074,6 +2308,7 @@ The following npm packages may be included in this product: - @radix-ui/rect@1.1.0 - dlv@1.1.3 - eastasianwidth@0.2.0 + - microseconds@0.2.0 - react-remove-scroll-bar@2.3.6 - react-style-singleton@2.2.1 - undici-types@5.26.5 @@ -2175,36 +2410,6 @@ SOFTWARE. ----------- -The following npm package may be included in this product: - - - acorn-walk@8.3.3 - -This package contains the following license and notice below: - -MIT License - -Copyright (C) 2012-2020 by various contributors (see AUTHORS) - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - ------------ - The following npm package may be included in this product: - acorn@8.12.1 @@ -2235,11 +2440,12 @@ THE SOFTWARE. ----------- -The following npm package may be included in this product: +The following npm packages may be included in this product: + - brace-expansion@1.1.11 - brace-expansion@2.0.1 -This package contains the following license and notice below: +These packages each contain the following license and notice below: MIT License @@ -2540,11 +2746,12 @@ SOFTWARE. ----------- -The following npm package may be included in this product: +The following npm packages may be included in this product: - detect-node-es@1.1.0 + - detect-node@2.1.0 -This package contains the following license and notice below: +These packages each contain the following license and notice below: MIT License @@ -2572,13 +2779,13 @@ SOFTWARE. The following npm package may be included in this product: - - arg@4.1.3 + - broadcast-channel@3.7.0 This package contains the following license and notice below: MIT License -Copyright (c) 2017-2019 Zeit, Inc. +Copyright (c) 2018 Daniel Meyer Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -2708,6 +2915,36 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI ----------- +The following npm package may be included in this product: + + - react-query@3.39.3 + +This package contains the following license and notice below: + +MIT License + +Copyright (c) 2019 Tanner Linsley + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------- + The following npm packages may be included in this product: - @hookform/resolvers@3.9.0 @@ -2741,17 +2978,13 @@ SOFTWARE. The following npm package may be included in this product: - - create-require@1.1.1 + - get-nonce@1.0.1 This package contains the following license and notice below: MIT License -Copyright (c) 2020 - -Maël Nison -Paul Soporan -Pooya Parsa +Copyright (c) 2020 Anton Korzunov Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -2775,13 +3008,13 @@ SOFTWARE. The following npm package may be included in this product: - - get-nonce@1.0.1 + - zod@3.23.8 This package contains the following license and notice below: MIT License -Copyright (c) 2020 Anton Korzunov +Copyright (c) 2020 Colin McDonnell Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -2805,13 +3038,13 @@ SOFTWARE. The following npm package may be included in this product: - - zod@3.23.8 + - oblivious-set@1.0.0 This package contains the following license and notice below: MIT License -Copyright (c) 2020 Colin McDonnell +Copyright (c) 2020 Daniel Meyer Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -3286,39 +3519,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI ----------- -The following npm packages may be included in this product: - - - @tsconfig/node10@1.0.11 - - @tsconfig/node12@1.0.11 - - @tsconfig/node14@1.0.3 - - @tsconfig/node16@1.0.4 - -These packages each contain the following license and notice below: - -MIT License - -Copyright (c) Microsoft Corporation. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE - ------------ - The following npm package may be included in this product: - jiti@1.21.6 @@ -3435,7 +3635,6 @@ The following npm packages may be included in this product: - shebang-regex@3.0.0 - string-width@4.2.3 - strip-ansi@6.0.1 - - yn@3.1.1 These packages each contain the following license and notice below: @@ -3512,46 +3711,6 @@ THE SOFTWARE. ----------- -The following npm package may be included in this product: - - - diff@4.0.2 - -This package contains the following license and notice below: - -Software License Agreement (BSD License) - -Copyright (c) 2009-2015, Kevin Decker - -All rights reserved. - -Redistribution and use of this software in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above - copyright notice, this list of conditions and the - following disclaimer. - -* Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the - following disclaimer in the documentation and/or other - materials provided with the distribution. - -* Neither the name of Kevin Decker nor the names of its - contributors may be used to endorse or promote products - derived from this software without specific prior - written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR -IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER -IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ------------ - The following npm package may be included in this product: - glob@10.4.5 @@ -3769,10 +3928,62 @@ IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ----------- +The following npm package may be included in this product: + + - inflight@1.0.6 + +This package contains the following license and notice below: + +The ISC License + +Copyright (c) Isaac Z. Schlueter + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - inherits@2.0.4 + +This package contains the following license and notice below: + +The ISC License + +Copyright (c) Isaac Z. Schlueter + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. + +----------- + The following npm packages may be included in this product: - isexe@2.0.0 + - minimatch@3.1.2 + - once@1.4.0 + - rimraf@3.0.2 - which@2.0.2 + - wrappy@1.0.2 These packages each contain the following license and notice below: @@ -3794,6 +4005,88 @@ IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ----------- +The following npm package may be included in this product: + + - fs.realpath@1.0.0 + +This package contains the following license and notice below: + +The ISC License + +Copyright (c) Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +---- + +This library bundles a version of the `fs.realpath` and `fs.realpathSync` +methods from Node.js v0.10 under the terms of the Node.js MIT license. + +Node's license follows, also included at the header of `old.js` which contains +the licensed code: + + Copyright Joyent, Inc. and other Node contributors. + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + +----------- + +The following npm package may be included in this product: + + - glob@7.2.3 + +This package contains the following license and notice below: + +The ISC License + +Copyright (c) Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +## Glob Logo + +Glob's logo created by Tanya Brassie , licensed +under a Creative Commons Attribution-ShareAlike 4.0 International License +https://creativecommons.org/licenses/by-sa/4.0/ + +----------- + The following npm package may be included in this product: - @jridgewell/sourcemap-codec@1.5.0 @@ -3913,36 +4206,6 @@ THE SOFTWARE. ----------- -The following npm package may be included in this product: - - - ts-node@10.9.2 - -This package contains the following license and notice below: - -The MIT License (MIT) - -Copyright (c) 2014 Blake Embrey (hello@blakeembrey.com) - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - ------------ - The following npm package may be included in this product: - is-core-module@2.15.0 @@ -3972,36 +4235,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ----------- -The following npm package may be included in this product: - - - @cspotcode/source-map-support@0.8.1 - -This package contains the following license and notice below: - -The MIT License (MIT) - -Copyright (c) 2014 Evan Wallace - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - ------------ - The following npm package may be included in this product: - postcss-import@15.1.0 @@ -4334,6 +4567,36 @@ SOFTWARE. ----------- +The following npm package may be included in this product: + + - remove-accents@0.5.0 + +This package contains the following license and notice below: + +The MIT License (MIT) + +Copyright (c) 2015 Marin Atanasov + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------- + The following npm package may be included in this product: - reusify@1.0.4 @@ -4514,36 +4777,6 @@ THE SOFTWARE. ----------- -The following npm package may be included in this product: - - - v8-compile-cache-lib@3.0.1 - -This package contains the following license and notice below: - -The MIT License (MIT) - -Copyright (c) 2019 Andres Suarez - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - ------------ - The following npm package may be included in this product: - arg@5.0.2 @@ -4640,6 +4873,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. The following npm packages may be included in this product: - object-assign@4.1.1 + - path-is-absolute@1.0.1 - pify@2.3.0 These packages each contain the following license and notice below: @@ -4902,6 +5136,35 @@ THE SOFTWARE. ----------- +The following npm package may be included in this product: + + - match-sorter@6.3.4 + +This package contains the following license and notice below: + +The MIT License (MIT) +Copyright (c) 2020 Kent C. Dodds + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +----------- + The following npm package may be included in this product: - color-name@1.1.4 @@ -4921,10 +5184,44 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI The following npm package may be included in this product: - - camelize@1.0.1 + - big-integer@1.6.52 This package contains the following license and notice below: +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to + +----------- + +The following npm packages may be included in this product: + + - camelize@1.0.1 + - concat-map@0.0.1 + +These packages each contain the following license and notice below: + This software is released under the MIT license: Permission is hereby granted, free of charge, to any person obtaining a copy of From bb668d8fef44e4a3d48a0644dd751324220171b3 Mon Sep 17 00:00:00 2001 From: Anirudh Ramchandran Date: Thu, 19 Sep 2024 12:01:00 -0400 Subject: [PATCH 43/61] Anirud/re update license headers(#51) * update lc header python file - to use pathlib instead of os for compatability simalr to https://github.com/tenstorrent/tt-inference-server/pull/8/commits/00b5764adca4f36e38e7c01a2abb87b8ec1015a2 - also work on backend and models folder * add any other missing lc headers --- add_spdx_header.py | 37 +++++++++++++++++++ app/api/add_spdx_header.py | 25 ------------- models/dummy_echo_model/Dockerfile | 4 ++ models/dummy_echo_model/src/__init__.py | 4 ++ .../src/dummy_echo_backend.py | 4 ++ models/dummy_echo_model/src/gunicorn.conf.py | 4 ++ .../src/inference_api_server.py | 4 ++ .../dummy_echo_model/src/inference_config.py | 4 ++ .../dummy_echo_model/src/inference_logger.py | 4 ++ .../src/model_weights_handler.py | 4 ++ .../src/test_dummy_backend.py | 4 ++ models/tt-metal-falcon-7b/Dockerfile | 4 ++ models/tt-metal-falcon-7b/src/__init__.py | 4 ++ .../src/_mock_inference_api_server.py | 4 ++ .../src/falcon_7b_backend.py | 4 ++ .../tt-metal-falcon-7b/src/gunicorn.conf.py | 4 ++ .../src/inference_api_server.py | 4 ++ .../src/inference_config.py | 4 ++ .../src/inference_logger.py | 4 ++ .../src/model_weights_handler.py | 4 ++ .../src/test_falcon_7b_backend.py | 4 ++ .../src/test_falcon_7b_backend_mock.py | 4 ++ .../src/test_inference_api.py | 4 ++ .../src/tt_metal_impl/__init__.py | 4 ++ 24 files changed, 125 insertions(+), 25 deletions(-) create mode 100644 add_spdx_header.py delete mode 100644 app/api/add_spdx_header.py diff --git a/add_spdx_header.py b/add_spdx_header.py new file mode 100644 index 00000000..6e1c6036 --- /dev/null +++ b/add_spdx_header.py @@ -0,0 +1,37 @@ +from pathlib import Path + +# SPDX header content +SPDX_HEADER = """# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC +""" + +def add_spdx_header(file_path): + """ + Adds the SPDX header to the file if it doesn't already contain it. + """ + with open(file_path, "r+") as file: + content = file.read() + # print(content) + if "SPDX-License-Identifier" not in content: + file.seek(0, 0) + file.write(SPDX_HEADER + "\n" + content) + +if __name__ == "__main__": + # Define the repo root and directories to process + repo_root = Path(__file__).resolve().parent.parent + directories_to_process = [ + repo_root / "tt-studio/app/api", + repo_root / "tt-studio/models", + ] + + # print(f"Processing directories: {directories_to_process}") + + # Walk through the directories and add the header to relevant files + for directory in directories_to_process: + for file_path in directory.rglob("*"): + # print(file_path) + # Check if the file is a Python file, Bash script, or Dockerfile + if file_path.suffix in (".py", ".sh") or file_path.name == "Dockerfile": + print(f"Adding SPDX header to: {file_path}") + add_spdx_header(file_path) diff --git a/app/api/add_spdx_header.py b/app/api/add_spdx_header.py deleted file mode 100644 index 1afa32bb..00000000 --- a/app/api/add_spdx_header.py +++ /dev/null @@ -1,25 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 -# -# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC - -import os - -# SPDX header content -SPDX_HEADER = """# SPDX-License-Identifier: Apache-2.0 -# -# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC -""" - -def add_spdx_header(file_path): - with open(file_path, 'r+') as file: - content = file.read() - if "SPDX-License-Identifier" not in content: - file.seek(0, 0) - file.write(SPDX_HEADER + "\n" + content) - -# Walk through the directory and add the header to all relevant files -for root, dirs, files in os.walk("."): - for file in files: - if file.endswith((".py", "Dockerfile", ".sh")): # Check if the file is Python, Dockerfile, or Bash - file_path = os.path.join(root, file) # Construct the file path - add_spdx_header(file_path) # Pass the file path to the function diff --git a/models/dummy_echo_model/Dockerfile b/models/dummy_echo_model/Dockerfile index 3c778683..3d884508 100644 --- a/models/dummy_echo_model/Dockerfile +++ b/models/dummy_echo_model/Dockerfile @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + # Build stage FROM ubuntu:20.04 AS builder LABEL maintainer="Tom Stesco " diff --git a/models/dummy_echo_model/src/__init__.py b/models/dummy_echo_model/src/__init__.py index e69de29b..4da24a6e 100644 --- a/models/dummy_echo_model/src/__init__.py +++ b/models/dummy_echo_model/src/__init__.py @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + diff --git a/models/dummy_echo_model/src/dummy_echo_backend.py b/models/dummy_echo_model/src/dummy_echo_backend.py index d08e1199..5a349b98 100644 --- a/models/dummy_echo_model/src/dummy_echo_backend.py +++ b/models/dummy_echo_model/src/dummy_echo_backend.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + import time import traceback from multiprocessing import Queue diff --git a/models/dummy_echo_model/src/gunicorn.conf.py b/models/dummy_echo_model/src/gunicorn.conf.py index db74153e..a4c40c5c 100644 --- a/models/dummy_echo_model/src/gunicorn.conf.py +++ b/models/dummy_echo_model/src/gunicorn.conf.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + import pathlib from datetime import datetime diff --git a/models/dummy_echo_model/src/inference_api_server.py b/models/dummy_echo_model/src/inference_api_server.py index 95ec9018..67d50a74 100644 --- a/models/dummy_echo_model/src/inference_api_server.py +++ b/models/dummy_echo_model/src/inference_api_server.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + import multiprocessing import os import psutil diff --git a/models/dummy_echo_model/src/inference_config.py b/models/dummy_echo_model/src/inference_config.py index 12a3d6ca..c2c5f4a0 100644 --- a/models/dummy_echo_model/src/inference_config.py +++ b/models/dummy_echo_model/src/inference_config.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + import os from collections import namedtuple from pprint import pprint diff --git a/models/dummy_echo_model/src/inference_logger.py b/models/dummy_echo_model/src/inference_logger.py index ab4a5087..9b7acf43 100644 --- a/models/dummy_echo_model/src/inference_logger.py +++ b/models/dummy_echo_model/src/inference_logger.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + import logging import os from datetime import datetime diff --git a/models/dummy_echo_model/src/model_weights_handler.py b/models/dummy_echo_model/src/model_weights_handler.py index f54ac7aa..680523cc 100644 --- a/models/dummy_echo_model/src/model_weights_handler.py +++ b/models/dummy_echo_model/src/model_weights_handler.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + import os from pathlib import Path diff --git a/models/dummy_echo_model/src/test_dummy_backend.py b/models/dummy_echo_model/src/test_dummy_backend.py index 1b1962af..10a44ab3 100644 --- a/models/dummy_echo_model/src/test_dummy_backend.py +++ b/models/dummy_echo_model/src/test_dummy_backend.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + import queue import os from pathlib import Path diff --git a/models/tt-metal-falcon-7b/Dockerfile b/models/tt-metal-falcon-7b/Dockerfile index 4b803ade..b50c2c88 100644 --- a/models/tt-metal-falcon-7b/Dockerfile +++ b/models/tt-metal-falcon-7b/Dockerfile @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + # Build stage FROM ubuntu:20.04 as builder LABEL maintainer="Tom Stesco " diff --git a/models/tt-metal-falcon-7b/src/__init__.py b/models/tt-metal-falcon-7b/src/__init__.py index e69de29b..4da24a6e 100644 --- a/models/tt-metal-falcon-7b/src/__init__.py +++ b/models/tt-metal-falcon-7b/src/__init__.py @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + diff --git a/models/tt-metal-falcon-7b/src/_mock_inference_api_server.py b/models/tt-metal-falcon-7b/src/_mock_inference_api_server.py index 0d12c7c8..a31f6f69 100644 --- a/models/tt-metal-falcon-7b/src/_mock_inference_api_server.py +++ b/models/tt-metal-falcon-7b/src/_mock_inference_api_server.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + import os from time import sleep from unittest.mock import Mock, patch diff --git a/models/tt-metal-falcon-7b/src/falcon_7b_backend.py b/models/tt-metal-falcon-7b/src/falcon_7b_backend.py index 997faabb..1c6ab550 100644 --- a/models/tt-metal-falcon-7b/src/falcon_7b_backend.py +++ b/models/tt-metal-falcon-7b/src/falcon_7b_backend.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + import os import time import traceback diff --git a/models/tt-metal-falcon-7b/src/gunicorn.conf.py b/models/tt-metal-falcon-7b/src/gunicorn.conf.py index eaf495ef..e807cb69 100644 --- a/models/tt-metal-falcon-7b/src/gunicorn.conf.py +++ b/models/tt-metal-falcon-7b/src/gunicorn.conf.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + import pathlib from datetime import datetime diff --git a/models/tt-metal-falcon-7b/src/inference_api_server.py b/models/tt-metal-falcon-7b/src/inference_api_server.py index 6b74f669..75857c40 100644 --- a/models/tt-metal-falcon-7b/src/inference_api_server.py +++ b/models/tt-metal-falcon-7b/src/inference_api_server.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + import multiprocessing import os import queue diff --git a/models/tt-metal-falcon-7b/src/inference_config.py b/models/tt-metal-falcon-7b/src/inference_config.py index eb61feaf..00db89fd 100644 --- a/models/tt-metal-falcon-7b/src/inference_config.py +++ b/models/tt-metal-falcon-7b/src/inference_config.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + import os from collections import namedtuple from pprint import pprint diff --git a/models/tt-metal-falcon-7b/src/inference_logger.py b/models/tt-metal-falcon-7b/src/inference_logger.py index c9b32e35..f4856fad 100644 --- a/models/tt-metal-falcon-7b/src/inference_logger.py +++ b/models/tt-metal-falcon-7b/src/inference_logger.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + import logging import os from datetime import datetime diff --git a/models/tt-metal-falcon-7b/src/model_weights_handler.py b/models/tt-metal-falcon-7b/src/model_weights_handler.py index af0c784a..c4c4d271 100644 --- a/models/tt-metal-falcon-7b/src/model_weights_handler.py +++ b/models/tt-metal-falcon-7b/src/model_weights_handler.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + import os from pathlib import Path diff --git a/models/tt-metal-falcon-7b/src/test_falcon_7b_backend.py b/models/tt-metal-falcon-7b/src/test_falcon_7b_backend.py index 330c5848..e8b86bcc 100644 --- a/models/tt-metal-falcon-7b/src/test_falcon_7b_backend.py +++ b/models/tt-metal-falcon-7b/src/test_falcon_7b_backend.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + import queue import os from pathlib import Path diff --git a/models/tt-metal-falcon-7b/src/test_falcon_7b_backend_mock.py b/models/tt-metal-falcon-7b/src/test_falcon_7b_backend_mock.py index 19d2d29c..2ea2a8b5 100644 --- a/models/tt-metal-falcon-7b/src/test_falcon_7b_backend_mock.py +++ b/models/tt-metal-falcon-7b/src/test_falcon_7b_backend_mock.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + import queue import os from pathlib import Path diff --git a/models/tt-metal-falcon-7b/src/test_inference_api.py b/models/tt-metal-falcon-7b/src/test_inference_api.py index d8ece303..c3fb56f3 100644 --- a/models/tt-metal-falcon-7b/src/test_inference_api.py +++ b/models/tt-metal-falcon-7b/src/test_inference_api.py @@ -1,3 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + import os import threading diff --git a/models/tt-metal-falcon-7b/src/tt_metal_impl/__init__.py b/models/tt-metal-falcon-7b/src/tt_metal_impl/__init__.py index e69de29b..4da24a6e 100644 --- a/models/tt-metal-falcon-7b/src/tt_metal_impl/__init__.py +++ b/models/tt-metal-falcon-7b/src/tt_metal_impl/__init__.py @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + From caa60624d5e01595dcc209b11b7b65a385bd0fb6 Mon Sep 17 00:00:00 2001 From: Anirudh Ramchandran Date: Sat, 21 Sep 2024 09:13:51 -0400 Subject: [PATCH 44/61] feat(NavBar): add tooltips and separators (#45) - Added tooltips to the navbar on all pages for better user guidance. - Included a specific tooltip for the "Rag Management" section in the navbar. - Reintroduced separators in the navbar for improved visual separation of sections. --- app/frontend/src/components/NavBar.tsx | 120 +++++++++++++++++++++---- 1 file changed, 101 insertions(+), 19 deletions(-) diff --git a/app/frontend/src/components/NavBar.tsx b/app/frontend/src/components/NavBar.tsx index dc587d97..dd2e88fe 100644 --- a/app/frontend/src/components/NavBar.tsx +++ b/app/frontend/src/components/NavBar.tsx @@ -8,7 +8,7 @@ import { NavigationMenuItem, NavigationMenuList, } from "./ui/navigation-menu"; -import { Home, BrainCog, BotMessageSquare, Notebook } from "lucide-react"; // Import BotMessageSquare +import { Home, BrainCog, BotMessageSquare, Notebook } from "lucide-react"; import ModeToggle from "./DarkModeToggle"; import HelpIcon from "./HelpIcon"; import { Separator } from "./ui/separator"; @@ -111,10 +111,25 @@ export default function NavBar() { to="/" className={({ isActive }) => getNavLinkClass(isActive)} > - - {!isChatUI && Home} + {isChatUI ? ( + + + + + +

Home

+
+
+ ) : ( + <> + + Home + + )}
{!isChatUI && ( @@ -130,12 +145,28 @@ export default function NavBar() { to="/rag-management" className={({ isActive }) => getNavLinkClass(isActive)} > - - {!isChatUI && Rag Management} + {isChatUI ? ( + + + + + +

Rag Management

+
+
+ ) : ( + <> + + Rag Management + + )}
+ {!isChatUI && ( getNavLinkClass(isActive)} > - - {!isChatUI && Models Deployed} + {isChatUI ? ( + + + + + +

Models Deployed

+
+
+ ) : ( + <> + + Models Deployed + + )} {isChatUI && ( @@ -163,9 +209,16 @@ export default function NavBar() { to="/chat-ui" className={({ isActive }) => getNavLinkClass(isActive)} > - + + + + + +

Chat UI

+
+
)} @@ -216,9 +269,38 @@ export default function NavBar() {
{isChatUI && (
- - - + + + +
+ +
+
+ +

Toggle Dark/Light Mode

+
+
+ + +
+ +
+
+ +

Reset Board

+
+
+ + +
+ +
+
+ +

Get Help

+
+
+
)} From 3599460f793d026274eab4de72afe54c4dc45c41 Mon Sep 17 00:00:00 2001 From: Anirudh Ramchandran Date: Sat, 21 Sep 2024 09:15:34 -0400 Subject: [PATCH 45/61] feat(chat-ui): update scroll behavior and UI enhancements (#46) - Removed auto-scroll behavior. - Added an icon to allow users to click to scroll to the bottom of the chat history. - Increased right padding in the message window. - Moved the scroll button to the middle of the page. - Changed toast message for better clarity. - Increased z-index and adjusted the position of the scroll button in the chat UI page. - Refactored code for better maintainability. - fixes #31. --- app/frontend/src/api/modelsDeployedApis.ts | 3 +- app/frontend/src/components/ChatComponent.tsx | 189 +++++++----------- app/frontend/src/components/ChatExamples.tsx | 61 ++++++ 3 files changed, 132 insertions(+), 121 deletions(-) create mode 100644 app/frontend/src/components/ChatExamples.tsx diff --git a/app/frontend/src/api/modelsDeployedApis.ts b/app/frontend/src/api/modelsDeployedApis.ts index 81f38a88..f37e436c 100644 --- a/app/frontend/src/api/modelsDeployedApis.ts +++ b/app/frontend/src/api/modelsDeployedApis.ts @@ -163,7 +163,8 @@ export const handleChatUI = ( ): void => { console.log(`ChatUI button clicked for model: ${modelID}`); console.log(`Opening Chat UI for model: ${modelName}`); - customToast.success(`Chat UI for model ${modelID} (${modelName}) opened.`); + // customToast.success(`Chat UI for model:${modelName} opened.`); + customToast.success(`Chat UI page opened!`); navigate("/chat-ui", { state: { containerID: modelID, modelName: modelName }, diff --git a/app/frontend/src/components/ChatComponent.tsx b/app/frontend/src/components/ChatComponent.tsx index feaf1b39..f50bef4d 100644 --- a/app/frontend/src/components/ChatComponent.tsx +++ b/app/frontend/src/components/ChatComponent.tsx @@ -3,17 +3,10 @@ import React, { useEffect, useState, useRef } from "react"; import { Card } from "./ui/card"; import { Button } from "./ui/button"; -import { ScrollArea } from "./ui/scroll-area"; +import * as ScrollArea from "@radix-ui/react-scroll-area"; import { useLocation } from "react-router-dom"; import { Spinner } from "./ui/spinner"; -import { - MessageCircle, - Smile, - CloudSun, - Lightbulb, - User, - ChevronDown, -} from "lucide-react"; +import { User, ChevronDown } from "lucide-react"; import { Textarea } from "./ui/textarea"; import logo from "../assets/tt_logo.svg"; import { @@ -32,6 +25,7 @@ import { DropdownMenuTrigger, } from "./ui/dropdown-menu"; import { fetchModels } from "../api/modelsDeployedApis"; +import ChatExamples from "./ChatExamples"; import axios from "axios"; import { Select, @@ -83,7 +77,7 @@ const ChatComponent: React.FC = () => { const [modelID, setModelID] = useState(null); const [modelName, setModelName] = useState(null); const [isStreaming, setIsStreaming] = useState(false); - const scrollAreaRef = useRef(null); + const viewportRef = useRef(null); const bottomRef = useRef(null); const [isScrollButtonVisible, setIsScrollButtonVisible] = useState(false); const [modelsDeployed, setModelsDeployed] = useState([]); @@ -107,20 +101,19 @@ const ChatComponent: React.FC = () => { }, [location.state]); const scrollToBottom = () => { - if (bottomRef.current) { - bottomRef.current.scrollIntoView({ behavior: "smooth" }); + if (viewportRef.current) { + viewportRef.current.scrollTo({ + top: viewportRef.current.scrollHeight, + behavior: "smooth", + }); } }; - useEffect(() => { - scrollToBottom(); - }, [chatHistory]); - const handleScroll = () => { - if (scrollAreaRef.current) { + if (viewportRef.current) { const isAtBottom = - scrollAreaRef.current.scrollHeight - scrollAreaRef.current.scrollTop <= - scrollAreaRef.current.clientHeight + 1; + viewportRef.current.scrollHeight - viewportRef.current.scrollTop <= + viewportRef.current.clientHeight + 1; setIsScrollButtonVisible(!isAtBottom); } }; @@ -197,7 +190,6 @@ const ChatComponent: React.FC = () => { ]; } }); - scrollToBottom(); } } } @@ -319,113 +311,70 @@ const ChatComponent: React.FC = () => {
- { - const dataSource = ragDataSources.find((rds: RagDataSource) => { - return rds.name == v; - }); - if (dataSource) { - setRagDatasource(dataSource); - } - }} - activeCollection={ragDatasource} - /> + { + const dataSource = ragDataSources.find((rds: RagDataSource) => { + return rds.name == v; + }); + if (dataSource) { + setRagDatasource(dataSource); + } + }} + activeCollection={ragDatasource} + /> {chatHistory.length === 0 && ( -
- Tenstorrent Logo -

- Start a conversation with LLM Studio Chat... -

-
-
- setTextInput("Hello, how are you today?")} - > - - - Hello, how are you today? - - - setTextInput("Can you tell me a joke?")} - > - - - Can you tell me a joke? - - - setTextInput("What's the weather like?")} - > - - - What's the weather like? - - - setTextInput("Tell me a fun fact.")} - > - - - Tell me a fun fact. - - -
-
-
+ )} {chatHistory.length > 0 && (
- - {chatHistory.map((message, index) => ( -
-
-
- {message.sender === "user" ? ( - - ) : ( - Tenstorrent Logo - )} -
-
+ + + {chatHistory.map((message, index) => (
- {message.text} +
+
+ {message.sender === "user" ? ( + + ) : ( + Tenstorrent Logo + )} +
+
+
+ {message.text} +
-
- ))} -
- + ))} +
+ + + + + {isScrollButtonVisible && ( diff --git a/app/frontend/src/pages/rag/RagManagement.tsx b/app/frontend/src/pages/rag/RagManagement.tsx index 9a14fcb6..c78b4ad4 100644 --- a/app/frontend/src/pages/rag/RagManagement.tsx +++ b/app/frontend/src/pages/rag/RagManagement.tsx @@ -148,7 +148,7 @@ export default function RagManagement() { }; const renderRow = ({ - theme, + // theme, item, isUploading, onDelete, @@ -191,7 +191,6 @@ export default function RagManagement() { disabled={isUploading} className="bg-blue-500 dark:bg-blue-700 hover:bg-blue-600 dark:hover:bg-blue-600 text-white rounded-lg" onClick={() => onUploadClick(item)} - className="bg-blue-500 dark:bg-blue-700 hover:bg-blue-600 dark:hover:bg-blue-600 text-white rounded-lg" > Upload Document diff --git a/app/frontend/src/routes/index.tsx b/app/frontend/src/routes/index.tsx index d9fef55d..faa9f9dd 100644 --- a/app/frontend/src/routes/index.tsx +++ b/app/frontend/src/routes/index.tsx @@ -12,15 +12,15 @@ import RagManagement from "../pages/rag/RagManagement"; const AppRouter = () => { return ( - - - - } /> - } /> - } /> - } /> - - + + + + } /> + } /> + } /> + } /> + + ); }; diff --git a/app/frontend/vite.config.ts b/app/frontend/vite.config.ts index 5bdf94af..63b6b2c1 100644 --- a/app/frontend/vite.config.ts +++ b/app/frontend/vite.config.ts @@ -24,19 +24,36 @@ const proxyConfig: Record = Object.fromEntries( secure: true, // debug logging configure: (proxy: HttpProxy.Server) => { - proxy.on("error", (err: Error, _req: IncomingMessage, _res: ServerResponse) => { - console.log("proxy error", err); - }); - proxy.on("proxyReq", (proxyReq: ClientRequest, req: IncomingMessage, _res: ServerResponse) => { - console.log("Sending Request to the Target:", req.method, req.url); - }); - proxy.on("proxyRes", (proxyRes: IncomingMessage, req: IncomingMessage, _res: ServerResponse) => { - console.log( - "Received Response from the Target:", - proxyRes.statusCode, - req.url, - ); - }); + proxy.on( + "error", + (err: Error, _req: IncomingMessage, _res: ServerResponse) => { + console.log("proxy error", err); + }, + ); + proxy.on( + "proxyReq", + ( + proxyReq: ClientRequest, + req: IncomingMessage, + _res: ServerResponse, + ) => { + console.log("Sending Request to the Target:", req.method, req.url); + }, + ); + proxy.on( + "proxyRes", + ( + proxyRes: IncomingMessage, + req: IncomingMessage, + _res: ServerResponse, + ) => { + console.log( + "Received Response from the Target:", + proxyRes.statusCode, + req.url, + ); + }, + ); }, rewrite: (path: string) => path.replace(new RegExp(`^/${proxyPath}`), `/${actualPath}`), diff --git a/models/tt-metal-falcon-7b/src/_mock_inference_api_server.py b/models/tt-metal-falcon-7b/src/_mock_inference_api_server.py index a31f6f69..a1b61c14 100644 --- a/models/tt-metal-falcon-7b/src/_mock_inference_api_server.py +++ b/models/tt-metal-falcon-7b/src/_mock_inference_api_server.py @@ -2,6 +2,8 @@ # # SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + + import os from time import sleep from unittest.mock import Mock, patch From d4a7689ffa7ef5f7a907d16544e58ccc66c164bb Mon Sep 17 00:00:00 2001 From: Anirudh Ramchandran Date: Tue, 29 Oct 2024 11:25:15 -0400 Subject: [PATCH 47/61] Anirud/v1 end to end testing (#70) * update package json and package lock json - plus run npm audit fix * move rag folder into components folder * remove browser auto-fill on rag input * correct rag input error message colors * clear rag input field post submit * update deploy model functionality: - add dynamic button text, -disable logic - refresh handling * more updated to deploy model - to show previously selected model and weights * update models deployed table to refresh model context * Adds models context to refresh deployed models throughtout the app * add more model interfaces * Adds Models Provider * update animated deploy button * update navbar: - show chatui icon - greyed out when no models deployed - shown when a single or more model is deployed - updates the models provider so that other components can subscribe * update navabr - adds seperator - updates icon for models deployed * better error management when deployment fails * shows user when model is being deleted * remove model id from toast message * adds better animation when deploying a model * Pre select default weights: - add an animation when the component mounts to show the default weight is selected * removes finetuer option * fix: bugs in chatui page and improve layout: - Restructure chat message layout for better alignment - Implement max-width and text wrapping for long messages - Adjust chat bubble styling for consistent appearance - Enhance ScrollArea to improve spacing between messages - add tooltip in menu bar - adjust menu bar look and layout - adjust inferecne button to be better * Add better scroll down button when text is very large * feat (Custom Toaster ) - gets a info toast message * fix ts form errors * Add log view feature: ListLogsView and GetLogView endpoints * add log viewer views to test POC * WIP: Add log view feature: to frontend to test POC * WIP: log viewer - update frontend to accept tree file structure from backend * Enhance LogsViewer icons and add visual indicators - Add color to folder (yellow) and file (blue) icons - Introduce ExternalLink icon for log files on hover - Improve button layout for better visual hierarchy - Maintain existing functionality and component structure * fix(logs-viewer): ensure correct log file path handling in frontend + backend - Removed double-encoding of log file paths when constructing URLs for fetching logs - Improved log file tree rendering for better user experience when navigating directories * clean out log viewer feature * better button effects throughtout the app * fix syntax errors * Navbar icons get a new button variant * updates models deployed page for better icons and ux * fixed named exports in models deployed * fix import * update chatui component - add back scroll wheel - make it default export * switch to export default * update model config: to support llama3-70 - adds ModelImpl for llamma3-70b - sets WH_ARCH_YAML in case device is N150 or N300x4 * adds temperature and max tokens to the post req to the model * up streams new model config and uses intruct weights * overhaul chat component to accept infernce from lamma models and show stats * Append the custom end marker after the last chunk to ensure frontend reads all infernce chunks * updates tsconfig * adds infernce stat component * updates backgound * update to v1.0 * fix ts vite warnings fixes #61 * remove streaming info for now * refctor to use: - only folders that contain logs * refactor functions to new files with module scope * attempt to sort logs by date * added mistral to model config * removing old implemention in model config * Anirud/fix refactor chatui page (#64) * refactor(Header): Resolve ref warning and improve type safety - Extract ModelSelector as a separate forwardRef component - Fix TypeScript errors in DropdownMenu implementation - Improve overall type safety in Header component - fixes #62 * refactor ChatUI component - Break down large ChatComponent into smaller, reusable components in its own folder - Create separate Header, ChatHistory, and InputArea components - move chat components like stats, examples into its own folder called "chatui" * refactor: chatui history and examples - add scroll back which allows user to scoll to bottom of chat * keep focus on chat text area * Refactor ChatComponent for improved modularity - Move utility functions to separate files - Update imports to use new utility files - Simplify handleInference function * increase cycle time before moving to a new chat example * Create refactored runInference.ts for inference processing * Create getRagContext.ts for RAG functionality * Create types.ts with shared interfaces across chat ui * remove this unused component --------- Co-authored-by: Mithun Vanniasinghe --- app/api/api/settings.py | 1 + app/api/api/urls.py | 1 + app/api/logs_control/__init__.py | 3 + app/api/logs_control/urls.py | 10 + app/api/logs_control/views.py | 81 ++++ app/api/model_control/model_utils.py | 17 +- app/api/shared_config/model_config.py | 35 +- app/frontend/index.html | 4 +- app/frontend/package-lock.json | 188 ++++---- app/frontend/package.json | 2 +- app/frontend/src/api/modelsDeployedApis.ts | 2 +- app/frontend/src/components/ChatComponent.tsx | 422 ------------------ app/frontend/src/components/ChatExamples.tsx | 61 --- app/frontend/src/components/CustomToaster.tsx | 9 + .../src/components/DarkModeToggle.tsx | 2 +- .../src/components/DeployModelStep.tsx | 97 +++- app/frontend/src/components/HelpIcon.tsx | 2 +- .../src/components/ModelsDeployedTable.tsx | 130 ++++-- app/frontend/src/components/NavBar.tsx | 173 ++++--- app/frontend/src/components/ResetIcon.tsx | 2 +- .../src/components/SecondStepForm.tsx | 103 +++-- .../src/components/SelectionSteps.tsx | 3 +- .../src/components/StepperFormActions.tsx | 13 +- .../src/components/chatui/ChatComponent.tsx | 94 ++++ .../src/components/chatui/ChatExamples.tsx | 120 +++++ .../src/components/chatui/ChatHistory.tsx | 133 ++++++ app/frontend/src/components/chatui/Header.tsx | 176 ++++++++ .../src/components/chatui/InferenceStats.tsx | 102 +++++ .../src/components/chatui/InputArea.tsx | 72 +++ .../src/components/chatui/getRagContext.ts | 29 ++ .../src/components/chatui/runInference.ts | 101 +++++ app/frontend/src/components/chatui/types.ts | 40 ++ .../src/components/log_viewer/LogViewer.tsx | 205 +++++++++ .../log_viewer/openEncodedLogInNewTab.tsx | 12 + .../log_viewer/parseLogFileName.tsx | 20 + .../magicui/AnimatedDeployButton.tsx | 171 +++++-- .../rag/RagDataSourceForm.tsx | 16 +- .../rag/RagManagement.tsx | 2 +- .../src/{pages => components}/rag/index.ts | 0 app/frontend/src/components/ui/button.tsx | 14 +- app/frontend/src/pages/ChatUIPage.tsx | 4 +- app/frontend/src/pages/LogsPage.tsx | 24 + app/frontend/src/pages/ModelsDeployed.tsx | 2 +- app/frontend/src/providers/ModelsContext.tsx | 52 +++ app/frontend/src/routes/index.tsx | 27 +- app/frontend/tsconfig.json | 3 +- app/frontend/vite.config.ts | 1 + 47 files changed, 1985 insertions(+), 796 deletions(-) create mode 100644 app/api/logs_control/__init__.py create mode 100644 app/api/logs_control/urls.py create mode 100644 app/api/logs_control/views.py delete mode 100644 app/frontend/src/components/ChatComponent.tsx delete mode 100644 app/frontend/src/components/ChatExamples.tsx create mode 100644 app/frontend/src/components/chatui/ChatComponent.tsx create mode 100644 app/frontend/src/components/chatui/ChatExamples.tsx create mode 100644 app/frontend/src/components/chatui/ChatHistory.tsx create mode 100644 app/frontend/src/components/chatui/Header.tsx create mode 100644 app/frontend/src/components/chatui/InferenceStats.tsx create mode 100644 app/frontend/src/components/chatui/InputArea.tsx create mode 100644 app/frontend/src/components/chatui/getRagContext.ts create mode 100644 app/frontend/src/components/chatui/runInference.ts create mode 100644 app/frontend/src/components/chatui/types.ts create mode 100644 app/frontend/src/components/log_viewer/LogViewer.tsx create mode 100644 app/frontend/src/components/log_viewer/openEncodedLogInNewTab.tsx create mode 100644 app/frontend/src/components/log_viewer/parseLogFileName.tsx rename app/frontend/src/{pages => components}/rag/RagDataSourceForm.tsx (73%) rename app/frontend/src/{pages => components}/rag/RagManagement.tsx (99%) rename app/frontend/src/{pages => components}/rag/index.ts (100%) create mode 100644 app/frontend/src/pages/LogsPage.tsx create mode 100644 app/frontend/src/providers/ModelsContext.tsx diff --git a/app/api/api/settings.py b/app/api/api/settings.py index b49debb0..b6b375bb 100644 --- a/app/api/api/settings.py +++ b/app/api/api/settings.py @@ -56,6 +56,7 @@ "model_control", "vector_db_control", "corsheaders", + "logs_control", ] MIDDLEWARE = [ diff --git a/app/api/api/urls.py b/app/api/api/urls.py index 28e6d331..28ee8856 100644 --- a/app/api/api/urls.py +++ b/app/api/api/urls.py @@ -30,4 +30,5 @@ path("models/", include("model_control.urls")), path('reset_board/', include('docker_control.urls')), path("collections/", include("vector_db_control.urls")), + path("logs/", include("logs_control.urls")), ] diff --git a/app/api/logs_control/__init__.py b/app/api/logs_control/__init__.py new file mode 100644 index 00000000..deca65cf --- /dev/null +++ b/app/api/logs_control/__init__.py @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC \ No newline at end of file diff --git a/app/api/logs_control/urls.py b/app/api/logs_control/urls.py new file mode 100644 index 00000000..47f333ff --- /dev/null +++ b/app/api/logs_control/urls.py @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: Apache-2.0 +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + +from django.urls import path +from .views import ListLogsView, GetLogView + +urlpatterns = [ + path('', ListLogsView.as_view(), name='list_logs'), + path('/', GetLogView.as_view(), name='get_log'), # Use for multi-directory paths +] \ No newline at end of file diff --git a/app/api/logs_control/views.py b/app/api/logs_control/views.py new file mode 100644 index 00000000..428a5a2b --- /dev/null +++ b/app/api/logs_control/views.py @@ -0,0 +1,81 @@ +# SPDX-License-Identifier: Apache-2.0 +# SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC + +import os +from urllib.parse import unquote +from django.http import JsonResponse, HttpResponse, Http404 +from rest_framework.views import APIView +from shared_config.logger_config import get_logger + +# Setting up logger +logger = get_logger(__name__) + +# Use environment variable for the base storage volume +LOGS_ROOT = os.getenv("INTERNAL_PERSISTENT_STORAGE_VOLUME", "/path/to/fallback") + +class ListLogsView(APIView): + """ + Lists all available directories and log files within the base logs directory + """ + def get(self, request, *args, **kwargs): + logger.info("ListLogsView endpoint hit") + try: + logs_tree = self.build_logs_tree(LOGS_ROOT) + logger.info(f"Log tree built: {logs_tree}") + return JsonResponse({'logs': logs_tree}, status=200) + except Exception as e: + logger.error(f"Error listing logs: {e}") + return JsonResponse({'error': str(e)}, status=500) + + def build_logs_tree(self, directory): + """ + Recursively build a tree of directories and files. + """ + tree = [] + for entry in os.listdir(directory): + path = os.path.join(directory, entry) + if os.path.isdir(path): + tree.append({ + "name": entry, + "type": "directory", + "children": self.build_logs_tree(path) + }) + elif entry.endswith(".log"): + tree.append({ + "name": entry, + "type": "file" + }) + return tree + + +class GetLogView(APIView): + """ + Retrieves the content of a specific log file from the logs directory. + """ + def get(self, request, filename, *args, **kwargs): + + decoded_filename = unquote(filename) + + file_path = os.path.normpath(os.path.join(LOGS_ROOT, decoded_filename)) + + # Security check: Ensure the resolved path is within LOGS_ROOT + if not file_path.startswith(os.path.abspath(LOGS_ROOT)): + logger.error(f"Invalid log file path: {file_path}") + raise Http404("Invalid file path.") + + logger.info(f"Looking for log file at: {file_path}") + + + if os.path.exists(file_path) and os.path.isfile(file_path): + try: + with open(file_path, 'r') as file: + content = file.read() + logger.info(f"Successfully retrieved content for log: {decoded_filename}") + return HttpResponse(content, content_type='text/plain') + except Exception as e: + logger.error(f"Error reading log file {decoded_filename}: {e}") + return JsonResponse({'error': str(e)}, status=500) + else: + logger.error(f"Log file {decoded_filename} not found at {file_path}") + raise Http404(f"Log file {decoded_filename} not found.") + diff --git a/app/api/model_control/model_utils.py b/app/api/model_control/model_utils.py index dfc846ed..3c7669fe 100644 --- a/app/api/model_control/model_utils.py +++ b/app/api/model_control/model_utils.py @@ -34,21 +34,34 @@ def get_all_records(): data = get_all_records() return data - def stream_response_from_external_api(url, json_data): logger.info(f"stream_response_from_external_api to: url={url}") try: headers = {"Authorization": f"Bearer {encoded_jwt}"} + logger.info(f"stream_response_from_external_api headers:={headers}") + logger.info(f"stream_response_from_external_api json_data:={json_data}") + json_data["temperature"] = 1 + json_data["max_tokens"] = 128 + logger.info(f"added extra token and temp!:={json_data}") + with requests.post( url, json=json_data, headers=headers, stream=True, timeout=None ) as response: + logger.info(f"stream_response_from_external_api response:={response}") response.raise_for_status() logger.info(f"response.headers:={response.headers}") logger.info(f"response.encoding:={response.encoding}") # only allow HTTP 1.1 chunked encoding assert response.headers.get("transfer-encoding") == "chunked" - # Note: chunk_size=None must be passed or it will chunk single chars + + # Stream chunks for chunk in response.iter_content(chunk_size=None, decode_unicode=True): + logger.info(f"stream_response_from_external_api chunk:={chunk}") yield chunk + + # Append the custom end marker after the last chunk + yield "<>" # Custom marker to signal end of stream + + logger.info("stream_response_from_external done") except requests.RequestException as e: yield str(e) diff --git a/app/api/shared_config/model_config.py b/app/api/shared_config/model_config.py index 526712ac..c62856ed 100644 --- a/app/api/shared_config/model_config.py +++ b/app/api/shared_config/model_config.py @@ -25,9 +25,7 @@ class ModelImpl: model_id: str image_name: str image_tag: str - device_configurations: Set[ - "DeviceConfigurations" - ] # Assuming DeviceConfigurations is an enum or similar + device_configurations: Set["DeviceConfigurations"] docker_config: Dict[str, Any] user_uid: int # user inside docker container uid (for file permissions) user_gid: int # user inside docker container gid (for file permissions) @@ -41,6 +39,10 @@ def __post_init__(self): self.docker_config["environment"]["HF_HOME"] = Path( backend_config.model_container_cache_root ).joinpath("huggingface") + + # Set environment variable if N150 or N300x4 is in the device configurations + if DeviceConfigurations.N150 in self.device_configurations or DeviceConfigurations.N300x4 in self.device_configurations: + self.docker_config["environment"]["WH_ARCH_YAML"] = "wormhole_b0_80_arch_eth_dispatch.yaml" @property def image_version(self) -> str: @@ -150,9 +152,34 @@ def base_docker_config(): service_port=7000, service_route="/inference/falcon7b", ), + ModelImpl( + model_name="Llama3.1-70bv0.0.1-instruct", + model_id="id_tt-metal-llama-3.1-70b-instructv0.0.1", + image_name="ghcr.io/tenstorrent/tt-inference-server/tt-metal-llama3-70b-src-base-inference", + image_tag="v0.0.1-tt-metal-v0.52.0-rc31-9d3be887987b", + device_configurations={DeviceConfigurations.N300x4}, + docker_config=base_docker_config(), + user_uid=1000, + user_gid=1000, + shm_size="32G", + service_port=7000, + service_route="/inference/llama3-70b", + ), + ModelImpl( + model_name="Mistral7B-instruct-v0.2", + model_id="id_tt-metal-mistral-7bv0.0.2", + image_name="ghcr.io/tenstorrent/tt-inference-server/tt-metal-mistral-7b-src-base", + image_tag="v0.0.3-tt-metal-v0.52.0-rc33", + device_configurations={DeviceConfigurations.N300x4}, + docker_config=base_docker_config(), + user_uid=1000, + user_gid=1000, + shm_size="32G", + service_port=7000, + service_route="/inference/mistral7b", + ) ] - def validate_model_implemenation_config(impl): # no / in model_id strings, model_id will be used in path names assert not "/" in impl.model_id diff --git a/app/frontend/index.html b/app/frontend/index.html index 383f2f4e..d2de22e2 100644 --- a/app/frontend/index.html +++ b/app/frontend/index.html @@ -1,10 +1,10 @@ - + - llm studio v0.0 + llm studio v1.0
diff --git a/app/frontend/package-lock.json b/app/frontend/package-lock.json index 72ad382c..4fb719a1 100644 --- a/app/frontend/package-lock.json +++ b/app/frontend/package-lock.json @@ -26,7 +26,7 @@ "@radix-ui/react-separator": "^1.0.3", "@radix-ui/react-slot": "^1.1.0", "@radix-ui/react-tooltip": "^1.0.7", - "@tanstack/react-query": "^5.35.1", + "@tanstack/react-query": "^5.56.2", "axios": "^1.6.8", "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", @@ -2234,9 +2234,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.19.0.tgz", - "integrity": "sha512-JlPfZ/C7yn5S5p0yKk7uhHTTnFlvTgLetl2VxqE518QgyM7C9bSfFTYvB/Q/ftkq0RIPY4ySxTz+/wKJ/dXC0w==", + "version": "4.21.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.21.3.tgz", + "integrity": "sha512-MmKSfaB9GX+zXl6E8z4koOr/xU63AMVleLEa64v7R0QF/ZloMs5vcD1sHgM64GXXS1csaJutG+ddtzcueI/BLg==", "cpu": [ "arm" ], @@ -2247,9 +2247,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.19.0.tgz", - "integrity": "sha512-RDxUSY8D1tWYfn00DDi5myxKgOk6RvWPxhmWexcICt/MEC6yEMr4HNCu1sXXYLw8iAsg0D44NuU+qNq7zVWCrw==", + "version": "4.21.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.21.3.tgz", + "integrity": "sha512-zrt8ecH07PE3sB4jPOggweBjJMzI1JG5xI2DIsUbkA+7K+Gkjys6eV7i9pOenNSDJH3eOr/jLb/PzqtmdwDq5g==", "cpu": [ "arm64" ], @@ -2260,9 +2260,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.19.0.tgz", - "integrity": "sha512-emvKHL4B15x6nlNTBMtIaC9tLPRpeA5jMvRLXVbl/W9Ie7HhkrE7KQjvgS9uxgatL1HmHWDXk5TTS4IaNJxbAA==", + "version": "4.21.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.21.3.tgz", + "integrity": "sha512-P0UxIOrKNBFTQaXTxOH4RxuEBVCgEA5UTNV6Yz7z9QHnUJ7eLX9reOd/NYMO3+XZO2cco19mXTxDMXxit4R/eQ==", "cpu": [ "arm64" ], @@ -2273,9 +2273,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.19.0.tgz", - "integrity": "sha512-fO28cWA1dC57qCd+D0rfLC4VPbh6EOJXrreBmFLWPGI9dpMlER2YwSPZzSGfq11XgcEpPukPTfEVFtw2q2nYJg==", + "version": "4.21.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.21.3.tgz", + "integrity": "sha512-L1M0vKGO5ASKntqtsFEjTq/fD91vAqnzeaF6sfNAy55aD+Hi2pBI5DKwCO+UNDQHWsDViJLqshxOahXyLSh3EA==", "cpu": [ "x64" ], @@ -2286,9 +2286,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.19.0.tgz", - "integrity": "sha512-2Rn36Ubxdv32NUcfm0wB1tgKqkQuft00PtM23VqLuCUR4N5jcNWDoV5iBC9jeGdgS38WK66ElncprqgMUOyomw==", + "version": "4.21.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.21.3.tgz", + "integrity": "sha512-btVgIsCjuYFKUjopPoWiDqmoUXQDiW2A4C3Mtmp5vACm7/GnyuprqIDPNczeyR5W8rTXEbkmrJux7cJmD99D2g==", "cpu": [ "arm" ], @@ -2299,9 +2299,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.19.0.tgz", - "integrity": "sha512-gJuzIVdq/X1ZA2bHeCGCISe0VWqCoNT8BvkQ+BfsixXwTOndhtLUpOg0A1Fcx/+eA6ei6rMBzlOz4JzmiDw7JQ==", + "version": "4.21.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.21.3.tgz", + "integrity": "sha512-zmjbSphplZlau6ZTkxd3+NMtE4UKVy7U4aVFMmHcgO5CUbw17ZP6QCgyxhzGaU/wFFdTfiojjbLG3/0p9HhAqA==", "cpu": [ "arm" ], @@ -2312,9 +2312,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.19.0.tgz", - "integrity": "sha512-0EkX2HYPkSADo9cfeGFoQ7R0/wTKb7q6DdwI4Yn/ULFE1wuRRCHybxpl2goQrx4c/yzK3I8OlgtBu4xvted0ug==", + "version": "4.21.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.21.3.tgz", + "integrity": "sha512-nSZfcZtAnQPRZmUkUQwZq2OjQciR6tEoJaZVFvLHsj0MF6QhNMg0fQ6mUOsiCUpTqxTx0/O6gX0V/nYc7LrgPw==", "cpu": [ "arm64" ], @@ -2325,9 +2325,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.19.0.tgz", - "integrity": "sha512-GlIQRj9px52ISomIOEUq/IojLZqzkvRpdP3cLgIE1wUWaiU5Takwlzpz002q0Nxxr1y2ZgxC2obWxjr13lvxNQ==", + "version": "4.21.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.21.3.tgz", + "integrity": "sha512-MnvSPGO8KJXIMGlQDYfvYS3IosFN2rKsvxRpPO2l2cum+Z3exiExLwVU+GExL96pn8IP+GdH8Tz70EpBhO0sIQ==", "cpu": [ "arm64" ], @@ -2338,9 +2338,9 @@ ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.19.0.tgz", - "integrity": "sha512-N6cFJzssruDLUOKfEKeovCKiHcdwVYOT1Hs6dovDQ61+Y9n3Ek4zXvtghPPelt6U0AH4aDGnDLb83uiJMkWYzQ==", + "version": "4.21.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.21.3.tgz", + "integrity": "sha512-+W+p/9QNDr2vE2AXU0qIy0qQE75E8RTwTwgqS2G5CRQ11vzq0tbnfBd6brWhS9bCRjAjepJe2fvvkvS3dno+iw==", "cpu": [ "ppc64" ], @@ -2351,9 +2351,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.19.0.tgz", - "integrity": "sha512-2DnD3mkS2uuam/alF+I7M84koGwvn3ZVD7uG+LEWpyzo/bq8+kKnus2EVCkcvh6PlNB8QPNFOz6fWd5N8o1CYg==", + "version": "4.21.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.21.3.tgz", + "integrity": "sha512-yXH6K6KfqGXaxHrtr+Uoy+JpNlUlI46BKVyonGiaD74ravdnF9BUNC+vV+SIuB96hUMGShhKV693rF9QDfO6nQ==", "cpu": [ "riscv64" ], @@ -2364,9 +2364,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.19.0.tgz", - "integrity": "sha512-D6pkaF7OpE7lzlTOFCB2m3Ngzu2ykw40Nka9WmKGUOTS3xcIieHe82slQlNq69sVB04ch73thKYIWz/Ian8DUA==", + "version": "4.21.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.21.3.tgz", + "integrity": "sha512-R8cwY9wcnApN/KDYWTH4gV/ypvy9yZUHlbJvfaiXSB48JO3KpwSpjOGqO4jnGkLDSk1hgjYkTbTt6Q7uvPf8eg==", "cpu": [ "s390x" ], @@ -2377,9 +2377,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.19.0.tgz", - "integrity": "sha512-HBndjQLP8OsdJNSxpNIN0einbDmRFg9+UQeZV1eiYupIRuZsDEoeGU43NQsS34Pp166DtwQOnpcbV/zQxM+rWA==", + "version": "4.21.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.21.3.tgz", + "integrity": "sha512-kZPbX/NOPh0vhS5sI+dR8L1bU2cSO9FgxwM8r7wHzGydzfSjLRCFAT87GR5U9scj2rhzN3JPYVC7NoBbl4FZ0g==", "cpu": [ "x64" ], @@ -2390,9 +2390,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.19.0.tgz", - "integrity": "sha512-HxfbvfCKJe/RMYJJn0a12eiOI9OOtAUF4G6ozrFUK95BNyoJaSiBjIOHjZskTUffUrB84IPKkFG9H9nEvJGW6A==", + "version": "4.21.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.21.3.tgz", + "integrity": "sha512-S0Yq+xA1VEH66uiMNhijsWAafffydd2X5b77eLHfRmfLsRSpbiAWiRHV6DEpz6aOToPsgid7TI9rGd6zB1rhbg==", "cpu": [ "x64" ], @@ -2403,9 +2403,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.19.0.tgz", - "integrity": "sha512-HxDMKIhmcguGTiP5TsLNolwBUK3nGGUEoV/BO9ldUBoMLBssvh4J0X8pf11i1fTV7WShWItB1bKAKjX4RQeYmg==", + "version": "4.21.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.21.3.tgz", + "integrity": "sha512-9isNzeL34yquCPyerog+IMCNxKR8XYmGd0tHSV+OVx0TmE0aJOo9uw4fZfUuk2qxobP5sug6vNdZR6u7Mw7Q+Q==", "cpu": [ "arm64" ], @@ -2416,9 +2416,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.19.0.tgz", - "integrity": "sha512-xItlIAZZaiG/u0wooGzRsx11rokP4qyc/79LkAOdznGRAbOFc+SfEdfUOszG1odsHNgwippUJavag/+W/Etc6Q==", + "version": "4.21.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.21.3.tgz", + "integrity": "sha512-nMIdKnfZfzn1Vsk+RuOvl43ONTZXoAPUUxgcU0tXooqg4YrAqzfKzVenqqk2g5efWh46/D28cKFrOzDSW28gTA==", "cpu": [ "ia32" ], @@ -2429,9 +2429,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.19.0.tgz", - "integrity": "sha512-xNo5fV5ycvCCKqiZcpB65VMR11NJB+StnxHz20jdqRAktfdfzhgjTiJ2doTDQE/7dqGaV5I7ZGqKpgph6lCIag==", + "version": "4.21.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.21.3.tgz", + "integrity": "sha512-fOvu7PCQjAj4eWDEuD8Xz5gpzFqXzGlxHZozHP4b9Jxv9APtdxL6STqztDzMLuRXEc4UpXGGhx029Xgm91QBeA==", "cpu": [ "x64" ], @@ -2719,27 +2719,27 @@ } }, "node_modules/@tanstack/query-core": { - "version": "5.51.9", - "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.51.9.tgz", - "integrity": "sha512-HsAwaY5J19MD18ykZDS3aVVh+bAt0i7m6uQlFC2b77DLV9djo+xEN7MWQAQQTR8IM+7r/zbozTQ7P0xr0bHuew==", + "version": "5.56.2", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.56.2.tgz", + "integrity": "sha512-gor0RI3/R5rVV3gXfddh1MM+hgl0Z4G7tj6Xxpq6p2I03NGPaJ8dITY9Gz05zYYb/EJq9vPas/T4wn9EaDPd4Q==", "funding": { "type": "github", "url": "https://github.com/sponsors/tannerlinsley" } }, "node_modules/@tanstack/react-query": { - "version": "5.51.11", - "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.51.11.tgz", - "integrity": "sha512-4Kq2x0XpDlpvSnaLG+8pHNH60zEc3mBvb3B2tOMDjcPCi/o+Du3p/9qpPLwJOTliVxxPJAP27fuIhLrsRdCr7A==", + "version": "5.56.2", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.56.2.tgz", + "integrity": "sha512-SR0GzHVo6yzhN72pnRhkEFRAHMsUo5ZPzAxfTMvUxFIDVS6W9LYUp6nXW3fcHVdg0ZJl8opSH85jqahvm6DSVg==", "dependencies": { - "@tanstack/query-core": "5.51.9" + "@tanstack/query-core": "5.56.2" }, "funding": { "type": "github", "url": "https://github.com/sponsors/tannerlinsley" }, "peerDependencies": { - "react": "^18.0.0" + "react": "^18 || ^19" } }, "node_modules/@tsconfig/node10": { @@ -6535,9 +6535,9 @@ } }, "node_modules/picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==" + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", + "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==" }, "node_modules/picomatch": { "version": "2.3.1", @@ -6567,9 +6567,9 @@ } }, "node_modules/postcss": { - "version": "8.4.41", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.41.tgz", - "integrity": "sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==", + "version": "8.4.47", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz", + "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==", "funding": [ { "type": "opencollective", @@ -6586,8 +6586,8 @@ ], "dependencies": { "nanoid": "^3.3.7", - "picocolors": "^1.0.1", - "source-map-js": "^1.2.0" + "picocolors": "^1.1.0", + "source-map-js": "^1.2.1" }, "engines": { "node": "^10 || ^12 || >=14" @@ -7230,9 +7230,9 @@ } }, "node_modules/rollup": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.19.0.tgz", - "integrity": "sha512-5r7EYSQIowHsK4eTZ0Y81qpZuJz+MUuYeqmmYmRMl1nwhdmbiYqt5jwzf6u7wyOzJgYqtCRMtVRKOtHANBz7rA==", + "version": "4.21.3", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.21.3.tgz", + "integrity": "sha512-7sqRtBNnEbcBtMeRVc6VRsJMmpI+JU1z9VTvW8D4gXIYQFz0aLcsE6rRkyghZkLfEgUZgVvOG7A5CVz/VW5GIA==", "dev": true, "dependencies": { "@types/estree": "1.0.5" @@ -7245,22 +7245,22 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.19.0", - "@rollup/rollup-android-arm64": "4.19.0", - "@rollup/rollup-darwin-arm64": "4.19.0", - "@rollup/rollup-darwin-x64": "4.19.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.19.0", - "@rollup/rollup-linux-arm-musleabihf": "4.19.0", - "@rollup/rollup-linux-arm64-gnu": "4.19.0", - "@rollup/rollup-linux-arm64-musl": "4.19.0", - "@rollup/rollup-linux-powerpc64le-gnu": "4.19.0", - "@rollup/rollup-linux-riscv64-gnu": "4.19.0", - "@rollup/rollup-linux-s390x-gnu": "4.19.0", - "@rollup/rollup-linux-x64-gnu": "4.19.0", - "@rollup/rollup-linux-x64-musl": "4.19.0", - "@rollup/rollup-win32-arm64-msvc": "4.19.0", - "@rollup/rollup-win32-ia32-msvc": "4.19.0", - "@rollup/rollup-win32-x64-msvc": "4.19.0", + "@rollup/rollup-android-arm-eabi": "4.21.3", + "@rollup/rollup-android-arm64": "4.21.3", + "@rollup/rollup-darwin-arm64": "4.21.3", + "@rollup/rollup-darwin-x64": "4.21.3", + "@rollup/rollup-linux-arm-gnueabihf": "4.21.3", + "@rollup/rollup-linux-arm-musleabihf": "4.21.3", + "@rollup/rollup-linux-arm64-gnu": "4.21.3", + "@rollup/rollup-linux-arm64-musl": "4.21.3", + "@rollup/rollup-linux-powerpc64le-gnu": "4.21.3", + "@rollup/rollup-linux-riscv64-gnu": "4.21.3", + "@rollup/rollup-linux-s390x-gnu": "4.21.3", + "@rollup/rollup-linux-x64-gnu": "4.21.3", + "@rollup/rollup-linux-x64-musl": "4.21.3", + "@rollup/rollup-win32-arm64-msvc": "4.21.3", + "@rollup/rollup-win32-ia32-msvc": "4.21.3", + "@rollup/rollup-win32-x64-msvc": "4.21.3", "fsevents": "~2.3.2" } }, @@ -7433,9 +7433,9 @@ } }, "node_modules/source-map-js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", - "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", "engines": { "node": ">=0.10.0" } @@ -8181,14 +8181,14 @@ } }, "node_modules/vite": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.4.tgz", - "integrity": "sha512-Cw+7zL3ZG9/NZBB8C+8QbQZmR54GwqIz+WMI4b3JgdYJvX+ny9AjJXqkGQlDXSXRP9rP0B4tbciRMOVEKulVOA==", + "version": "5.4.6", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.6.tgz", + "integrity": "sha512-IeL5f8OO5nylsgzd9tq4qD2QqI0k2CQLGrWD0rCN0EQJZpBK5vJAx0I+GDkMOXxQX/OfFHMuLIx6ddAxGX/k+Q==", "dev": true, "dependencies": { "esbuild": "^0.21.3", - "postcss": "^8.4.39", - "rollup": "^4.13.0" + "postcss": "^8.4.43", + "rollup": "^4.20.0" }, "bin": { "vite": "bin/vite.js" @@ -8207,6 +8207,7 @@ "less": "*", "lightningcss": "^1.21.0", "sass": "*", + "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.4.0" @@ -8224,6 +8225,9 @@ "sass": { "optional": true }, + "sass-embedded": { + "optional": true + }, "stylus": { "optional": true }, diff --git a/app/frontend/package.json b/app/frontend/package.json index cd62af72..aad719ee 100644 --- a/app/frontend/package.json +++ b/app/frontend/package.json @@ -29,7 +29,7 @@ "@radix-ui/react-separator": "^1.0.3", "@radix-ui/react-slot": "^1.1.0", "@radix-ui/react-tooltip": "^1.0.7", - "@tanstack/react-query": "^5.35.1", + "@tanstack/react-query": "^5.56.2", "axios": "^1.6.8", "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", diff --git a/app/frontend/src/api/modelsDeployedApis.ts b/app/frontend/src/api/modelsDeployedApis.ts index f37e436c..9bfaf4dc 100644 --- a/app/frontend/src/api/modelsDeployedApis.ts +++ b/app/frontend/src/api/modelsDeployedApis.ts @@ -117,7 +117,7 @@ export const deleteModel = async (modelId: string): Promise => { `Model ID: ${truncatedModelId} has been reset successfully.`, ); } else { - customToast.error(`Model ID: ${truncatedModelId} reset failed.`); + customToast.error(`Board Reset failed.`); } console.log( diff --git a/app/frontend/src/components/ChatComponent.tsx b/app/frontend/src/components/ChatComponent.tsx deleted file mode 100644 index f50bef4d..00000000 --- a/app/frontend/src/components/ChatComponent.tsx +++ /dev/null @@ -1,422 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// SPDX-FileCopyrightText: © 2024 Tenstorrent AI ULC -import React, { useEffect, useState, useRef } from "react"; -import { Card } from "./ui/card"; -import { Button } from "./ui/button"; -import * as ScrollArea from "@radix-ui/react-scroll-area"; -import { useLocation } from "react-router-dom"; -import { Spinner } from "./ui/spinner"; -import { User, ChevronDown } from "lucide-react"; -import { Textarea } from "./ui/textarea"; -import logo from "../assets/tt_logo.svg"; -import { - Breadcrumb, - BreadcrumbEllipsis, - BreadcrumbItem, - BreadcrumbLink, - BreadcrumbList, - BreadcrumbPage, - BreadcrumbSeparator, -} from "./ui/breadcrumb"; -import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuItem, - DropdownMenuTrigger, -} from "./ui/dropdown-menu"; -import { fetchModels } from "../api/modelsDeployedApis"; -import ChatExamples from "./ChatExamples"; -import axios from "axios"; -import { - Select, - SelectContent, - SelectItem, - SelectTrigger, - SelectValue, -} from "./ui/select"; -import { useQuery } from "react-query"; -import { fetchCollections } from "@/src/pages/rag/"; - -interface InferenceRequest { - deploy_id: string; - text: string; - rag_context?: { documents: string[] }; -} - -interface RagDataSource { - id: string; - name: string; - metadata: Record; -} - -interface ChatMessage { - sender: "user" | "assistant"; - text: string; -} - -interface Model { - id: string; - name: string; -} - -const ChatComponent: React.FC = () => { - const location = useLocation(); - const [textInput, setTextInput] = useState(""); - - const [ragDatasource, setRagDatasource] = useState< - RagDataSource | undefined - >(); - - // Fetch collections - const { data: ragDataSources } = useQuery("collectionsList", { - queryFn: fetchCollections, - initialData: [], - }); - - const [chatHistory, setChatHistory] = useState([]); - const [modelID, setModelID] = useState(null); - const [modelName, setModelName] = useState(null); - const [isStreaming, setIsStreaming] = useState(false); - const viewportRef = useRef(null); - const bottomRef = useRef(null); - const [isScrollButtonVisible, setIsScrollButtonVisible] = useState(false); - const [modelsDeployed, setModelsDeployed] = useState([]); - - useEffect(() => { - if (location.state) { - setModelID(location.state.containerID); - setModelName(location.state.modelName); - } - - const loadModels = async () => { - try { - const models = await fetchModels(); - setModelsDeployed(models); - } catch (error) { - console.error("Error fetching models:", error); - } - }; - - loadModels(); - }, [location.state]); - - const scrollToBottom = () => { - if (viewportRef.current) { - viewportRef.current.scrollTo({ - top: viewportRef.current.scrollHeight, - behavior: "smooth", - }); - } - }; - - const handleScroll = () => { - if (viewportRef.current) { - const isAtBottom = - viewportRef.current.scrollHeight - viewportRef.current.scrollTop <= - viewportRef.current.clientHeight + 1; - setIsScrollButtonVisible(!isAtBottom); - } - }; - - const getRagContext = async (request: InferenceRequest) => { - const ragContext: { documents: string[] } = { - documents: [], - }; - - const response = await axios - .get(`/collections-api/${ragDatasource?.name}/query`, { - params: { query: request.text }, - }) - .catch((e) => { - console.error(`Error fetching RAG context ${e}`); - }); - - if (!response?.data) { - return ragContext; - } - - ragContext.documents = response.data.documents; - return ragContext; - }; - - const runInference = async (request: InferenceRequest) => { - try { - if (ragDatasource) { - request.rag_context = await getRagContext(request); - } - - setIsStreaming(true); - const response = await fetch(`/models-api/inference/`, { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify(request), - }); - - const reader = response.body?.getReader(); - - setChatHistory((prevHistory) => [ - ...prevHistory, - { sender: "user", text: textInput }, - ]); - setTextInput(""); - - let result = ""; - if (reader) { - let done = false; - while (!done) { - const { done: streamDone, value } = await reader.read(); - done = streamDone; - - if (value) { - const decoder = new TextDecoder(); - const chunk = decoder.decode(value); - result += chunk; - const cleanedResult = result.replace(/<\|endoftext\|>/g, ""); - setChatHistory((prevHistory) => { - const lastMessage = prevHistory[prevHistory.length - 1]; - if (lastMessage && lastMessage.sender === "assistant") { - const updatedHistory = [...prevHistory]; - updatedHistory[updatedHistory.length - 1] = { - ...lastMessage, - text: cleanedResult, - }; - return updatedHistory; - } else { - return [ - ...prevHistory, - { sender: "assistant", text: cleanedResult }, - ]; - } - }); - } - } - } - - setIsStreaming(false); - } catch (error) { - console.error("Error running inference:", error); - setIsStreaming(false); - } - }; - - const handleInference = () => { - if (textInput.trim() === "") return; - - const inferenceRequest: InferenceRequest = { - deploy_id: modelID!, - text: textInput, - }; - - if (textInput === "Tell me a fun fact.") { - setChatHistory((prevHistory) => [ - ...prevHistory, - { sender: "user", text: textInput }, - { sender: "assistant", text: "Did you know? Honey never spoils." }, - ]); - setTextInput(""); - scrollToBottom(); - return; - } - - runInference(inferenceRequest); - }; - - const RagContextSelector = ({ - collections, - onChange, - activeCollection, - }: { - collections: RagDataSource[]; - activeCollection?: RagDataSource; - onChange: (v: string) => void; - }) => ( -
-
Select RAG Datasource
- - -
- ); - - const handleKeyPress = (e: React.KeyboardEvent) => { - if (e.key === "Enter" && !e.shiftKey) { - e.preventDefault(); - handleInference(); - } - }; - - return ( -
- -
- - - - - Models Deployed - - - - / - - - - - - Toggle menu - - - {modelsDeployed.map((model) => ( - { - setModelID(model.id); - setModelName(model.name); - }} - > - {model.name} - - ))} - - - - - / - - - - {modelName} - - - - -
-
- { - const dataSource = ragDataSources.find((rds: RagDataSource) => { - return rds.name == v; - }); - if (dataSource) { - setRagDatasource(dataSource); - } - }} - activeCollection={ragDatasource} - /> - {chatHistory.length === 0 && ( - - )} - {chatHistory.length > 0 && ( -
- - - {chatHistory.map((message, index) => ( -
-
-
- {message.sender === "user" ? ( - - ) : ( - Tenstorrent Logo - )} -
-
-
- {message.text} -
-
- ))} -
- - - - - - {isScrollButtonVisible && ( - - )} -
- )} -
-