diff --git a/README.md b/README.md
index abef206..5dde0df 100644
--- a/README.md
+++ b/README.md
@@ -12,12 +12,13 @@
## 📝 Introduction
-Protypo simplifies the process of generating backend code using JSON schemas, allowing you to focus on business logic and reducing repetitive tasks. It can generate code for various languages using customizable templates, making it a versatile tool for API generation, code scaffolding, and more.
+The name Protypo originates from the Greek word πρότυπο (pronounced pro-tý-po), meaning 'model', 'template', or 'pattern'. Protypo is a powerful code generator that transforms entity definitions into fully functional code, allowing you to quickly scaffold entire backend systems, APIs, and more.
-Protypo was built to bring the speed and flexibility of low-code tools to Rust, with the extensibility and performance expected from a modern Rust-based tool.
+
+Built for speed and flexibility, Protypo brings modern code generation to Rust, combining the performance of a Rust-based tool with the convenience of customizable templates for various programming languages and architectures.
## Features
-- 🚀 Supports `Tera` (default) and `MiniJinja` template engines.
+- 🚀 Supports `MiniJinja` (default) and `Tera` template engines.
- 🛠️ Generates code based on JSON schemas for APIs, microservices, and more.
- 📦 Customizable generators for different frameworks and programming languages.
- 📂 Project structure designed for flexibility and scalability.
@@ -33,7 +34,7 @@ To install Protypo, follow the steps below:
2. Install Protypo via Cargo:
```bash
- cargo install --git https://github.com/dinosath
+ cargo install --git https://github.com/dinosath/protypo
```
#### 🚀 Usage
diff --git a/generators/ra-shadcn/Generator.yaml b/generators/ra-shadcn/Generator.yaml
new file mode 100644
index 0000000..fb40b96
--- /dev/null
+++ b/generators/ra-shadcn/Generator.yaml
@@ -0,0 +1,21 @@
+apiVersion: 0.0.1
+name: ra-shadcn
+version: 0.0.1
+description: Code generator for fronted using the react admin framework.
+keywords:
+ - react
+ - react-admin
+ - shadcn
+ - frontend
+dependencies:
+ - name: jsonschema-commons
+ version: 0.0.1
+ url: "file://../jsonschema-commons"
+ tags:
+ - jsonschema
+ - commons
+sources:
+ - https://github.com/dinosath/protypo
+maintainers:
+ - name: Konstantinos Athanasiou
+ email: dinosath0@gmail.com
\ No newline at end of file
diff --git a/generators/ra-shadcn/LICENSE b/generators/ra-shadcn/LICENSE
new file mode 100644
index 0000000..c309c3d
--- /dev/null
+++ b/generators/ra-shadcn/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2024 Konstantinos Athanasiou
+
+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.
diff --git a/generators/ra-shadcn/files/.gitignore b/generators/ra-shadcn/files/.gitignore
new file mode 100644
index 0000000..a547bf3
--- /dev/null
+++ b/generators/ra-shadcn/files/.gitignore
@@ -0,0 +1,24 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+lerna-debug.log*
+
+node_modules
+dist
+dist-ssr
+*.local
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+.DS_Store
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
diff --git a/generators/ra-shadcn/files/README.md b/generators/ra-shadcn/files/README.md
new file mode 100644
index 0000000..74872fd
--- /dev/null
+++ b/generators/ra-shadcn/files/README.md
@@ -0,0 +1,50 @@
+# React + TypeScript + Vite
+
+This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
+
+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
+
+## Expanding the ESLint configuration
+
+If you are developing a production application, we recommend updating the configuration to enable type aware lint rules:
+
+- Configure the top-level `parserOptions` property like this:
+
+```js
+export default tseslint.config({
+ languageOptions: {
+ // other options...
+ parserOptions: {
+ project: ['./tsconfig.node.json', './tsconfig.app.json'],
+ tsconfigRootDir: import.meta.dirname,
+ },
+ },
+})
+```
+
+- Replace `tseslint.configs.recommended` to `tseslint.configs.recommendedTypeChecked` or `tseslint.configs.strictTypeChecked`
+- Optionally add `...tseslint.configs.stylisticTypeChecked`
+- Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and update the config:
+
+```js
+// eslint.config.js
+import react from 'eslint-plugin-react'
+
+export default tseslint.config({
+ // Set the react version
+ settings: { react: { version: '18.3' } },
+ plugins: {
+ // Add the react plugin
+ react,
+ },
+ rules: {
+ // other rules...
+ // Enable its recommended rules
+ ...react.configs.recommended.rules,
+ ...react.configs['jsx-runtime'].rules,
+ },
+})
+```
diff --git a/generators/ra-shadcn/files/eslint.config.js b/generators/ra-shadcn/files/eslint.config.js
new file mode 100644
index 0000000..092408a
--- /dev/null
+++ b/generators/ra-shadcn/files/eslint.config.js
@@ -0,0 +1,28 @@
+import js from '@eslint/js'
+import globals from 'globals'
+import reactHooks from 'eslint-plugin-react-hooks'
+import reactRefresh from 'eslint-plugin-react-refresh'
+import tseslint from 'typescript-eslint'
+
+export default tseslint.config(
+ { ignores: ['dist'] },
+ {
+ extends: [js.configs.recommended, ...tseslint.configs.recommended],
+ files: ['**/*.{ts,tsx}'],
+ languageOptions: {
+ ecmaVersion: 2020,
+ globals: globals.browser,
+ },
+ plugins: {
+ 'react-hooks': reactHooks,
+ 'react-refresh': reactRefresh,
+ },
+ rules: {
+ ...reactHooks.configs.recommended.rules,
+ 'react-refresh/only-export-components': [
+ 'warn',
+ { allowConstantExport: true },
+ ],
+ },
+ },
+)
diff --git a/generators/ra-shadcn/files/index.html b/generators/ra-shadcn/files/index.html
new file mode 100644
index 0000000..e4b78ea
--- /dev/null
+++ b/generators/ra-shadcn/files/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ Vite + React + TS
+
+
+
+
+
+
diff --git a/generators/ra-shadcn/files/package.json b/generators/ra-shadcn/files/package.json
new file mode 100644
index 0000000..40280e2
--- /dev/null
+++ b/generators/ra-shadcn/files/package.json
@@ -0,0 +1,29 @@
+{
+ "name": "vite-project",
+ "private": true,
+ "version": "0.0.0",
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "tsc -b && vite build",
+ "lint": "eslint .",
+ "preview": "vite preview"
+ },
+ "dependencies": {
+ "react": "^19.0.0",
+ "react-dom": "^19.0.0"
+ },
+ "devDependencies": {
+ "@eslint/js": "^9.17.0",
+ "@types/react": "^19.0.8",
+ "@types/react-dom": "^19.0.3",
+ "@vitejs/plugin-react-swc": "^3.5.0",
+ "eslint": "^9.17.0",
+ "eslint-plugin-react-hooks": "^5.0.0",
+ "eslint-plugin-react-refresh": "^0.4.16",
+ "globals": "^15.14.0",
+ "typescript": "~5.7.3",
+ "typescript-eslint": "^8.18.2",
+ "vite": "^6.0.5"
+ }
+}
diff --git a/generators/ra-shadcn/files/pnpm-lock.yaml b/generators/ra-shadcn/files/pnpm-lock.yaml
new file mode 100644
index 0000000..8553779
--- /dev/null
+++ b/generators/ra-shadcn/files/pnpm-lock.yaml
@@ -0,0 +1,1741 @@
+lockfileVersion: '9.0'
+
+settings:
+ autoInstallPeers: true
+ excludeLinksFromLockfile: false
+
+importers:
+
+ .:
+ dependencies:
+ react:
+ specifier: ^19.0.0
+ version: 19.0.0
+ react-dom:
+ specifier: ^19.0.0
+ version: 19.0.0(react@19.0.0)
+ devDependencies:
+ '@eslint/js':
+ specifier: ^9.17.0
+ version: 9.19.0
+ '@types/react':
+ specifier: ^19.0.8
+ version: 19.0.8
+ '@types/react-dom':
+ specifier: ^19.0.3
+ version: 19.0.3(@types/react@19.0.8)
+ '@vitejs/plugin-react-swc':
+ specifier: ^3.5.0
+ version: 3.7.2(vite@6.0.11)
+ eslint:
+ specifier: ^9.17.0
+ version: 9.19.0
+ eslint-plugin-react-hooks:
+ specifier: ^5.0.0
+ version: 5.1.0(eslint@9.19.0)
+ eslint-plugin-react-refresh:
+ specifier: ^0.4.16
+ version: 0.4.18(eslint@9.19.0)
+ globals:
+ specifier: ^15.14.0
+ version: 15.14.0
+ typescript:
+ specifier: ~5.7.3
+ version: 5.7.3
+ typescript-eslint:
+ specifier: ^8.18.2
+ version: 8.22.0(eslint@9.19.0)(typescript@5.7.3)
+ vite:
+ specifier: ^6.0.5
+ version: 6.0.11
+
+packages:
+
+ '@esbuild/aix-ppc64@0.24.2':
+ resolution: {integrity: sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==}
+ engines: {node: '>=18'}
+ cpu: [ppc64]
+ os: [aix]
+
+ '@esbuild/android-arm64@0.24.2':
+ resolution: {integrity: sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [android]
+
+ '@esbuild/android-arm@0.24.2':
+ resolution: {integrity: sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==}
+ engines: {node: '>=18'}
+ cpu: [arm]
+ os: [android]
+
+ '@esbuild/android-x64@0.24.2':
+ resolution: {integrity: sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [android]
+
+ '@esbuild/darwin-arm64@0.24.2':
+ resolution: {integrity: sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@esbuild/darwin-x64@0.24.2':
+ resolution: {integrity: sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@esbuild/freebsd-arm64@0.24.2':
+ resolution: {integrity: sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [freebsd]
+
+ '@esbuild/freebsd-x64@0.24.2':
+ resolution: {integrity: sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@esbuild/linux-arm64@0.24.2':
+ resolution: {integrity: sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@esbuild/linux-arm@0.24.2':
+ resolution: {integrity: sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==}
+ engines: {node: '>=18'}
+ cpu: [arm]
+ os: [linux]
+
+ '@esbuild/linux-ia32@0.24.2':
+ resolution: {integrity: sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==}
+ engines: {node: '>=18'}
+ cpu: [ia32]
+ os: [linux]
+
+ '@esbuild/linux-loong64@0.24.2':
+ resolution: {integrity: sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==}
+ engines: {node: '>=18'}
+ cpu: [loong64]
+ os: [linux]
+
+ '@esbuild/linux-mips64el@0.24.2':
+ resolution: {integrity: sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==}
+ engines: {node: '>=18'}
+ cpu: [mips64el]
+ os: [linux]
+
+ '@esbuild/linux-ppc64@0.24.2':
+ resolution: {integrity: sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==}
+ engines: {node: '>=18'}
+ cpu: [ppc64]
+ os: [linux]
+
+ '@esbuild/linux-riscv64@0.24.2':
+ resolution: {integrity: sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==}
+ engines: {node: '>=18'}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@esbuild/linux-s390x@0.24.2':
+ resolution: {integrity: sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==}
+ engines: {node: '>=18'}
+ cpu: [s390x]
+ os: [linux]
+
+ '@esbuild/linux-x64@0.24.2':
+ resolution: {integrity: sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [linux]
+
+ '@esbuild/netbsd-arm64@0.24.2':
+ resolution: {integrity: sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [netbsd]
+
+ '@esbuild/netbsd-x64@0.24.2':
+ resolution: {integrity: sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [netbsd]
+
+ '@esbuild/openbsd-arm64@0.24.2':
+ resolution: {integrity: sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [openbsd]
+
+ '@esbuild/openbsd-x64@0.24.2':
+ resolution: {integrity: sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [openbsd]
+
+ '@esbuild/sunos-x64@0.24.2':
+ resolution: {integrity: sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [sunos]
+
+ '@esbuild/win32-arm64@0.24.2':
+ resolution: {integrity: sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@esbuild/win32-ia32@0.24.2':
+ resolution: {integrity: sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==}
+ engines: {node: '>=18'}
+ cpu: [ia32]
+ os: [win32]
+
+ '@esbuild/win32-x64@0.24.2':
+ resolution: {integrity: sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [win32]
+
+ '@eslint-community/eslint-utils@4.4.1':
+ resolution: {integrity: sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+ peerDependencies:
+ eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
+
+ '@eslint-community/regexpp@4.12.1':
+ resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==}
+ engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
+
+ '@eslint/config-array@0.19.1':
+ resolution: {integrity: sha512-fo6Mtm5mWyKjA/Chy1BYTdn5mGJoDNjC7C64ug20ADsRDGrA85bN3uK3MaKbeRkRuuIEAR5N33Jr1pbm411/PA==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ '@eslint/core@0.10.0':
+ resolution: {integrity: sha512-gFHJ+xBOo4G3WRlR1e/3G8A6/KZAH6zcE/hkLRCZTi/B9avAG365QhFA8uOGzTMqgTghpn7/fSnscW++dpMSAw==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ '@eslint/eslintrc@3.2.0':
+ resolution: {integrity: sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ '@eslint/js@9.19.0':
+ resolution: {integrity: sha512-rbq9/g38qjfqFLOVPvwjIvFFdNziEC5S65jmjPw5r6A//QH+W91akh9irMwjDN8zKUTak6W9EsAv4m/7Wnw0UQ==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ '@eslint/object-schema@2.1.5':
+ resolution: {integrity: sha512-o0bhxnL89h5Bae5T318nFoFzGy+YE5i/gGkoPAgkmTVdRKTiv3p8JHevPiPaMwoloKfEiiaHlawCqaZMqRm+XQ==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ '@eslint/plugin-kit@0.2.5':
+ resolution: {integrity: sha512-lB05FkqEdUg2AA0xEbUz0SnkXT1LcCTa438W4IWTUh4hdOnVbQyOJ81OrDXsJk/LSiJHubgGEFoR5EHq1NsH1A==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ '@humanfs/core@0.19.1':
+ resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==}
+ engines: {node: '>=18.18.0'}
+
+ '@humanfs/node@0.16.6':
+ resolution: {integrity: sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==}
+ engines: {node: '>=18.18.0'}
+
+ '@humanwhocodes/module-importer@1.0.1':
+ resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==}
+ engines: {node: '>=12.22'}
+
+ '@humanwhocodes/retry@0.3.1':
+ resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==}
+ engines: {node: '>=18.18'}
+
+ '@humanwhocodes/retry@0.4.1':
+ resolution: {integrity: sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==}
+ engines: {node: '>=18.18'}
+
+ '@nodelib/fs.scandir@2.1.5':
+ resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
+ engines: {node: '>= 8'}
+
+ '@nodelib/fs.stat@2.0.5':
+ resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==}
+ engines: {node: '>= 8'}
+
+ '@nodelib/fs.walk@1.2.8':
+ resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
+ engines: {node: '>= 8'}
+
+ '@rollup/rollup-android-arm-eabi@4.32.0':
+ resolution: {integrity: sha512-G2fUQQANtBPsNwiVFg4zKiPQyjVKZCUdQUol53R8E71J7AsheRMV/Yv/nB8giOcOVqP7//eB5xPqieBYZe9bGg==}
+ cpu: [arm]
+ os: [android]
+
+ '@rollup/rollup-android-arm64@4.32.0':
+ resolution: {integrity: sha512-qhFwQ+ljoymC+j5lXRv8DlaJYY/+8vyvYmVx074zrLsu5ZGWYsJNLjPPVJJjhZQpyAKUGPydOq9hRLLNvh1s3A==}
+ cpu: [arm64]
+ os: [android]
+
+ '@rollup/rollup-darwin-arm64@4.32.0':
+ resolution: {integrity: sha512-44n/X3lAlWsEY6vF8CzgCx+LQaoqWGN7TzUfbJDiTIOjJm4+L2Yq+r5a8ytQRGyPqgJDs3Rgyo8eVL7n9iW6AQ==}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@rollup/rollup-darwin-x64@4.32.0':
+ resolution: {integrity: sha512-F9ct0+ZX5Np6+ZDztxiGCIvlCaW87HBdHcozUfsHnj1WCUTBUubAoanhHUfnUHZABlElyRikI0mgcw/qdEm2VQ==}
+ cpu: [x64]
+ os: [darwin]
+
+ '@rollup/rollup-freebsd-arm64@4.32.0':
+ resolution: {integrity: sha512-JpsGxLBB2EFXBsTLHfkZDsXSpSmKD3VxXCgBQtlPcuAqB8TlqtLcbeMhxXQkCDv1avgwNjF8uEIbq5p+Cee0PA==}
+ cpu: [arm64]
+ os: [freebsd]
+
+ '@rollup/rollup-freebsd-x64@4.32.0':
+ resolution: {integrity: sha512-wegiyBT6rawdpvnD9lmbOpx5Sph+yVZKHbhnSP9MqUEDX08G4UzMU+D87jrazGE7lRSyTRs6NEYHtzfkJ3FjjQ==}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@rollup/rollup-linux-arm-gnueabihf@4.32.0':
+ resolution: {integrity: sha512-3pA7xecItbgOs1A5H58dDvOUEboG5UfpTq3WzAdF54acBbUM+olDJAPkgj1GRJ4ZqE12DZ9/hNS2QZk166v92A==}
+ cpu: [arm]
+ os: [linux]
+
+ '@rollup/rollup-linux-arm-musleabihf@4.32.0':
+ resolution: {integrity: sha512-Y7XUZEVISGyge51QbYyYAEHwpGgmRrAxQXO3siyYo2kmaj72USSG8LtlQQgAtlGfxYiOwu+2BdbPjzEpcOpRmQ==}
+ cpu: [arm]
+ os: [linux]
+
+ '@rollup/rollup-linux-arm64-gnu@4.32.0':
+ resolution: {integrity: sha512-r7/OTF5MqeBrZo5omPXcTnjvv1GsrdH8a8RerARvDFiDwFpDVDnJyByYM/nX+mvks8XXsgPUxkwe/ltaX2VH7w==}
+ cpu: [arm64]
+ os: [linux]
+
+ '@rollup/rollup-linux-arm64-musl@4.32.0':
+ resolution: {integrity: sha512-HJbifC9vex9NqnlodV2BHVFNuzKL5OnsV2dvTw6e1dpZKkNjPG6WUq+nhEYV6Hv2Bv++BXkwcyoGlXnPrjAKXw==}
+ cpu: [arm64]
+ os: [linux]
+
+ '@rollup/rollup-linux-loongarch64-gnu@4.32.0':
+ resolution: {integrity: sha512-VAEzZTD63YglFlWwRj3taofmkV1V3xhebDXffon7msNz4b14xKsz7utO6F8F4cqt8K/ktTl9rm88yryvDpsfOw==}
+ cpu: [loong64]
+ os: [linux]
+
+ '@rollup/rollup-linux-powerpc64le-gnu@4.32.0':
+ resolution: {integrity: sha512-Sts5DST1jXAc9YH/iik1C9QRsLcCoOScf3dfbY5i4kH9RJpKxiTBXqm7qU5O6zTXBTEZry69bGszr3SMgYmMcQ==}
+ cpu: [ppc64]
+ os: [linux]
+
+ '@rollup/rollup-linux-riscv64-gnu@4.32.0':
+ resolution: {integrity: sha512-qhlXeV9AqxIyY9/R1h1hBD6eMvQCO34ZmdYvry/K+/MBs6d1nRFLm6BOiITLVI+nFAAB9kUB6sdJRKyVHXnqZw==}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@rollup/rollup-linux-s390x-gnu@4.32.0':
+ resolution: {integrity: sha512-8ZGN7ExnV0qjXa155Rsfi6H8M4iBBwNLBM9lcVS+4NcSzOFaNqmt7djlox8pN1lWrRPMRRQ8NeDlozIGx3Omsw==}
+ cpu: [s390x]
+ os: [linux]
+
+ '@rollup/rollup-linux-x64-gnu@4.32.0':
+ resolution: {integrity: sha512-VDzNHtLLI5s7xd/VubyS10mq6TxvZBp+4NRWoW+Hi3tgV05RtVm4qK99+dClwTN1McA6PHwob6DEJ6PlXbY83A==}
+ cpu: [x64]
+ os: [linux]
+
+ '@rollup/rollup-linux-x64-musl@4.32.0':
+ resolution: {integrity: sha512-qcb9qYDlkxz9DxJo7SDhWxTWV1gFuwznjbTiov289pASxlfGbaOD54mgbs9+z94VwrXtKTu+2RqwlSTbiOqxGg==}
+ cpu: [x64]
+ os: [linux]
+
+ '@rollup/rollup-win32-arm64-msvc@4.32.0':
+ resolution: {integrity: sha512-pFDdotFDMXW2AXVbfdUEfidPAk/OtwE/Hd4eYMTNVVaCQ6Yl8et0meDaKNL63L44Haxv4UExpv9ydSf3aSayDg==}
+ cpu: [arm64]
+ os: [win32]
+
+ '@rollup/rollup-win32-ia32-msvc@4.32.0':
+ resolution: {integrity: sha512-/TG7WfrCAjeRNDvI4+0AAMoHxea/USWhAzf9PVDFHbcqrQ7hMMKp4jZIy4VEjk72AAfN5k4TiSMRXRKf/0akSw==}
+ cpu: [ia32]
+ os: [win32]
+
+ '@rollup/rollup-win32-x64-msvc@4.32.0':
+ resolution: {integrity: sha512-5hqO5S3PTEO2E5VjCePxv40gIgyS2KvO7E7/vvC/NbIW4SIRamkMr1hqj+5Y67fbBWv/bQLB6KelBQmXlyCjWA==}
+ cpu: [x64]
+ os: [win32]
+
+ '@swc/core-darwin-arm64@1.10.11':
+ resolution: {integrity: sha512-ZpgEaNcx2e5D+Pd0yZGVbpSrEDOEubn7r2JXoNBf0O85lPjUm3HDzGRfLlV/MwxRPAkwm93eLP4l7gYnc50l3g==}
+ engines: {node: '>=10'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@swc/core-darwin-x64@1.10.11':
+ resolution: {integrity: sha512-szObinnq2o7spXMDU5pdunmUeLrfV67Q77rV+DyojAiGJI1RSbEQotLOk+ONOLpoapwGUxOijFG4IuX1xiwQ2g==}
+ engines: {node: '>=10'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@swc/core-linux-arm-gnueabihf@1.10.11':
+ resolution: {integrity: sha512-tVE8aXQwd8JUB9fOGLawFJa76nrpvp3dvErjozMmWSKWqtoeO7HV83aOrVtc8G66cj4Vq7FjTE9pOJeV1FbKRw==}
+ engines: {node: '>=10'}
+ cpu: [arm]
+ os: [linux]
+
+ '@swc/core-linux-arm64-gnu@1.10.11':
+ resolution: {integrity: sha512-geFkENU5GMEKO7FqHOaw9HVlpQEW10nICoM6ubFc0hXBv8dwRXU4vQbh9s/isLSFRftw1m4jEEWixAnXSw8bxQ==}
+ engines: {node: '>=10'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@swc/core-linux-arm64-musl@1.10.11':
+ resolution: {integrity: sha512-2mMscXe/ivq8c4tO3eQSbQDFBvagMJGlalXCspn0DgDImLYTEnt/8KHMUMGVfh0gMJTZ9q4FlGLo7mlnbx99MQ==}
+ engines: {node: '>=10'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@swc/core-linux-x64-gnu@1.10.11':
+ resolution: {integrity: sha512-eu2apgDbC4xwsigpl6LS+iyw6a3mL6kB4I+6PZMbFF2nIb1Dh7RGnu70Ai6mMn1o80fTmRSKsCT3CKMfVdeNFg==}
+ engines: {node: '>=10'}
+ cpu: [x64]
+ os: [linux]
+
+ '@swc/core-linux-x64-musl@1.10.11':
+ resolution: {integrity: sha512-0n+wPWpDigwqRay4IL2JIvAqSKCXv6nKxPig9M7+epAlEQlqX+8Oq/Ap3yHtuhjNPb7HmnqNJLCXT1Wx+BZo0w==}
+ engines: {node: '>=10'}
+ cpu: [x64]
+ os: [linux]
+
+ '@swc/core-win32-arm64-msvc@1.10.11':
+ resolution: {integrity: sha512-7+bMSIoqcbXKosIVd314YjckDRPneA4OpG1cb3/GrkQTEDXmWT3pFBBlJf82hzJfw7b6lfv6rDVEFBX7/PJoLA==}
+ engines: {node: '>=10'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@swc/core-win32-ia32-msvc@1.10.11':
+ resolution: {integrity: sha512-6hkLl4+3KjP/OFTryWxpW7YFN+w4R689TSPwiII4fFgsFNupyEmLWWakKfkGgV2JVA59L4Oi02elHy/O1sbgtw==}
+ engines: {node: '>=10'}
+ cpu: [ia32]
+ os: [win32]
+
+ '@swc/core-win32-x64-msvc@1.10.11':
+ resolution: {integrity: sha512-kKNE2BGu/La2k2WFHovenqZvGQAHRIU+rd2/6a7D6EiQ6EyimtbhUqjCCZ+N1f5fIAnvM+sMdLiQJq4jdd/oOQ==}
+ engines: {node: '>=10'}
+ cpu: [x64]
+ os: [win32]
+
+ '@swc/core@1.10.11':
+ resolution: {integrity: sha512-3zGU5y3S20cAwot9ZcsxVFNsSVaptG+dKdmAxORSE3EX7ixe1Xn5kUwLlgIsM4qrwTUWCJDLNhRS+2HLFivcDg==}
+ engines: {node: '>=10'}
+ peerDependencies:
+ '@swc/helpers': '*'
+ peerDependenciesMeta:
+ '@swc/helpers':
+ optional: true
+
+ '@swc/counter@0.1.3':
+ resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==}
+
+ '@swc/types@0.1.17':
+ resolution: {integrity: sha512-V5gRru+aD8YVyCOMAjMpWR1Ui577DD5KSJsHP8RAxopAH22jFz6GZd/qxqjO6MJHQhcsjvjOFXyDhyLQUnMveQ==}
+
+ '@types/estree@1.0.6':
+ resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==}
+
+ '@types/json-schema@7.0.15':
+ resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
+
+ '@types/react-dom@19.0.3':
+ resolution: {integrity: sha512-0Knk+HJiMP/qOZgMyNFamlIjw9OFCsyC2ZbigmEEyXXixgre6IQpm/4V+r3qH4GC1JPvRJKInw+on2rV6YZLeA==}
+ peerDependencies:
+ '@types/react': ^19.0.0
+
+ '@types/react@19.0.8':
+ resolution: {integrity: sha512-9P/o1IGdfmQxrujGbIMDyYaaCykhLKc0NGCtYcECNUr9UAaDe4gwvV9bR6tvd5Br1SG0j+PBpbKr2UYY8CwqSw==}
+
+ '@typescript-eslint/eslint-plugin@8.22.0':
+ resolution: {integrity: sha512-4Uta6REnz/xEJMvwf72wdUnC3rr4jAQf5jnTkeRQ9b6soxLxhDEbS/pfMPoJLDfFPNVRdryqWUIV/2GZzDJFZw==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ peerDependencies:
+ '@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0
+ eslint: ^8.57.0 || ^9.0.0
+ typescript: '>=4.8.4 <5.8.0'
+
+ '@typescript-eslint/parser@8.22.0':
+ resolution: {integrity: sha512-MqtmbdNEdoNxTPzpWiWnqNac54h8JDAmkWtJExBVVnSrSmi9z+sZUt0LfKqk9rjqmKOIeRhO4fHHJ1nQIjduIQ==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ peerDependencies:
+ eslint: ^8.57.0 || ^9.0.0
+ typescript: '>=4.8.4 <5.8.0'
+
+ '@typescript-eslint/scope-manager@8.22.0':
+ resolution: {integrity: sha512-/lwVV0UYgkj7wPSw0o8URy6YI64QmcOdwHuGuxWIYznO6d45ER0wXUbksr9pYdViAofpUCNJx/tAzNukgvaaiQ==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ '@typescript-eslint/type-utils@8.22.0':
+ resolution: {integrity: sha512-NzE3aB62fDEaGjaAYZE4LH7I1MUwHooQ98Byq0G0y3kkibPJQIXVUspzlFOmOfHhiDLwKzMlWxaNv+/qcZurJA==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ peerDependencies:
+ eslint: ^8.57.0 || ^9.0.0
+ typescript: '>=4.8.4 <5.8.0'
+
+ '@typescript-eslint/types@8.22.0':
+ resolution: {integrity: sha512-0S4M4baNzp612zwpD4YOieP3VowOARgK2EkN/GBn95hpyF8E2fbMT55sRHWBq+Huaqk3b3XK+rxxlM8sPgGM6A==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ '@typescript-eslint/typescript-estree@8.22.0':
+ resolution: {integrity: sha512-SJX99NAS2ugGOzpyhMza/tX+zDwjvwAtQFLsBo3GQxiGcvaKlqGBkmZ+Y1IdiSi9h4Q0Lr5ey+Cp9CGWNY/F/w==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ peerDependencies:
+ typescript: '>=4.8.4 <5.8.0'
+
+ '@typescript-eslint/utils@8.22.0':
+ resolution: {integrity: sha512-T8oc1MbF8L+Bk2msAvCUzjxVB2Z2f+vXYfcucE2wOmYs7ZUwco5Ep0fYZw8quNwOiw9K8GYVL+Kgc2pETNTLOg==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ peerDependencies:
+ eslint: ^8.57.0 || ^9.0.0
+ typescript: '>=4.8.4 <5.8.0'
+
+ '@typescript-eslint/visitor-keys@8.22.0':
+ resolution: {integrity: sha512-AWpYAXnUgvLNabGTy3uBylkgZoosva/miNd1I8Bz3SjotmQPbVqhO4Cczo8AsZ44XVErEBPr/CRSgaj8sG7g0w==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ '@vitejs/plugin-react-swc@3.7.2':
+ resolution: {integrity: sha512-y0byko2b2tSVVf5Gpng1eEhX1OvPC7x8yns1Fx8jDzlJp4LS6CMkCPfLw47cjyoMrshQDoQw4qcgjsU9VvlCew==}
+ peerDependencies:
+ vite: ^4 || ^5 || ^6
+
+ acorn-jsx@5.3.2:
+ resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
+ peerDependencies:
+ acorn: ^6.0.0 || ^7.0.0 || ^8.0.0
+
+ acorn@8.14.0:
+ resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==}
+ engines: {node: '>=0.4.0'}
+ hasBin: true
+
+ ajv@6.12.6:
+ resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
+
+ ansi-styles@4.3.0:
+ resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
+ engines: {node: '>=8'}
+
+ argparse@2.0.1:
+ resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
+
+ balanced-match@1.0.2:
+ resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
+
+ brace-expansion@1.1.11:
+ resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==}
+
+ brace-expansion@2.0.1:
+ resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==}
+
+ braces@3.0.3:
+ resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
+ engines: {node: '>=8'}
+
+ callsites@3.1.0:
+ resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
+ engines: {node: '>=6'}
+
+ chalk@4.1.2:
+ resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
+ engines: {node: '>=10'}
+
+ color-convert@2.0.1:
+ resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
+ engines: {node: '>=7.0.0'}
+
+ color-name@1.1.4:
+ resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
+
+ concat-map@0.0.1:
+ resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
+
+ cross-spawn@7.0.6:
+ resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
+ engines: {node: '>= 8'}
+
+ csstype@3.1.3:
+ resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
+
+ debug@4.4.0:
+ resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==}
+ engines: {node: '>=6.0'}
+ peerDependencies:
+ supports-color: '*'
+ peerDependenciesMeta:
+ supports-color:
+ optional: true
+
+ deep-is@0.1.4:
+ resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
+
+ esbuild@0.24.2:
+ resolution: {integrity: sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==}
+ engines: {node: '>=18'}
+ hasBin: true
+
+ escape-string-regexp@4.0.0:
+ resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
+ engines: {node: '>=10'}
+
+ eslint-plugin-react-hooks@5.1.0:
+ resolution: {integrity: sha512-mpJRtPgHN2tNAvZ35AMfqeB3Xqeo273QxrHJsbBEPWODRM4r0yB6jfoROqKEYrOn27UtRPpcpHc2UqyBSuUNTw==}
+ engines: {node: '>=10'}
+ peerDependencies:
+ eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0
+
+ eslint-plugin-react-refresh@0.4.18:
+ resolution: {integrity: sha512-IRGEoFn3OKalm3hjfolEWGqoF/jPqeEYFp+C8B0WMzwGwBMvlRDQd06kghDhF0C61uJ6WfSDhEZE/sAQjduKgw==}
+ peerDependencies:
+ eslint: '>=8.40'
+
+ eslint-scope@8.2.0:
+ resolution: {integrity: sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ eslint-visitor-keys@3.4.3:
+ resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+
+ eslint-visitor-keys@4.2.0:
+ resolution: {integrity: sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ eslint@9.19.0:
+ resolution: {integrity: sha512-ug92j0LepKlbbEv6hD911THhoRHmbdXt2gX+VDABAW/Ir7D3nqKdv5Pf5vtlyY6HQMTEP2skXY43ueqTCWssEA==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ hasBin: true
+ peerDependencies:
+ jiti: '*'
+ peerDependenciesMeta:
+ jiti:
+ optional: true
+
+ espree@10.3.0:
+ resolution: {integrity: sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+
+ esquery@1.6.0:
+ resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==}
+ engines: {node: '>=0.10'}
+
+ esrecurse@4.3.0:
+ resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==}
+ engines: {node: '>=4.0'}
+
+ estraverse@5.3.0:
+ resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==}
+ engines: {node: '>=4.0'}
+
+ esutils@2.0.3:
+ resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
+ engines: {node: '>=0.10.0'}
+
+ fast-deep-equal@3.1.3:
+ resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
+
+ fast-glob@3.3.3:
+ resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==}
+ engines: {node: '>=8.6.0'}
+
+ fast-json-stable-stringify@2.1.0:
+ resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==}
+
+ fast-levenshtein@2.0.6:
+ resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==}
+
+ fastq@1.18.0:
+ resolution: {integrity: sha512-QKHXPW0hD8g4UET03SdOdunzSouc9N4AuHdsX8XNcTsuz+yYFILVNIX4l9yHABMhiEI9Db0JTTIpu0wB+Y1QQw==}
+
+ file-entry-cache@8.0.0:
+ resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==}
+ engines: {node: '>=16.0.0'}
+
+ fill-range@7.1.1:
+ resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
+ engines: {node: '>=8'}
+
+ find-up@5.0.0:
+ resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==}
+ engines: {node: '>=10'}
+
+ flat-cache@4.0.1:
+ resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==}
+ engines: {node: '>=16'}
+
+ flatted@3.3.2:
+ resolution: {integrity: sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==}
+
+ fsevents@2.3.3:
+ resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
+ engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
+ os: [darwin]
+
+ glob-parent@5.1.2:
+ resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
+ engines: {node: '>= 6'}
+
+ glob-parent@6.0.2:
+ resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==}
+ engines: {node: '>=10.13.0'}
+
+ globals@14.0.0:
+ resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==}
+ engines: {node: '>=18'}
+
+ globals@15.14.0:
+ resolution: {integrity: sha512-OkToC372DtlQeje9/zHIo5CT8lRP/FUgEOKBEhU4e0abL7J7CD24fD9ohiLN5hagG/kWCYj4K5oaxxtj2Z0Dig==}
+ engines: {node: '>=18'}
+
+ graphemer@1.4.0:
+ resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==}
+
+ has-flag@4.0.0:
+ resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
+ engines: {node: '>=8'}
+
+ ignore@5.3.2:
+ resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==}
+ engines: {node: '>= 4'}
+
+ import-fresh@3.3.0:
+ resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==}
+ engines: {node: '>=6'}
+
+ imurmurhash@0.1.4:
+ resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
+ engines: {node: '>=0.8.19'}
+
+ is-extglob@2.1.1:
+ resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
+ engines: {node: '>=0.10.0'}
+
+ is-glob@4.0.3:
+ resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
+ engines: {node: '>=0.10.0'}
+
+ is-number@7.0.0:
+ resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
+ engines: {node: '>=0.12.0'}
+
+ isexe@2.0.0:
+ resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
+
+ js-yaml@4.1.0:
+ resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==}
+ hasBin: true
+
+ json-buffer@3.0.1:
+ resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==}
+
+ json-schema-traverse@0.4.1:
+ resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
+
+ json-stable-stringify-without-jsonify@1.0.1:
+ resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
+
+ keyv@4.5.4:
+ resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
+
+ levn@0.4.1:
+ resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
+ engines: {node: '>= 0.8.0'}
+
+ locate-path@6.0.0:
+ resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
+ engines: {node: '>=10'}
+
+ lodash.merge@4.6.2:
+ resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
+
+ merge2@1.4.1:
+ resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
+ engines: {node: '>= 8'}
+
+ micromatch@4.0.8:
+ resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==}
+ engines: {node: '>=8.6'}
+
+ minimatch@3.1.2:
+ resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
+
+ minimatch@9.0.5:
+ resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==}
+ engines: {node: '>=16 || 14 >=14.17'}
+
+ ms@2.1.3:
+ resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
+
+ nanoid@3.3.8:
+ resolution: {integrity: sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==}
+ engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
+ hasBin: true
+
+ natural-compare@1.4.0:
+ resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
+
+ optionator@0.9.4:
+ resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==}
+ engines: {node: '>= 0.8.0'}
+
+ p-limit@3.1.0:
+ resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
+ engines: {node: '>=10'}
+
+ p-locate@5.0.0:
+ resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
+ engines: {node: '>=10'}
+
+ parent-module@1.0.1:
+ resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
+ engines: {node: '>=6'}
+
+ path-exists@4.0.0:
+ resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
+ engines: {node: '>=8'}
+
+ path-key@3.1.1:
+ resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
+ engines: {node: '>=8'}
+
+ picocolors@1.1.1:
+ resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
+
+ picomatch@2.3.1:
+ resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
+ engines: {node: '>=8.6'}
+
+ postcss@8.5.1:
+ resolution: {integrity: sha512-6oz2beyjc5VMn/KV1pPw8fliQkhBXrVn1Z3TVyqZxU8kZpzEKhBdmCFqI6ZbmGtamQvQGuU1sgPTk8ZrXDD7jQ==}
+ engines: {node: ^10 || ^12 || >=14}
+
+ prelude-ls@1.2.1:
+ resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
+ engines: {node: '>= 0.8.0'}
+
+ punycode@2.3.1:
+ resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
+ engines: {node: '>=6'}
+
+ queue-microtask@1.2.3:
+ resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
+
+ react-dom@19.0.0:
+ resolution: {integrity: sha512-4GV5sHFG0e/0AD4X+ySy6UJd3jVl1iNsNHdpad0qhABJ11twS3TTBnseqsKurKcsNqCEFeGL3uLpVChpIO3QfQ==}
+ peerDependencies:
+ react: ^19.0.0
+
+ react@19.0.0:
+ resolution: {integrity: sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==}
+ engines: {node: '>=0.10.0'}
+
+ resolve-from@4.0.0:
+ resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
+ engines: {node: '>=4'}
+
+ reusify@1.0.4:
+ resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==}
+ engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
+
+ rollup@4.32.0:
+ resolution: {integrity: sha512-JmrhfQR31Q4AuNBjjAX4s+a/Pu/Q8Q9iwjWBsjRH1q52SPFE2NqRMK6fUZKKnvKO6id+h7JIRf0oYsph53eATg==}
+ engines: {node: '>=18.0.0', npm: '>=8.0.0'}
+ hasBin: true
+
+ run-parallel@1.2.0:
+ resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
+
+ scheduler@0.25.0:
+ resolution: {integrity: sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA==}
+
+ semver@7.6.3:
+ resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==}
+ engines: {node: '>=10'}
+ hasBin: true
+
+ shebang-command@2.0.0:
+ resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
+ engines: {node: '>=8'}
+
+ shebang-regex@3.0.0:
+ resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
+ engines: {node: '>=8'}
+
+ source-map-js@1.2.1:
+ resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
+ engines: {node: '>=0.10.0'}
+
+ strip-json-comments@3.1.1:
+ resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
+ engines: {node: '>=8'}
+
+ supports-color@7.2.0:
+ resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
+ engines: {node: '>=8'}
+
+ to-regex-range@5.0.1:
+ resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
+ engines: {node: '>=8.0'}
+
+ ts-api-utils@2.0.0:
+ resolution: {integrity: sha512-xCt/TOAc+EOHS1XPnijD3/yzpH6qg2xppZO1YDqGoVsNXfQfzHpOdNuXwrwOU8u4ITXJyDCTyt8w5g1sZv9ynQ==}
+ engines: {node: '>=18.12'}
+ peerDependencies:
+ typescript: '>=4.8.4'
+
+ type-check@0.4.0:
+ resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
+ engines: {node: '>= 0.8.0'}
+
+ typescript-eslint@8.22.0:
+ resolution: {integrity: sha512-Y2rj210FW1Wb6TWXzQc5+P+EWI9/zdS57hLEc0gnyuvdzWo8+Y8brKlbj0muejonhMI/xAZCnZZwjbIfv1CkOw==}
+ engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ peerDependencies:
+ eslint: ^8.57.0 || ^9.0.0
+ typescript: '>=4.8.4 <5.8.0'
+
+ typescript@5.7.3:
+ resolution: {integrity: sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==}
+ engines: {node: '>=14.17'}
+ hasBin: true
+
+ uri-js@4.4.1:
+ resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
+
+ vite@6.0.11:
+ resolution: {integrity: sha512-4VL9mQPKoHy4+FE0NnRE/kbY51TOfaknxAjt3fJbGJxhIpBZiqVzlZDEesWWsuREXHwNdAoOFZ9MkPEVXczHwg==}
+ engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
+ hasBin: true
+ peerDependencies:
+ '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0
+ jiti: '>=1.21.0'
+ less: '*'
+ lightningcss: ^1.21.0
+ sass: '*'
+ sass-embedded: '*'
+ stylus: '*'
+ sugarss: '*'
+ terser: ^5.16.0
+ tsx: ^4.8.1
+ yaml: ^2.4.2
+ peerDependenciesMeta:
+ '@types/node':
+ optional: true
+ jiti:
+ optional: true
+ less:
+ optional: true
+ lightningcss:
+ optional: true
+ sass:
+ optional: true
+ sass-embedded:
+ optional: true
+ stylus:
+ optional: true
+ sugarss:
+ optional: true
+ terser:
+ optional: true
+ tsx:
+ optional: true
+ yaml:
+ optional: true
+
+ which@2.0.2:
+ resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
+ engines: {node: '>= 8'}
+ hasBin: true
+
+ word-wrap@1.2.5:
+ resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==}
+ engines: {node: '>=0.10.0'}
+
+ yocto-queue@0.1.0:
+ resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
+ engines: {node: '>=10'}
+
+snapshots:
+
+ '@esbuild/aix-ppc64@0.24.2':
+ optional: true
+
+ '@esbuild/android-arm64@0.24.2':
+ optional: true
+
+ '@esbuild/android-arm@0.24.2':
+ optional: true
+
+ '@esbuild/android-x64@0.24.2':
+ optional: true
+
+ '@esbuild/darwin-arm64@0.24.2':
+ optional: true
+
+ '@esbuild/darwin-x64@0.24.2':
+ optional: true
+
+ '@esbuild/freebsd-arm64@0.24.2':
+ optional: true
+
+ '@esbuild/freebsd-x64@0.24.2':
+ optional: true
+
+ '@esbuild/linux-arm64@0.24.2':
+ optional: true
+
+ '@esbuild/linux-arm@0.24.2':
+ optional: true
+
+ '@esbuild/linux-ia32@0.24.2':
+ optional: true
+
+ '@esbuild/linux-loong64@0.24.2':
+ optional: true
+
+ '@esbuild/linux-mips64el@0.24.2':
+ optional: true
+
+ '@esbuild/linux-ppc64@0.24.2':
+ optional: true
+
+ '@esbuild/linux-riscv64@0.24.2':
+ optional: true
+
+ '@esbuild/linux-s390x@0.24.2':
+ optional: true
+
+ '@esbuild/linux-x64@0.24.2':
+ optional: true
+
+ '@esbuild/netbsd-arm64@0.24.2':
+ optional: true
+
+ '@esbuild/netbsd-x64@0.24.2':
+ optional: true
+
+ '@esbuild/openbsd-arm64@0.24.2':
+ optional: true
+
+ '@esbuild/openbsd-x64@0.24.2':
+ optional: true
+
+ '@esbuild/sunos-x64@0.24.2':
+ optional: true
+
+ '@esbuild/win32-arm64@0.24.2':
+ optional: true
+
+ '@esbuild/win32-ia32@0.24.2':
+ optional: true
+
+ '@esbuild/win32-x64@0.24.2':
+ optional: true
+
+ '@eslint-community/eslint-utils@4.4.1(eslint@9.19.0)':
+ dependencies:
+ eslint: 9.19.0
+ eslint-visitor-keys: 3.4.3
+
+ '@eslint-community/regexpp@4.12.1': {}
+
+ '@eslint/config-array@0.19.1':
+ dependencies:
+ '@eslint/object-schema': 2.1.5
+ debug: 4.4.0
+ minimatch: 3.1.2
+ transitivePeerDependencies:
+ - supports-color
+
+ '@eslint/core@0.10.0':
+ dependencies:
+ '@types/json-schema': 7.0.15
+
+ '@eslint/eslintrc@3.2.0':
+ dependencies:
+ ajv: 6.12.6
+ debug: 4.4.0
+ espree: 10.3.0
+ globals: 14.0.0
+ ignore: 5.3.2
+ import-fresh: 3.3.0
+ js-yaml: 4.1.0
+ minimatch: 3.1.2
+ strip-json-comments: 3.1.1
+ transitivePeerDependencies:
+ - supports-color
+
+ '@eslint/js@9.19.0': {}
+
+ '@eslint/object-schema@2.1.5': {}
+
+ '@eslint/plugin-kit@0.2.5':
+ dependencies:
+ '@eslint/core': 0.10.0
+ levn: 0.4.1
+
+ '@humanfs/core@0.19.1': {}
+
+ '@humanfs/node@0.16.6':
+ dependencies:
+ '@humanfs/core': 0.19.1
+ '@humanwhocodes/retry': 0.3.1
+
+ '@humanwhocodes/module-importer@1.0.1': {}
+
+ '@humanwhocodes/retry@0.3.1': {}
+
+ '@humanwhocodes/retry@0.4.1': {}
+
+ '@nodelib/fs.scandir@2.1.5':
+ dependencies:
+ '@nodelib/fs.stat': 2.0.5
+ run-parallel: 1.2.0
+
+ '@nodelib/fs.stat@2.0.5': {}
+
+ '@nodelib/fs.walk@1.2.8':
+ dependencies:
+ '@nodelib/fs.scandir': 2.1.5
+ fastq: 1.18.0
+
+ '@rollup/rollup-android-arm-eabi@4.32.0':
+ optional: true
+
+ '@rollup/rollup-android-arm64@4.32.0':
+ optional: true
+
+ '@rollup/rollup-darwin-arm64@4.32.0':
+ optional: true
+
+ '@rollup/rollup-darwin-x64@4.32.0':
+ optional: true
+
+ '@rollup/rollup-freebsd-arm64@4.32.0':
+ optional: true
+
+ '@rollup/rollup-freebsd-x64@4.32.0':
+ optional: true
+
+ '@rollup/rollup-linux-arm-gnueabihf@4.32.0':
+ optional: true
+
+ '@rollup/rollup-linux-arm-musleabihf@4.32.0':
+ optional: true
+
+ '@rollup/rollup-linux-arm64-gnu@4.32.0':
+ optional: true
+
+ '@rollup/rollup-linux-arm64-musl@4.32.0':
+ optional: true
+
+ '@rollup/rollup-linux-loongarch64-gnu@4.32.0':
+ optional: true
+
+ '@rollup/rollup-linux-powerpc64le-gnu@4.32.0':
+ optional: true
+
+ '@rollup/rollup-linux-riscv64-gnu@4.32.0':
+ optional: true
+
+ '@rollup/rollup-linux-s390x-gnu@4.32.0':
+ optional: true
+
+ '@rollup/rollup-linux-x64-gnu@4.32.0':
+ optional: true
+
+ '@rollup/rollup-linux-x64-musl@4.32.0':
+ optional: true
+
+ '@rollup/rollup-win32-arm64-msvc@4.32.0':
+ optional: true
+
+ '@rollup/rollup-win32-ia32-msvc@4.32.0':
+ optional: true
+
+ '@rollup/rollup-win32-x64-msvc@4.32.0':
+ optional: true
+
+ '@swc/core-darwin-arm64@1.10.11':
+ optional: true
+
+ '@swc/core-darwin-x64@1.10.11':
+ optional: true
+
+ '@swc/core-linux-arm-gnueabihf@1.10.11':
+ optional: true
+
+ '@swc/core-linux-arm64-gnu@1.10.11':
+ optional: true
+
+ '@swc/core-linux-arm64-musl@1.10.11':
+ optional: true
+
+ '@swc/core-linux-x64-gnu@1.10.11':
+ optional: true
+
+ '@swc/core-linux-x64-musl@1.10.11':
+ optional: true
+
+ '@swc/core-win32-arm64-msvc@1.10.11':
+ optional: true
+
+ '@swc/core-win32-ia32-msvc@1.10.11':
+ optional: true
+
+ '@swc/core-win32-x64-msvc@1.10.11':
+ optional: true
+
+ '@swc/core@1.10.11':
+ dependencies:
+ '@swc/counter': 0.1.3
+ '@swc/types': 0.1.17
+ optionalDependencies:
+ '@swc/core-darwin-arm64': 1.10.11
+ '@swc/core-darwin-x64': 1.10.11
+ '@swc/core-linux-arm-gnueabihf': 1.10.11
+ '@swc/core-linux-arm64-gnu': 1.10.11
+ '@swc/core-linux-arm64-musl': 1.10.11
+ '@swc/core-linux-x64-gnu': 1.10.11
+ '@swc/core-linux-x64-musl': 1.10.11
+ '@swc/core-win32-arm64-msvc': 1.10.11
+ '@swc/core-win32-ia32-msvc': 1.10.11
+ '@swc/core-win32-x64-msvc': 1.10.11
+
+ '@swc/counter@0.1.3': {}
+
+ '@swc/types@0.1.17':
+ dependencies:
+ '@swc/counter': 0.1.3
+
+ '@types/estree@1.0.6': {}
+
+ '@types/json-schema@7.0.15': {}
+
+ '@types/react-dom@19.0.3(@types/react@19.0.8)':
+ dependencies:
+ '@types/react': 19.0.8
+
+ '@types/react@19.0.8':
+ dependencies:
+ csstype: 3.1.3
+
+ '@typescript-eslint/eslint-plugin@8.22.0(@typescript-eslint/parser@8.22.0(eslint@9.19.0)(typescript@5.7.3))(eslint@9.19.0)(typescript@5.7.3)':
+ dependencies:
+ '@eslint-community/regexpp': 4.12.1
+ '@typescript-eslint/parser': 8.22.0(eslint@9.19.0)(typescript@5.7.3)
+ '@typescript-eslint/scope-manager': 8.22.0
+ '@typescript-eslint/type-utils': 8.22.0(eslint@9.19.0)(typescript@5.7.3)
+ '@typescript-eslint/utils': 8.22.0(eslint@9.19.0)(typescript@5.7.3)
+ '@typescript-eslint/visitor-keys': 8.22.0
+ eslint: 9.19.0
+ graphemer: 1.4.0
+ ignore: 5.3.2
+ natural-compare: 1.4.0
+ ts-api-utils: 2.0.0(typescript@5.7.3)
+ typescript: 5.7.3
+ transitivePeerDependencies:
+ - supports-color
+
+ '@typescript-eslint/parser@8.22.0(eslint@9.19.0)(typescript@5.7.3)':
+ dependencies:
+ '@typescript-eslint/scope-manager': 8.22.0
+ '@typescript-eslint/types': 8.22.0
+ '@typescript-eslint/typescript-estree': 8.22.0(typescript@5.7.3)
+ '@typescript-eslint/visitor-keys': 8.22.0
+ debug: 4.4.0
+ eslint: 9.19.0
+ typescript: 5.7.3
+ transitivePeerDependencies:
+ - supports-color
+
+ '@typescript-eslint/scope-manager@8.22.0':
+ dependencies:
+ '@typescript-eslint/types': 8.22.0
+ '@typescript-eslint/visitor-keys': 8.22.0
+
+ '@typescript-eslint/type-utils@8.22.0(eslint@9.19.0)(typescript@5.7.3)':
+ dependencies:
+ '@typescript-eslint/typescript-estree': 8.22.0(typescript@5.7.3)
+ '@typescript-eslint/utils': 8.22.0(eslint@9.19.0)(typescript@5.7.3)
+ debug: 4.4.0
+ eslint: 9.19.0
+ ts-api-utils: 2.0.0(typescript@5.7.3)
+ typescript: 5.7.3
+ transitivePeerDependencies:
+ - supports-color
+
+ '@typescript-eslint/types@8.22.0': {}
+
+ '@typescript-eslint/typescript-estree@8.22.0(typescript@5.7.3)':
+ dependencies:
+ '@typescript-eslint/types': 8.22.0
+ '@typescript-eslint/visitor-keys': 8.22.0
+ debug: 4.4.0
+ fast-glob: 3.3.3
+ is-glob: 4.0.3
+ minimatch: 9.0.5
+ semver: 7.6.3
+ ts-api-utils: 2.0.0(typescript@5.7.3)
+ typescript: 5.7.3
+ transitivePeerDependencies:
+ - supports-color
+
+ '@typescript-eslint/utils@8.22.0(eslint@9.19.0)(typescript@5.7.3)':
+ dependencies:
+ '@eslint-community/eslint-utils': 4.4.1(eslint@9.19.0)
+ '@typescript-eslint/scope-manager': 8.22.0
+ '@typescript-eslint/types': 8.22.0
+ '@typescript-eslint/typescript-estree': 8.22.0(typescript@5.7.3)
+ eslint: 9.19.0
+ typescript: 5.7.3
+ transitivePeerDependencies:
+ - supports-color
+
+ '@typescript-eslint/visitor-keys@8.22.0':
+ dependencies:
+ '@typescript-eslint/types': 8.22.0
+ eslint-visitor-keys: 4.2.0
+
+ '@vitejs/plugin-react-swc@3.7.2(vite@6.0.11)':
+ dependencies:
+ '@swc/core': 1.10.11
+ vite: 6.0.11
+ transitivePeerDependencies:
+ - '@swc/helpers'
+
+ acorn-jsx@5.3.2(acorn@8.14.0):
+ dependencies:
+ acorn: 8.14.0
+
+ acorn@8.14.0: {}
+
+ ajv@6.12.6:
+ dependencies:
+ fast-deep-equal: 3.1.3
+ fast-json-stable-stringify: 2.1.0
+ json-schema-traverse: 0.4.1
+ uri-js: 4.4.1
+
+ ansi-styles@4.3.0:
+ dependencies:
+ color-convert: 2.0.1
+
+ argparse@2.0.1: {}
+
+ balanced-match@1.0.2: {}
+
+ brace-expansion@1.1.11:
+ dependencies:
+ balanced-match: 1.0.2
+ concat-map: 0.0.1
+
+ brace-expansion@2.0.1:
+ dependencies:
+ balanced-match: 1.0.2
+
+ braces@3.0.3:
+ dependencies:
+ fill-range: 7.1.1
+
+ callsites@3.1.0: {}
+
+ chalk@4.1.2:
+ dependencies:
+ ansi-styles: 4.3.0
+ supports-color: 7.2.0
+
+ color-convert@2.0.1:
+ dependencies:
+ color-name: 1.1.4
+
+ color-name@1.1.4: {}
+
+ concat-map@0.0.1: {}
+
+ cross-spawn@7.0.6:
+ dependencies:
+ path-key: 3.1.1
+ shebang-command: 2.0.0
+ which: 2.0.2
+
+ csstype@3.1.3: {}
+
+ debug@4.4.0:
+ dependencies:
+ ms: 2.1.3
+
+ deep-is@0.1.4: {}
+
+ esbuild@0.24.2:
+ optionalDependencies:
+ '@esbuild/aix-ppc64': 0.24.2
+ '@esbuild/android-arm': 0.24.2
+ '@esbuild/android-arm64': 0.24.2
+ '@esbuild/android-x64': 0.24.2
+ '@esbuild/darwin-arm64': 0.24.2
+ '@esbuild/darwin-x64': 0.24.2
+ '@esbuild/freebsd-arm64': 0.24.2
+ '@esbuild/freebsd-x64': 0.24.2
+ '@esbuild/linux-arm': 0.24.2
+ '@esbuild/linux-arm64': 0.24.2
+ '@esbuild/linux-ia32': 0.24.2
+ '@esbuild/linux-loong64': 0.24.2
+ '@esbuild/linux-mips64el': 0.24.2
+ '@esbuild/linux-ppc64': 0.24.2
+ '@esbuild/linux-riscv64': 0.24.2
+ '@esbuild/linux-s390x': 0.24.2
+ '@esbuild/linux-x64': 0.24.2
+ '@esbuild/netbsd-arm64': 0.24.2
+ '@esbuild/netbsd-x64': 0.24.2
+ '@esbuild/openbsd-arm64': 0.24.2
+ '@esbuild/openbsd-x64': 0.24.2
+ '@esbuild/sunos-x64': 0.24.2
+ '@esbuild/win32-arm64': 0.24.2
+ '@esbuild/win32-ia32': 0.24.2
+ '@esbuild/win32-x64': 0.24.2
+
+ escape-string-regexp@4.0.0: {}
+
+ eslint-plugin-react-hooks@5.1.0(eslint@9.19.0):
+ dependencies:
+ eslint: 9.19.0
+
+ eslint-plugin-react-refresh@0.4.18(eslint@9.19.0):
+ dependencies:
+ eslint: 9.19.0
+
+ eslint-scope@8.2.0:
+ dependencies:
+ esrecurse: 4.3.0
+ estraverse: 5.3.0
+
+ eslint-visitor-keys@3.4.3: {}
+
+ eslint-visitor-keys@4.2.0: {}
+
+ eslint@9.19.0:
+ dependencies:
+ '@eslint-community/eslint-utils': 4.4.1(eslint@9.19.0)
+ '@eslint-community/regexpp': 4.12.1
+ '@eslint/config-array': 0.19.1
+ '@eslint/core': 0.10.0
+ '@eslint/eslintrc': 3.2.0
+ '@eslint/js': 9.19.0
+ '@eslint/plugin-kit': 0.2.5
+ '@humanfs/node': 0.16.6
+ '@humanwhocodes/module-importer': 1.0.1
+ '@humanwhocodes/retry': 0.4.1
+ '@types/estree': 1.0.6
+ '@types/json-schema': 7.0.15
+ ajv: 6.12.6
+ chalk: 4.1.2
+ cross-spawn: 7.0.6
+ debug: 4.4.0
+ escape-string-regexp: 4.0.0
+ eslint-scope: 8.2.0
+ eslint-visitor-keys: 4.2.0
+ espree: 10.3.0
+ esquery: 1.6.0
+ esutils: 2.0.3
+ fast-deep-equal: 3.1.3
+ file-entry-cache: 8.0.0
+ find-up: 5.0.0
+ glob-parent: 6.0.2
+ ignore: 5.3.2
+ imurmurhash: 0.1.4
+ is-glob: 4.0.3
+ json-stable-stringify-without-jsonify: 1.0.1
+ lodash.merge: 4.6.2
+ minimatch: 3.1.2
+ natural-compare: 1.4.0
+ optionator: 0.9.4
+ transitivePeerDependencies:
+ - supports-color
+
+ espree@10.3.0:
+ dependencies:
+ acorn: 8.14.0
+ acorn-jsx: 5.3.2(acorn@8.14.0)
+ eslint-visitor-keys: 4.2.0
+
+ esquery@1.6.0:
+ dependencies:
+ estraverse: 5.3.0
+
+ esrecurse@4.3.0:
+ dependencies:
+ estraverse: 5.3.0
+
+ estraverse@5.3.0: {}
+
+ esutils@2.0.3: {}
+
+ fast-deep-equal@3.1.3: {}
+
+ fast-glob@3.3.3:
+ dependencies:
+ '@nodelib/fs.stat': 2.0.5
+ '@nodelib/fs.walk': 1.2.8
+ glob-parent: 5.1.2
+ merge2: 1.4.1
+ micromatch: 4.0.8
+
+ fast-json-stable-stringify@2.1.0: {}
+
+ fast-levenshtein@2.0.6: {}
+
+ fastq@1.18.0:
+ dependencies:
+ reusify: 1.0.4
+
+ file-entry-cache@8.0.0:
+ dependencies:
+ flat-cache: 4.0.1
+
+ fill-range@7.1.1:
+ dependencies:
+ to-regex-range: 5.0.1
+
+ find-up@5.0.0:
+ dependencies:
+ locate-path: 6.0.0
+ path-exists: 4.0.0
+
+ flat-cache@4.0.1:
+ dependencies:
+ flatted: 3.3.2
+ keyv: 4.5.4
+
+ flatted@3.3.2: {}
+
+ fsevents@2.3.3:
+ optional: true
+
+ glob-parent@5.1.2:
+ dependencies:
+ is-glob: 4.0.3
+
+ glob-parent@6.0.2:
+ dependencies:
+ is-glob: 4.0.3
+
+ globals@14.0.0: {}
+
+ globals@15.14.0: {}
+
+ graphemer@1.4.0: {}
+
+ has-flag@4.0.0: {}
+
+ ignore@5.3.2: {}
+
+ import-fresh@3.3.0:
+ dependencies:
+ parent-module: 1.0.1
+ resolve-from: 4.0.0
+
+ imurmurhash@0.1.4: {}
+
+ is-extglob@2.1.1: {}
+
+ is-glob@4.0.3:
+ dependencies:
+ is-extglob: 2.1.1
+
+ is-number@7.0.0: {}
+
+ isexe@2.0.0: {}
+
+ js-yaml@4.1.0:
+ dependencies:
+ argparse: 2.0.1
+
+ json-buffer@3.0.1: {}
+
+ json-schema-traverse@0.4.1: {}
+
+ json-stable-stringify-without-jsonify@1.0.1: {}
+
+ keyv@4.5.4:
+ dependencies:
+ json-buffer: 3.0.1
+
+ levn@0.4.1:
+ dependencies:
+ prelude-ls: 1.2.1
+ type-check: 0.4.0
+
+ locate-path@6.0.0:
+ dependencies:
+ p-locate: 5.0.0
+
+ lodash.merge@4.6.2: {}
+
+ merge2@1.4.1: {}
+
+ micromatch@4.0.8:
+ dependencies:
+ braces: 3.0.3
+ picomatch: 2.3.1
+
+ minimatch@3.1.2:
+ dependencies:
+ brace-expansion: 1.1.11
+
+ minimatch@9.0.5:
+ dependencies:
+ brace-expansion: 2.0.1
+
+ ms@2.1.3: {}
+
+ nanoid@3.3.8: {}
+
+ natural-compare@1.4.0: {}
+
+ optionator@0.9.4:
+ dependencies:
+ deep-is: 0.1.4
+ fast-levenshtein: 2.0.6
+ levn: 0.4.1
+ prelude-ls: 1.2.1
+ type-check: 0.4.0
+ word-wrap: 1.2.5
+
+ p-limit@3.1.0:
+ dependencies:
+ yocto-queue: 0.1.0
+
+ p-locate@5.0.0:
+ dependencies:
+ p-limit: 3.1.0
+
+ parent-module@1.0.1:
+ dependencies:
+ callsites: 3.1.0
+
+ path-exists@4.0.0: {}
+
+ path-key@3.1.1: {}
+
+ picocolors@1.1.1: {}
+
+ picomatch@2.3.1: {}
+
+ postcss@8.5.1:
+ dependencies:
+ nanoid: 3.3.8
+ picocolors: 1.1.1
+ source-map-js: 1.2.1
+
+ prelude-ls@1.2.1: {}
+
+ punycode@2.3.1: {}
+
+ queue-microtask@1.2.3: {}
+
+ react-dom@19.0.0(react@19.0.0):
+ dependencies:
+ react: 19.0.0
+ scheduler: 0.25.0
+
+ react@19.0.0: {}
+
+ resolve-from@4.0.0: {}
+
+ reusify@1.0.4: {}
+
+ rollup@4.32.0:
+ dependencies:
+ '@types/estree': 1.0.6
+ optionalDependencies:
+ '@rollup/rollup-android-arm-eabi': 4.32.0
+ '@rollup/rollup-android-arm64': 4.32.0
+ '@rollup/rollup-darwin-arm64': 4.32.0
+ '@rollup/rollup-darwin-x64': 4.32.0
+ '@rollup/rollup-freebsd-arm64': 4.32.0
+ '@rollup/rollup-freebsd-x64': 4.32.0
+ '@rollup/rollup-linux-arm-gnueabihf': 4.32.0
+ '@rollup/rollup-linux-arm-musleabihf': 4.32.0
+ '@rollup/rollup-linux-arm64-gnu': 4.32.0
+ '@rollup/rollup-linux-arm64-musl': 4.32.0
+ '@rollup/rollup-linux-loongarch64-gnu': 4.32.0
+ '@rollup/rollup-linux-powerpc64le-gnu': 4.32.0
+ '@rollup/rollup-linux-riscv64-gnu': 4.32.0
+ '@rollup/rollup-linux-s390x-gnu': 4.32.0
+ '@rollup/rollup-linux-x64-gnu': 4.32.0
+ '@rollup/rollup-linux-x64-musl': 4.32.0
+ '@rollup/rollup-win32-arm64-msvc': 4.32.0
+ '@rollup/rollup-win32-ia32-msvc': 4.32.0
+ '@rollup/rollup-win32-x64-msvc': 4.32.0
+ fsevents: 2.3.3
+
+ run-parallel@1.2.0:
+ dependencies:
+ queue-microtask: 1.2.3
+
+ scheduler@0.25.0: {}
+
+ semver@7.6.3: {}
+
+ shebang-command@2.0.0:
+ dependencies:
+ shebang-regex: 3.0.0
+
+ shebang-regex@3.0.0: {}
+
+ source-map-js@1.2.1: {}
+
+ strip-json-comments@3.1.1: {}
+
+ supports-color@7.2.0:
+ dependencies:
+ has-flag: 4.0.0
+
+ to-regex-range@5.0.1:
+ dependencies:
+ is-number: 7.0.0
+
+ ts-api-utils@2.0.0(typescript@5.7.3):
+ dependencies:
+ typescript: 5.7.3
+
+ type-check@0.4.0:
+ dependencies:
+ prelude-ls: 1.2.1
+
+ typescript-eslint@8.22.0(eslint@9.19.0)(typescript@5.7.3):
+ dependencies:
+ '@typescript-eslint/eslint-plugin': 8.22.0(@typescript-eslint/parser@8.22.0(eslint@9.19.0)(typescript@5.7.3))(eslint@9.19.0)(typescript@5.7.3)
+ '@typescript-eslint/parser': 8.22.0(eslint@9.19.0)(typescript@5.7.3)
+ '@typescript-eslint/utils': 8.22.0(eslint@9.19.0)(typescript@5.7.3)
+ eslint: 9.19.0
+ typescript: 5.7.3
+ transitivePeerDependencies:
+ - supports-color
+
+ typescript@5.7.3: {}
+
+ uri-js@4.4.1:
+ dependencies:
+ punycode: 2.3.1
+
+ vite@6.0.11:
+ dependencies:
+ esbuild: 0.24.2
+ postcss: 8.5.1
+ rollup: 4.32.0
+ optionalDependencies:
+ fsevents: 2.3.3
+
+ which@2.0.2:
+ dependencies:
+ isexe: 2.0.0
+
+ word-wrap@1.2.5: {}
+
+ yocto-queue@0.1.0: {}
diff --git a/generators/ra-shadcn/files/public/vite.svg b/generators/ra-shadcn/files/public/vite.svg
new file mode 100644
index 0000000..e7b8dfb
--- /dev/null
+++ b/generators/ra-shadcn/files/public/vite.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/generators/ra-shadcn/files/src/App.css b/generators/ra-shadcn/files/src/App.css
new file mode 100644
index 0000000..e69de29
diff --git a/generators/ra-shadcn/files/src/App.tsx b/generators/ra-shadcn/files/src/App.tsx
new file mode 100644
index 0000000..3e68093
--- /dev/null
+++ b/generators/ra-shadcn/files/src/App.tsx
@@ -0,0 +1,39 @@
+import { useState } from 'react'
+import reactLogo from './assets/react.svg'
+import viteLogo from '/vite.svg'
+import './App.css'
+
+function App() {
+ const [count, setCount] = useState(0)
+
+ return (
+ <>
+
+ Hello world!
+
+
+
+ Vite + React
+
+
setCount((count) => count + 1)}>
+ count is {count}
+
+
+ Edit src/App.tsx
and save to test HMR
+
+
+
+ Click on the Vite and React logos to learn more
+
+ >
+ )
+}
+
+export default App
diff --git a/generators/ra-shadcn/files/src/assets/react.svg b/generators/ra-shadcn/files/src/assets/react.svg
new file mode 100644
index 0000000..6c87de9
--- /dev/null
+++ b/generators/ra-shadcn/files/src/assets/react.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/generators/ra-shadcn/files/src/index.css b/generators/ra-shadcn/files/src/index.css
new file mode 100644
index 0000000..f1d8c73
--- /dev/null
+++ b/generators/ra-shadcn/files/src/index.css
@@ -0,0 +1 @@
+@import "tailwindcss";
diff --git a/generators/ra-shadcn/files/src/main.tsx b/generators/ra-shadcn/files/src/main.tsx
new file mode 100644
index 0000000..bef5202
--- /dev/null
+++ b/generators/ra-shadcn/files/src/main.tsx
@@ -0,0 +1,10 @@
+import { StrictMode } from 'react'
+import { createRoot } from 'react-dom/client'
+import './index.css'
+import App from './App.tsx'
+
+createRoot(document.getElementById('root')!).render(
+
+
+ ,
+)
diff --git a/generators/ra-shadcn/files/src/vite-env.d.ts b/generators/ra-shadcn/files/src/vite-env.d.ts
new file mode 100644
index 0000000..11f02fe
--- /dev/null
+++ b/generators/ra-shadcn/files/src/vite-env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/generators/ra-shadcn/files/tsconfig.app.json b/generators/ra-shadcn/files/tsconfig.app.json
new file mode 100644
index 0000000..358ca9b
--- /dev/null
+++ b/generators/ra-shadcn/files/tsconfig.app.json
@@ -0,0 +1,26 @@
+{
+ "compilerOptions": {
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
+ "target": "ES2020",
+ "useDefineForClassFields": true,
+ "lib": ["ES2020", "DOM", "DOM.Iterable"],
+ "module": "ESNext",
+ "skipLibCheck": true,
+
+ /* Bundler mode */
+ "moduleResolution": "bundler",
+ "allowImportingTsExtensions": true,
+ "isolatedModules": true,
+ "moduleDetection": "force",
+ "noEmit": true,
+ "jsx": "react-jsx",
+
+ /* Linting */
+ "strict": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "noFallthroughCasesInSwitch": true,
+ "noUncheckedSideEffectImports": true
+ },
+ "include": ["src"]
+}
diff --git a/generators/ra-shadcn/files/tsconfig.json b/generators/ra-shadcn/files/tsconfig.json
new file mode 100644
index 0000000..1ffef60
--- /dev/null
+++ b/generators/ra-shadcn/files/tsconfig.json
@@ -0,0 +1,7 @@
+{
+ "files": [],
+ "references": [
+ { "path": "./tsconfig.app.json" },
+ { "path": "./tsconfig.node.json" }
+ ]
+}
diff --git a/generators/ra-shadcn/files/tsconfig.node.json b/generators/ra-shadcn/files/tsconfig.node.json
new file mode 100644
index 0000000..db0becc
--- /dev/null
+++ b/generators/ra-shadcn/files/tsconfig.node.json
@@ -0,0 +1,24 @@
+{
+ "compilerOptions": {
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
+ "target": "ES2022",
+ "lib": ["ES2023"],
+ "module": "ESNext",
+ "skipLibCheck": true,
+
+ /* Bundler mode */
+ "moduleResolution": "bundler",
+ "allowImportingTsExtensions": true,
+ "isolatedModules": true,
+ "moduleDetection": "force",
+ "noEmit": true,
+
+ /* Linting */
+ "strict": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "noFallthroughCasesInSwitch": true,
+ "noUncheckedSideEffectImports": true
+ },
+ "include": ["vite.config.ts"]
+}
diff --git a/generators/ra-shadcn/files/vite.config.ts b/generators/ra-shadcn/files/vite.config.ts
new file mode 100644
index 0000000..59b4c12
--- /dev/null
+++ b/generators/ra-shadcn/files/vite.config.ts
@@ -0,0 +1,13 @@
+import { defineConfig } from 'vite'
+import react from '@vitejs/plugin-react-swc'
+import tailwindcss from '@tailwindcss/vite'
+
+
+// https://vite.dev/config/
+export default defineConfig({
+ plugins: [
+ react(),
+ tailwindcss(),
+
+ ],
+})
diff --git a/generators/ra-shadcn/templates/App.tsx.jinja b/generators/ra-shadcn/templates/App.tsx.jinja
new file mode 100644
index 0000000..3c0f72b
--- /dev/null
+++ b/generators/ra-shadcn/templates/App.tsx.jinja
@@ -0,0 +1,24 @@
+to: {{ values.outputFolder }}/src/App.tsx
+message: "File `App.tsx` was created successfully."
+---
+import { Admin, Resource } from "react-admin";
+import { dataProvider } from './dataProvider';
+{% for entity_name,entity in entities | items -%}
+{% if not entity.properties -%}{% continue -%}{% endif -%}
+import {{ entity.title | camel_case }} from "./models/{{ entity.title | camel_case }}";
+{% endfor %}
+import { Dashboard } from "./Dashboard";
+import authProvider from './authProvider';
+
+const App = () => {
+ return (
+
+ {% for entity_name,entity in entities | items -%}
+ {% if not entity.properties -%}{% continue -%}{% endif -%}
+
+ {% endfor %}
+
+ );
+}
+
+export default App;
\ No newline at end of file
diff --git a/generators/ra-shadcn/templates/authProvider.tsx.jinja b/generators/ra-shadcn/templates/authProvider.tsx.jinja
new file mode 100644
index 0000000..c397c8a
--- /dev/null
+++ b/generators/ra-shadcn/templates/authProvider.tsx.jinja
@@ -0,0 +1,48 @@
+to: {{ values.outputFolder }}/src/authProvider.ts
+message: "File for ui `package.json` was created successfully."
+---
+const url = "";
+
+const authProvider = {
+
+ login: ({username, password}) => {
+ const request = new Request(`${url}/api/auth/login`, {
+ method: 'POST',
+ body: JSON.stringify({username, password}),
+ headers: new Headers({'Content-Type': 'application/json'}),
+ });
+ return fetch(request)
+ .then(response => {
+ if (response.status < 200 || response.status >= 300) {
+ throw new Error(response.statusText);
+ }
+ return response.json();
+ })
+ .then(auth => {
+ console.log("auth:", JSON.stringify(auth));
+ let token = `Bearer ${auth.id_token}`;
+ console.log("token:", token);
+ localStorage.setItem('token', token);
+ })
+ .catch(() => {
+ throw new Error('Network error')
+ });
+ },
+ logout: () => {
+ localStorage.removeItem('token');
+ return Promise.resolve();
+ },
+ checkAuth: () => {
+ return localStorage.getItem('token')
+ ? Promise.resolve()
+ : Promise.reject();
+
+ },
+ getPermissions: () => {
+ // Required for the authentication to work
+ return Promise.resolve();
+ },
+ // ...
+};
+
+export default authProvider;
\ No newline at end of file
diff --git a/generators/ra-shadcn/templates/dataProvider.tsx.jinja b/generators/ra-shadcn/templates/dataProvider.tsx.jinja
new file mode 100644
index 0000000..f3414d5
--- /dev/null
+++ b/generators/ra-shadcn/templates/dataProvider.tsx.jinja
@@ -0,0 +1,10 @@
+to: {{ values.outputFolder }}/src/dataProvider.ts
+message: "File for ui `package.json` was created successfully."
+---
+{% if features and 'graphql' in features -%}
+{% include "_graphql-data-provider.jinja" -%}
+{% elif features and 'jhipster' in features -%}
+{% include "_jhipster-data-provider.jinja" -%}
+{% else -%}
+{% include "_rest-data-provider.jinja" -%}
+{% endif -%}
diff --git a/generators/ra-shadcn/templates/models.tsx.jinja b/generators/ra-shadcn/templates/models.tsx.jinja
new file mode 100644
index 0000000..5b0e57f
--- /dev/null
+++ b/generators/ra-shadcn/templates/models.tsx.jinja
@@ -0,0 +1,88 @@
+{# generate model ui #}
+{% for entity_name,entity in entities | items -%}
+{% if entity.properties %}
+{% set file_name = entity.title | snake_case -%}
+{% set module_name = file_name | pascal_case -%}
+---
+to: {{ values.outputFolder }}/src/models/{{ entity.title | camel_case }}.tsx
+message: "File for ui `{{module_name}}` was created successfully."
+---
+{# generate model ui #}
+{% import "_macros_front.jinja" as macros %}
+{% import "_macros.jinja" as core %}
+{% import "react-admin-macros.jinja" as ra_macros -%}
+
+import { Show, SimpleShowLayout, Create, List, DatagridConfigurable, TextField, BooleanField, BooleanInput, DateField, ReferenceField, EditButton, Edit, SimpleForm, ReferenceInput, TextInput,DateInput, DateTimeInput, ReferenceArrayInput, NumberField, NumberInput, required, AutocompleteInput, SelectInput } from "ra-core";
+import { ListActions } from "../components/common/action-buttons/listActions.tsx";
+import { UserBulkActionButtons } from "../components/common/action-buttons/bulkListActions.tsx";
+import {ShowActionButtons} from "../components/common/action-buttons/showActionButtons.tsx";
+import {EditActionButtons} from "../components/common/action-buttons/editActionButtons.tsx";
+
+
+const {{ entity.title | camel_case }}Filters = [
+ ,
+];
+
+
+export const {{ entity.title | pascal_case }}List = () => (
+
} >
+
+
+ {% if extraFields and 'createdAt' in extraFields -%} {% endif -%}
+ {% if extraFields and 'updatedAt' in extraFields -%} {% endif -%}
+ {% for name,property in entity.properties | items -%}
+ {% if core.relation_is_one_to_many(property=property)=='true' -%}{% continue -%}{% endif -%}
+ <{{ macros.get_field(property=property) }} source="{{ macros.source(name=name,property=property)}}" />
+ {% endfor %}
+
+
+);
+
+export const {{ entity.title | pascal_case }}Show = () => (
+ }>
+
+
+ {% if extraFields and 'createdAt' in extraFields -%} {% endif -%}
+ {% if extraFields and 'updatedAt' in extraFields -%} {% endif -%}
+ {% for name,property in entity.properties | items -%}
+ {% if core.relation_is_one_to_many(property=property)=='true' -%}{% continue -%}{% endif -%}
+ <{{ macros.get_field(property=property) }} source="{{ macros.source(name=name,property=property)}}" />
+ {% endfor %}
+
+
+);
+
+export const {{ entity.title | pascal_case }}Edit = () => (
+ }>
+
+
+ {% if extraFields and 'createdAt' in extraFields -%} {% endif -%}
+ {% if extraFields and 'updatedAt' in extraFields -%} {% endif -%}
+ {% for name,property in entity.properties | items -%}
+ {% if core.relation_is_one_to_many(property=property)=='true' -%}{% continue -%}{% endif -%}
+ {{ ra_macros.get_input_element(name,property) }}
+ {% endfor %}
+
+
+);
+
+export const {{ entity.title | pascal_case }}Create = () => (
+
+
+ {% for name,property in entity.properties | items -%}
+ {% if core.relation_is_one_to_many(property=property)=='true' -%}{% continue -%}{% endif -%}
+ {{ ra_macros.get_input_element(name,property) }}
+ {% endfor -%}
+
+
+);
+
+export default {
+ list: {{ entity.title | pascal_case }}List,
+ show: {{ entity.title | pascal_case }}Show,
+ edit: {{ entity.title | pascal_case }}Edit,
+ create: {{ entity.title | pascal_case }}Create,
+};
+---
+{% endif %}
+{% endfor -%}
\ No newline at end of file
diff --git a/generators/ra-shadcn/templates/partials/_graphql-data-provider.jinja b/generators/ra-shadcn/templates/partials/_graphql-data-provider.jinja
new file mode 100644
index 0000000..c8db436
--- /dev/null
+++ b/generators/ra-shadcn/templates/partials/_graphql-data-provider.jinja
@@ -0,0 +1,265 @@
+{% import "_macros_front.jinja" as macros -%}
+import { ApolloClient, InMemoryCache, gql } from "@apollo/client";
+import { omit } from "lodash";
+
+const apiUrl = '/api/graphql';
+
+const client = new ApolloClient({
+ uri: apiUrl,
+ headers: { "x-graphql-token": "YYY" },
+ cache: new InMemoryCache(),
+ defaultOptions: {
+ watchQuery: {
+ fetchPolicy: 'no-cache',
+ errorPolicy: 'ignore',
+ },
+ query: {
+ fetchPolicy: 'no-cache',
+ errorPolicy: 'all',
+ },
+ }
+});
+
+//todo add nodes and ids in relationships
+const fields = {
+ {% for entity_name,entity in entities | items -%}
+ {%- if not entity.properties -%}{%- continue -%}{%- endif -%}
+ '{{ entity.title | plural | kebab_case }}': "id createdAt updatedAt {{ macros.get_all_properties_by_name(entity)}}"{%- if not loop.last -%},{% endif %}
+ {% endfor %}
+};
+
+const pascal = {
+ {% for entity_name,entity in entities | items -%}
+ {%- if not entity.properties -%}{%- continue -%}{%- endif -%}
+ '{{ entity.title | plural | kebab_case }}': "{{ entity.title | pascal_case }}"{%- if not loop.last -%},{% endif %}
+ {% endfor %}
+};
+
+const camel = {
+ {% for entity_name,entity in entities | items -%}
+ {%- if not entity.properties -%}{%- continue -%}{%- endif -%}
+ '{{ entity.title | plural | kebab_case }}': "{{ entity.title | camel_case }}"{%- if not loop.last -%},{% endif %}
+ {% endfor %}
+};
+
+export const dataProvider = {
+ getList: (resource,{ sort, pagination, filter, signal }, options) => {
+ console.log(resource)
+ console.log(options)
+ const { field, order } = sort;
+ const { page, perPage } = pagination;
+ return client
+ .query({
+ query: gql`
+ query ($limit: Int!, $offset: Int!, $orderBy: ${pascal[resource]}OrderInput) {
+ ${camel[resource]}(pagination: { page: { limit: $limit, page: $offset } }, orderBy:$orderBy) {
+ nodes{
+ ${fields[resource]}
+ }
+ paginationInfo {
+ pages current offset total __typename
+ }
+ pageInfo {
+ hasPreviousPage hasNextPage startCursor endCursor __typename
+ }
+ }
+ }`,
+ variables: {
+ limit: perPage,
+ offset: (page - 1) * perPage,
+ orderBy: { "id": "ASC" },
+ where: Object.keys(filter).reduce(
+ (prev, key) => ({
+ ...prev,
+ [key]: { _eq: filter[key] },
+ }),
+ {}
+ ),
+ },
+ context: {
+ fetchOptions: {
+ signal,
+ },
+ },
+ })
+ .then((result) => ({
+ data: result.data[camel[resource]].nodes,
+ total: result.data[camel[resource]].paginationInfo.total,
+ }));
+ },
+ getOne: (resource, params) => {
+ return client
+ .query({
+ query: gql`
+ query ($id: Int!) {
+ ${resource}(id: $id) {
+ ${fields[resource]}
+ }
+ }`,
+ variables: {
+ id: params.id,
+ },
+ context: {
+ fetchOptions: {
+ signal: params.signal,
+ },
+ },
+ })
+ .then((result) => ({ data: result.data[`${resource}`] }));
+ },
+ getMany: (resource, params) => {
+ return client
+ .query({
+ query: gql`
+ query ($where: ${resource}_bool_exp) {
+ ${resource}(where: $where) {
+ ${fields[resource]}
+ }
+ }`,
+ variables: {
+ where: {
+ id: { _in: params.ids },
+ },
+ },
+ context: {
+ fetchOptions: {
+ signal: params.signal,
+ },
+ },
+ })
+ .then((result) => ({ data: result.data[resource] }));
+ },
+ getManyReference: (
+ resource,
+ { target, id, sort, pagination, filter, signal }
+ ) => {
+ const { field, order } = sort;
+ const { page, perPage } = pagination;
+ return client
+ .query({
+ query: gql`
+ query ($limit: Int, $offset: Int, $order_by: [${resource}_order_by!], $where: ${resource}_bool_exp) {
+ ${resource}(limit: $limit, offset: $offset, order_by: $order_by, where: $where) {
+ ${fields[resource]}
+ }
+ ${resource}_aggregate(where: $where) {
+ aggregate {
+ count
+ }
+ }
+ }`,
+ variables: {
+ limit: perPage,
+ offset: (page - 1) * perPage,
+ order_by: { [field]: order.toLowerCase() },
+ where: Object.keys(filter).reduce(
+ (prev, key) => ({
+ ...prev,
+ [key]: { _eq: filter[key] },
+ }),
+ { [target]: { _eq: id } }
+ ),
+ },
+ context: {
+ fetchOptions: {
+ signal,
+ },
+ },
+ })
+ .then((result) => ({
+ data: result.data[resource],
+ total: result.data[`${resource}_aggregate`].aggregate.count,
+ }));
+ },
+ create: (resource, params) => {
+ return client
+ .mutate({
+ mutation: gql`
+ mutation ($data: ${resource}_insert_input!) {
+ insert_${resource}_one(object: $data) {
+ ${fields[resource]}
+ }
+ }`,
+ variables: {
+ data: omit(params.data, ['__typename']),
+ },
+ })
+ .then((result) => ({
+ data: result.data[`insert_${resource}_one`],
+ }));
+ },
+ update: (resource, params) => {
+ return client
+ .mutate({
+ mutation: gql`
+ mutation ($id: Int!, $data: ${resource}_set_input!) {
+ update_${resource}_by_pk(pk_columns: { id: $id }, _set: $data) {
+ ${fields[resource]}
+ }
+ }`,
+ variables: {
+ id: params.id,
+ data: omit(params.data, ['__typename']),
+ },
+ })
+ .then((result) => ({
+ data: result.data[`update_${resource}_by_pk`],
+ }));
+ },
+ updateMany: (resource, params) => {
+ return client
+ .mutate({
+ mutation: gql`
+ mutation ($where: ${resource}_bool_exp!, $data: ${resource}_set_input!) {
+ update_${resource}(where: $where, _set: $data) {
+ affected_rows
+ }
+ }`,
+ variables: {
+ where: {
+ id: { _in: params.ids },
+ },
+ data: omit(params.data, ['__typename']),
+ },
+ })
+ .then((result) => ({
+ data: params.ids,
+ }));
+ },
+ delete: (resource, params) => {
+ return client
+ .mutate({
+ mutation: gql`
+ mutation ($id: Int!) {
+ delete_${resource}_by_pk(id: $id) {
+ ${fields[resource]}
+ }
+ }`,
+ variables: {
+ id: params.id,
+ },
+ })
+ .then((result) => ({
+ data: result.data[`delete_${resource}_by_pk`],
+ }));
+ },
+ deleteMany: (resource, params) => {
+ return client
+ .mutate({
+ mutation: gql`
+ mutation ($where: ${resource}_bool_exp!) {
+ delete_${resource}(where: $where) {
+ affected_rows
+ }
+ }`,
+ variables: {
+ where: {
+ id: { _in: params.ids },
+ },
+ },
+ })
+ .then((result) => ({
+ data: params.ids,
+ }));
+ },
+};
\ No newline at end of file
diff --git a/generators/ra-shadcn/templates/partials/_jhipster-data-provider.jinja b/generators/ra-shadcn/templates/partials/_jhipster-data-provider.jinja
new file mode 100644
index 0000000..9f0906c
--- /dev/null
+++ b/generators/ra-shadcn/templates/partials/_jhipster-data-provider.jinja
@@ -0,0 +1,139 @@
+import {DataProvider, fetchUtils} from "react-admin";
+import {stringify} from "query-string";
+
+function fetchJson(url: any, options: any) {
+ options.user = {
+ authenticated: true,
+ token: localStorage.getItem('token')
+ };
+ console.log('options:' + JSON.stringify(options));
+ return fetchUtils.fetchJson(url, options);
+}
+
+const apiUrl = '/api';
+
+
+export const dataProvider: DataProvider = {
+ getList: async (resource, params) => {
+ console.log('[getList] resource: ' + JSON.stringify(resource));
+ console.log('[getList] params: ' + JSON.stringify(params));
+
+ const {page, perPage} = params.pagination;
+ const {field, order} = params.sort;
+ const query = {
+ sort: `${field},${order}`,
+ range: JSON.stringify([(page - 1) * perPage, page * perPage - 1]),
+ filter: JSON.stringify(params.filter),
+ };
+ const url = `${apiUrl}/${resource}?${stringify(query)}`;
+
+
+ const {json, headers} = await fetchJson(url, {signal: params.signal});
+ const contentRange = headers.get('content-range');
+ return {
+ data: json,
+ total: contentRange ? parseInt(contentRange.split('/').pop(), 10) : json.length,
+ };
+ },
+
+ getOne: async (resource, params) => {
+ console.log('[getOne] resource: ' + JSON.stringify(resource));
+ console.log('[getOne] params: ' + JSON.stringify(params));
+ return fetchJson(`${apiUrl}/${resource}/${params.id}`, {}).then(({json}) => ({
+ data: json,
+ }))
+ },
+
+ getMany: async (resource, params) => {
+ console.log('[getMany] resource: ' + JSON.stringify(resource));
+ console.log('[getMany] params: ' + JSON.stringify(params));
+ const query = {
+ filter: JSON.stringify({id: params.ids}),
+ };
+ const url = `${apiUrl}/${resource}?${stringify(query)}`;
+ return fetchJson(url, {}).then(({json}) => ({data: json}));
+ },
+
+ getManyReference: async (resource, params) => {
+ console.log('[getManyReference] resource: ' + JSON.stringify(resource));
+ console.log('[getManyReference] params: ' + JSON.stringify(params));
+ const {page, perPage} = params.pagination;
+ const {field, order} = params.sort;
+ const query = {
+ sort: `${field},${order}`,
+ range: JSON.stringify([(page - 1) * perPage, page * perPage - 1]),
+ filter: JSON.stringify({
+ ...params.filter,
+ [params.target]: params.id,
+ }),
+ };
+ const url = `${apiUrl}/${resource}?${stringify(query)}`;
+
+ return fetchJson(url).then(({headers, json}) => ({
+ data: json,
+ total: parseInt((headers.get('content-range') || "0").split('/').pop() || '0', 10),
+ }));
+ },
+
+ update: async (resource, params) => {
+ console.log('[update] resource: ' + JSON.stringify(resource));
+ console.log('[update] params: ' + JSON.stringify(params));
+ return fetchJson(`${apiUrl}/${resource}/${params.id}`, {
+ method: 'PUT',
+ body: JSON.stringify(params.data),
+ }).then(({json}) => ({data: json}))
+ },
+
+ updateMany: async (resource, params) => {
+ console.log('[updateMany] resource: ' + JSON.stringify(resource));
+ console.log('[updateMany] params: ' + JSON.stringify(params));
+ const query = {
+ filter: JSON.stringify({id: params.ids}),
+ };
+ return fetchJson(`${apiUrl}/${resource}?${stringify(query)}`, {
+ method: 'PUT',
+ body: JSON.stringify(params.data),
+ }).then(({json}) => ({data: json}));
+ },
+
+ create: async (resource, params) => {
+ console.log('[create] resource: ' + JSON.stringify(resource));
+ console.log('[create] params: ' + JSON.stringify(params));
+ return fetchJson(`${apiUrl}/${resource}`, {
+ method: 'POST',
+ body: JSON.stringify(params.data),
+ }).then(({json}) => ({
+ data: {...params.data, id: json.id} as any,
+ }))
+ },
+
+ delete: async (resource, params) => {
+ console.log('[delete] resource: ' + JSON.stringify(resource));
+ console.log('[delete] params: ' + JSON.stringify(params));
+ return fetchJson(`${apiUrl}/${resource}/${params.id}`, {
+ method: 'DELETE',
+ }).then(({json}) => ({data: json}))
+ },
+
+ deleteMany: async (resource, params) => {
+ console.log('[delete] resource: ' + JSON.stringify(resource));
+ console.log('[delete] params: ' + JSON.stringify(params));
+ const query = {
+ filter: JSON.stringify({id: params.ids}),
+ };
+ let deletePromises = params.ids.map(id => {
+ fetchJson(`${apiUrl}/${resource}/${id}`, {
+ method: 'DELETE',
+ })
+ });
+ return Promise.all(deletePromises)
+ .then((responses) => {
+ // Once all deletions are done, return the ids of the deleted items
+ return {data: params.ids};
+ })
+ .catch(error => {
+ console.error('[deleteMany] Error:', error);
+ throw new Error(error);
+ });
+ }
+};
\ No newline at end of file
diff --git a/generators/ra-shadcn/templates/partials/_rest-data-provider.jinja b/generators/ra-shadcn/templates/partials/_rest-data-provider.jinja
new file mode 100644
index 0000000..a15f584
--- /dev/null
+++ b/generators/ra-shadcn/templates/partials/_rest-data-provider.jinja
@@ -0,0 +1,113 @@
+import {DataProvider, fetchUtils} from "react-admin";
+import {stringify} from "query-string";
+
+function fetchJson(url: any, options: any) {
+ options.user = {
+ authenticated: true,
+ token: localStorage.getItem('token')
+ };
+ console.log('options:'+JSON.stringify(options));
+ return fetchUtils.fetchJson(url, options);
+}
+
+const apiUrl = '/api';
+
+const resource_url = {
+ {% for entity_name,entity in entities | items -%}
+ {%- if not entity.properties -%}{%- continue -%}{%- endif -%}
+ {{ entity.title | plural | snake_case }}: "{{ entity.title | plural | kebab_case }}"{%- if not loop.last -%},{% endif %}
+ {% endfor %}
+};
+
+
+export const dataProvider: DataProvider = {
+ getList: async (resource, params) => {
+ const {page, perPage} = params.pagination;
+ const {field, order} = params.sort;
+ const query = {
+ sort: `${field},${order}`,
+ range: JSON.stringify([(page - 1) * perPage, page * perPage - 1]),
+ filter: JSON.stringify(params.filter),
+ };
+ const url = `${apiUrl}/${resource}?${stringify(query)}`;
+
+
+ const {json, headers} = await fetchJson(url, {signal: params.signal});
+ const contentRange = headers.get('content-range');
+ let return_data = {
+ data: json,
+ total: contentRange ? parseInt(contentRange.split('/').pop(), 10) : json.length,
+ };
+ return return_data;
+ },
+
+ getOne: (resource, params) =>
+ fetchJson(`${apiUrl}/${resource}/${params.id}`,{}).then(({json}) => ({
+ data: json,
+ })),
+
+ getMany: (resource, params) => {
+ const query = {
+ filter: JSON.stringify({id: params.ids}),
+ };
+ const url = `${apiUrl}/${resource}?${stringify(query)}`;
+ return fetchJson(url,{}).then(({json}) => ({data: json}));
+ },
+
+ getManyReference: (resource, params) => {
+ const {page, perPage} = params.pagination;
+ const {field, order} = params.sort;
+ const query = {
+ sort: `${field},${order}`,
+ range: JSON.stringify([(page - 1) * perPage, page * perPage - 1]),
+ filter: JSON.stringify({
+ ...params.filter,
+ [params.target]: params.id,
+ }),
+ };
+ const url = `${apiUrl}/${resource}?${stringify(query)}`;
+
+ return fetchJson(url,{}).then(({headers, json}) => ({
+ data: json,
+ total: parseInt((headers.get('content-range') || "0").split('/').pop() || '0', 10),
+ }));
+ },
+
+ update: (resource, params) =>
+ fetchJson(`${apiUrl}/${resource}/${params.id}`, {
+ method: 'PUT',
+ body: JSON.stringify(params.data),
+ }).then(({json}) => ({data: json})),
+
+ updateMany: (resource, params) => {
+ const query = {
+ filter: JSON.stringify({id: params.ids}),
+ };
+ return fetchJson(`${apiUrl}/${resource}?${stringify(query)}`, {
+ method: 'PUT',
+ body: JSON.stringify(params.data),
+ }).then(({json}) => ({data: json}));
+ },
+
+ create: (resource, params) =>
+ fetchJson(`${apiUrl}/${resource}`, {
+ method: 'POST',
+ body: JSON.stringify(params.data),
+ }).then(({json}) => ({
+ data: {...params.data, id: json.id} as any,
+ })),
+
+ delete: (resource, params) =>
+ fetchJson(`${apiUrl}/${resource}/${params.id}`, {
+ method: 'DELETE',
+ }).then(({json}) => ({data: json})),
+
+ deleteMany: (resource, params) => {
+ const query = {
+ filter: JSON.stringify({id: params.ids}),
+ };
+ return fetchJson(`${apiUrl}/${resource}?${stringify(query)}`, {
+ method: 'DELETE',
+ }).then(({json}) => ({data: json}));
+ }
+};
\ No newline at end of file
diff --git a/generators/ra-shadcn/templates/partials/react-admin-property-validation.jinja b/generators/ra-shadcn/templates/partials/react-admin-property-validation.jinja
new file mode 100644
index 0000000..24729c2
--- /dev/null
+++ b/generators/ra-shadcn/templates/partials/react-admin-property-validation.jinja
@@ -0,0 +1,5 @@
+{%- filter trim -%}
+ {%- if 'required' in entity and name in entity.required -%}
+ validate={[required()]}
+ {%- endif -%}
+{%- endfilter -%}
\ No newline at end of file
diff --git a/generators/ra-shadcn/templates/react-admin-macros.jinja b/generators/ra-shadcn/templates/react-admin-macros.jinja
new file mode 100644
index 0000000..b9e84b6
--- /dev/null
+++ b/generators/ra-shadcn/templates/react-admin-macros.jinja
@@ -0,0 +1,65 @@
+{%- import "_macros.jinja" as macros -%}
+
+{%- macro get_input_type(name, property, required=false) -%}
+{%- filter trim -%}
+{%- set map = [
+ {"type": "string", "format": "uuid", "result": "TextInput"},
+ {"type": "string", "format": "date-time", "result": "DateTimeInput"},
+ {"type": "string", "format": "date", "result": "DateInput"},
+ {"type": "string", "format": "time", "result": "DateInput"},
+ {"type": "string", "result": "TextInput"},
+ {"type": "string", "enum": property.enum, "result": "SelectInput"},
+ {"type": "number", "enum": property.enum, "result": "SelectInput"},
+ {"type": "integer", "enum": property.enum, "result": "SelectInput"},
+ {"type": "boolean", "result": "BooleanInput"},
+ {"type": "integer", "min": 0, "max": 255, "result": "NumberInput"},
+ {"type": "integer", "min": 0, "max": 65535, "result": "NumberInput"},
+ {"type": "integer", "min": 0, "max": 4294967295, "result": "NumberInput"},
+ {"type": "integer", "min": 0, "max": None, "result": "NumberInput"},
+ {"type": "integer", "min": None, "max": 127, "result": "NumberInput"},
+ {"type": "integer", "min": None, "max": 32767, "result": "NumberInput"},
+ {"type": "integer", "min": None, "max": 2147483647, "result": "NumberInput"},
+ {"type": "integer", "min": None, "max": None, "result": "NumberInput"},
+ {"type": "number", "min": -3.40282347, "max": 3.40282347, "result": "NumberInput"},
+ {"type": "number", "min": None, "max": None, "result": "NumberInput"},
+ {"type": "object", "x-relationship": "many-to-one", "result": "ReferenceInput"},
+ {"type": "array", "x-relationship": "one-to-many", "result": "ReferenceArrayInput"},
+ {"type": "array","x-relationship": "many-to-many", "result": "ReferenceArrayInput"}
+] -%}
+{%- set type = map
+ | selectattr('type', 'equalto', property.type)
+ | selectattr('format', 'equalto', property.format)
+ | selectattr('min', 'equalto', property.min)
+ | selectattr('enum', 'equalto', property.enum)
+ | selectattr('max', 'equalto', property.max)
+ | selectattr('x-relationship', 'equalto', property['x-relationship'])
+ | map(attribute='result')
+ | first
+ | default('TextInput')
+-%}
+{{ type }}
+{%- endfilter -%}
+{%- endmacro -%}
+
+{%- macro get_choices(object) -%}
+{%- filter trim -%}
+{%- if 'enum' in object -%}
+choices={[
+{%- for enum in object.enum -%}{ id: '{{ enum }}', name: '{{ enum }}' }{%- if not loop.last -%},{% endif -%}{%- endfor -%}]}
+{% endif -%}
+{%- endfilter -%}
+{%- endmacro -%}
+
+{%- macro get_input_element(name, property) -%}
+{%- filter trim -%}
+<{{ get_input_type(name, property, name in property.required) }} {{ 'readOnly' if 'readOnly' in property }} source="{{ name | camel_case }}"
+{%- set is_relation = macros.relation_is_many_to_many(property)=='true' or macros.relation_is_many_to_one(property=property)=='true' -%}
+{%- if is_relation -%}
+{%- set relation = macros.get_relation(property) -%}
+{{' '}}reference="{{ relation | plural | kebab_case }}" label="{{ relation | pascal_case }}"> {{ get_input_type(name, property, name in property.required) }}>
+{% else -%}
+{{- ' validate={[required()]}' if 'required' in entity and name in entity.required }} {{ get_choices(entity) }} {{ get_choices(property) }}/>
+{% endif -%}
+{%- endfilter -%}
+{%- endmacro -%}
+
diff --git a/generators/ra-shadcn/values.yaml b/generators/ra-shadcn/values.yaml
new file mode 100644
index 0000000..fe0865c
--- /dev/null
+++ b/generators/ra-shadcn/values.yaml
@@ -0,0 +1,3 @@
+application:
+ name: react-admin-example
+outputFolder: "./gen"
\ No newline at end of file
diff --git a/protypo-cli/src/main.rs b/protypo-cli/src/main.rs
index 53d6dd4..80af3fb 100644
--- a/protypo-cli/src/main.rs
+++ b/protypo-cli/src/main.rs
@@ -179,11 +179,8 @@ fn create_new_template(name: &str) {
&format!("{package_dir:?}/template.html"),
"",
);
-
- println!("Template package '{name:?}' has been created!");
}
/// Helper function to create a file with content
fn create_file(path: &str, _content: &str) {
- println!("Created file: {path:?}");
}