Compare commits
	
		
			3 Commits
		
	
	
		
			main
			...
			v0.0.1-sna
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | d5959ca3c3 | ||
| 185ce1fac1 | |||
|   | c11bb6d637 | 
| @@ -19,16 +19,16 @@ jobs: | |||||||
|       - name: 登录到 Gitea Container Registry |       - name: 登录到 Gitea Container Registry | ||||||
|         uses: docker/login-action@v3 |         uses: docker/login-action@v3 | ||||||
|         with: |         with: | ||||||
|           registry: ${{ secrets.REGISTRY_ENDPOINT }} |           registry: ${{ env.GITEA_INSTANCE_URL }} | ||||||
|           username: ${{ secrets.REGISTRY_USERNAME }} |           username: ${{ env.GITEA_ACTOR }} | ||||||
|           password: ${{ secrets.REGISTRY_PASSWORD }} |           password: ${{ secrets.GITHUB_TOKEN }} | ||||||
|        |        | ||||||
|       - name: 提取 Docker 元数据 |       - name: 提取 Docker 元数据 | ||||||
|         id: meta |         id: meta | ||||||
|         uses: docker/metadata-action@v5 |         uses: docker/metadata-action@v5 | ||||||
|         with: |         with: | ||||||
|           images: | |           images: | | ||||||
|             ${{ secrets.REGISTRY_ENDPOINT }}/${{ github.repository_owner }}/litek |             ${{ env.GITEA_INSTANCE_URL }}/${{ env.GITEA_REPOSITORY_OWNER }}/litek | ||||||
|           tags: | |           tags: | | ||||||
|             type=semver,pattern={{version}} |             type=semver,pattern={{version}} | ||||||
|             type=semver,pattern={{major}}.{{minor}} |             type=semver,pattern={{major}}.{{minor}} | ||||||
| @@ -42,8 +42,7 @@ jobs: | |||||||
|           push: true |           push: true | ||||||
|           tags: ${{ steps.meta.outputs.tags }} |           tags: ${{ steps.meta.outputs.tags }} | ||||||
|           labels: ${{ steps.meta.outputs.labels }} |           labels: ${{ steps.meta.outputs.labels }} | ||||||
|           cache-from: type=registry,ref=${{ secrets.REGISTRY_ENDPOINT }}/${{ github.repository_owner }}/litek:buildcache |           cache-from: type=gha | ||||||
|           cache-to: type=registry,ref=${{ secrets.REGISTRY_ENDPOINT }}/${{ github.repository_owner }}/litek:buildcache,mode=max |           cache-to: type=gha,mode=max | ||||||
|           # platforms: linux/amd64,linux/arm64 |           platforms: linux/amd64,linux/arm64 | ||||||
|           platforms: linux/amd64 |  | ||||||
| 
 | 
 | ||||||
| @@ -2,7 +2,7 @@ | |||||||
| FROM node:22-alpine AS builder | FROM node:22-alpine AS builder | ||||||
|  |  | ||||||
| # 安装 pnpm | # 安装 pnpm | ||||||
| RUN npm install -g pnpm | RUN corepack enable && corepack prepare pnpm@latest --activate | ||||||
|  |  | ||||||
| # 设置工作目录 | # 设置工作目录 | ||||||
| WORKDIR /app | WORKDIR /app | ||||||
| @@ -11,8 +11,7 @@ WORKDIR /app | |||||||
| COPY package.json pnpm-lock.yaml ./ | COPY package.json pnpm-lock.yaml ./ | ||||||
|  |  | ||||||
| # 安装依赖 | # 安装依赖 | ||||||
| RUN --mount=type=cache,target=/root/.local/share/pnpm/store \ | RUN pnpm install --frozen-lockfile | ||||||
|     pnpm install --frozen-lockfile |  | ||||||
|  |  | ||||||
| # 复制源代码 | # 复制源代码 | ||||||
| COPY . . | COPY . . | ||||||
|   | |||||||
							
								
								
									
										17
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								package.json
									
									
									
									
									
								
							| @@ -1,35 +1,24 @@ | |||||||
| { | { | ||||||
|   "name": "litek", |   "name": "litek", | ||||||
|   "private": true, |   "private": true, | ||||||
|   "version": "0.0.7", |   "version": "0.0.0", | ||||||
|   "type": "module", |   "type": "module", | ||||||
|   "scripts": { |   "scripts": { | ||||||
|     "dev": "vite", |     "dev": "vite", | ||||||
|     "build": "tsc -b && vite build", |     "build": "tsc -b && vite build", | ||||||
|     "lint": "eslint .", |     "lint": "eslint .", | ||||||
|     "preview": "vite preview", |     "preview": "vite preview" | ||||||
|     "release:patch": "npm version patch && git push --follow-tags", |  | ||||||
|     "release:minor": "npm version minor && git push --follow-tags", |  | ||||||
|     "release:major": "npm version major && git push --follow-tags" |  | ||||||
|   }, |   }, | ||||||
|   "dependencies": { |   "dependencies": { | ||||||
|     "@radix-ui/react-dialog": "^1.1.15", |  | ||||||
|     "@radix-ui/react-separator": "^1.1.7", |  | ||||||
|     "@radix-ui/react-slot": "^1.2.3", |     "@radix-ui/react-slot": "^1.2.3", | ||||||
|     "@radix-ui/react-tooltip": "^1.2.8", |  | ||||||
|     "@tailwindcss/vite": "^4.1.16", |     "@tailwindcss/vite": "^4.1.16", | ||||||
|     "class-variance-authority": "^0.7.1", |     "class-variance-authority": "^0.7.1", | ||||||
|     "clsx": "^2.1.1", |     "clsx": "^2.1.1", | ||||||
|     "lucide-react": "^0.548.0", |     "lucide-react": "^0.548.0", | ||||||
|     "nanoid": "^5.1.6", |  | ||||||
|     "next-themes": "^0.4.6", |  | ||||||
|     "react": "^19.1.1", |     "react": "^19.1.1", | ||||||
|     "react-dom": "^19.1.1", |     "react-dom": "^19.1.1", | ||||||
|     "react-router-dom": "^7.9.4", |  | ||||||
|     "sonner": "^2.0.7", |  | ||||||
|     "tailwind-merge": "^3.3.1", |     "tailwind-merge": "^3.3.1", | ||||||
|     "tailwindcss": "^4.1.16", |     "tailwindcss": "^4.1.16" | ||||||
|     "uuid": "^13.0.0" |  | ||||||
|   }, |   }, | ||||||
|   "devDependencies": { |   "devDependencies": { | ||||||
|     "@eslint/js": "^9.36.0", |     "@eslint/js": "^9.36.0", | ||||||
|   | |||||||
							
								
								
									
										697
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										697
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							| @@ -11,18 +11,9 @@ importers: | |||||||
|  |  | ||||||
|   .: |   .: | ||||||
|     dependencies: |     dependencies: | ||||||
|       '@radix-ui/react-dialog': |  | ||||||
|         specifier: ^1.1.15 |  | ||||||
|         version: 1.1.15(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) |  | ||||||
|       '@radix-ui/react-separator': |  | ||||||
|         specifier: ^1.1.7 |  | ||||||
|         version: 1.1.7(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) |  | ||||||
|       '@radix-ui/react-slot': |       '@radix-ui/react-slot': | ||||||
|         specifier: ^1.2.3 |         specifier: ^1.2.3 | ||||||
|         version: 1.2.3(@types/react@19.2.2)(react@19.2.0) |         version: 1.2.3(@types/react@19.2.2)(react@19.2.0) | ||||||
|       '@radix-ui/react-tooltip': |  | ||||||
|         specifier: ^1.2.8 |  | ||||||
|         version: 1.2.8(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) |  | ||||||
|       '@tailwindcss/vite': |       '@tailwindcss/vite': | ||||||
|         specifier: ^4.1.16 |         specifier: ^4.1.16 | ||||||
|         version: 4.1.16(rolldown-vite@7.1.14(@types/node@24.9.1)(jiti@2.6.1)) |         version: 4.1.16(rolldown-vite@7.1.14(@types/node@24.9.1)(jiti@2.6.1)) | ||||||
| @@ -35,33 +26,18 @@ importers: | |||||||
|       lucide-react: |       lucide-react: | ||||||
|         specifier: ^0.548.0 |         specifier: ^0.548.0 | ||||||
|         version: 0.548.0(react@19.2.0) |         version: 0.548.0(react@19.2.0) | ||||||
|       nanoid: |  | ||||||
|         specifier: ^5.1.6 |  | ||||||
|         version: 5.1.6 |  | ||||||
|       next-themes: |  | ||||||
|         specifier: ^0.4.6 |  | ||||||
|         version: 0.4.6(react-dom@19.2.0(react@19.2.0))(react@19.2.0) |  | ||||||
|       react: |       react: | ||||||
|         specifier: ^19.1.1 |         specifier: ^19.1.1 | ||||||
|         version: 19.2.0 |         version: 19.2.0 | ||||||
|       react-dom: |       react-dom: | ||||||
|         specifier: ^19.1.1 |         specifier: ^19.1.1 | ||||||
|         version: 19.2.0(react@19.2.0) |         version: 19.2.0(react@19.2.0) | ||||||
|       react-router-dom: |  | ||||||
|         specifier: ^7.9.4 |  | ||||||
|         version: 7.9.4(react-dom@19.2.0(react@19.2.0))(react@19.2.0) |  | ||||||
|       sonner: |  | ||||||
|         specifier: ^2.0.7 |  | ||||||
|         version: 2.0.7(react-dom@19.2.0(react@19.2.0))(react@19.2.0) |  | ||||||
|       tailwind-merge: |       tailwind-merge: | ||||||
|         specifier: ^3.3.1 |         specifier: ^3.3.1 | ||||||
|         version: 3.3.1 |         version: 3.3.1 | ||||||
|       tailwindcss: |       tailwindcss: | ||||||
|         specifier: ^4.1.16 |         specifier: ^4.1.16 | ||||||
|         version: 4.1.16 |         version: 4.1.16 | ||||||
|       uuid: |  | ||||||
|         specifier: ^13.0.0 |  | ||||||
|         version: 13.0.0 |  | ||||||
|     devDependencies: |     devDependencies: | ||||||
|       '@eslint/js': |       '@eslint/js': | ||||||
|         specifier: ^9.36.0 |         specifier: ^9.36.0 | ||||||
| @@ -235,21 +211,6 @@ packages: | |||||||
|     resolution: {integrity: sha512-sB5uyeq+dwCWyPi31B2gQlVlo+j5brPlWx4yZBrEaRo/nhdDE8Xke1gsGgtiBdaBTxuTkceLVuVt/pclrasb0A==} |     resolution: {integrity: sha512-sB5uyeq+dwCWyPi31B2gQlVlo+j5brPlWx4yZBrEaRo/nhdDE8Xke1gsGgtiBdaBTxuTkceLVuVt/pclrasb0A==} | ||||||
|     engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} |     engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} | ||||||
|  |  | ||||||
|   '@floating-ui/core@1.7.3': |  | ||||||
|     resolution: {integrity: sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==} |  | ||||||
|  |  | ||||||
|   '@floating-ui/dom@1.7.4': |  | ||||||
|     resolution: {integrity: sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==} |  | ||||||
|  |  | ||||||
|   '@floating-ui/react-dom@2.1.6': |  | ||||||
|     resolution: {integrity: sha512-4JX6rEatQEvlmgU80wZyq9RT96HZJa88q8hp0pBd+LrczeDI4o6uA2M+uvxngVHo4Ihr8uibXxH6+70zhAFrVw==} |  | ||||||
|     peerDependencies: |  | ||||||
|       react: '>=16.8.0' |  | ||||||
|       react-dom: '>=16.8.0' |  | ||||||
|  |  | ||||||
|   '@floating-ui/utils@0.2.10': |  | ||||||
|     resolution: {integrity: sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==} |  | ||||||
|  |  | ||||||
|   '@humanfs/core@0.19.1': |   '@humanfs/core@0.19.1': | ||||||
|     resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} |     resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} | ||||||
|     engines: {node: '>=18.18.0'} |     engines: {node: '>=18.18.0'} | ||||||
| @@ -304,22 +265,6 @@ packages: | |||||||
|   '@oxc-project/types@0.93.0': |   '@oxc-project/types@0.93.0': | ||||||
|     resolution: {integrity: sha512-yNtwmWZIBtJsMr5TEfoZFDxIWV6OdScOpza/f5YxbqUMJk+j6QX3Cf3jgZShGEFYWQJ5j9mJ6jM0tZHu2J9Yrg==} |     resolution: {integrity: sha512-yNtwmWZIBtJsMr5TEfoZFDxIWV6OdScOpza/f5YxbqUMJk+j6QX3Cf3jgZShGEFYWQJ5j9mJ6jM0tZHu2J9Yrg==} | ||||||
|  |  | ||||||
|   '@radix-ui/primitive@1.1.3': |  | ||||||
|     resolution: {integrity: sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==} |  | ||||||
|  |  | ||||||
|   '@radix-ui/react-arrow@1.1.7': |  | ||||||
|     resolution: {integrity: sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==} |  | ||||||
|     peerDependencies: |  | ||||||
|       '@types/react': '*' |  | ||||||
|       '@types/react-dom': '*' |  | ||||||
|       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc |  | ||||||
|       react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc |  | ||||||
|     peerDependenciesMeta: |  | ||||||
|       '@types/react': |  | ||||||
|         optional: true |  | ||||||
|       '@types/react-dom': |  | ||||||
|         optional: true |  | ||||||
|  |  | ||||||
|   '@radix-ui/react-compose-refs@1.1.2': |   '@radix-ui/react-compose-refs@1.1.2': | ||||||
|     resolution: {integrity: sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==} |     resolution: {integrity: sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==} | ||||||
|     peerDependencies: |     peerDependencies: | ||||||
| @@ -329,137 +274,6 @@ packages: | |||||||
|       '@types/react': |       '@types/react': | ||||||
|         optional: true |         optional: true | ||||||
|  |  | ||||||
|   '@radix-ui/react-context@1.1.2': |  | ||||||
|     resolution: {integrity: sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==} |  | ||||||
|     peerDependencies: |  | ||||||
|       '@types/react': '*' |  | ||||||
|       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc |  | ||||||
|     peerDependenciesMeta: |  | ||||||
|       '@types/react': |  | ||||||
|         optional: true |  | ||||||
|  |  | ||||||
|   '@radix-ui/react-dialog@1.1.15': |  | ||||||
|     resolution: {integrity: sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw==} |  | ||||||
|     peerDependencies: |  | ||||||
|       '@types/react': '*' |  | ||||||
|       '@types/react-dom': '*' |  | ||||||
|       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc |  | ||||||
|       react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc |  | ||||||
|     peerDependenciesMeta: |  | ||||||
|       '@types/react': |  | ||||||
|         optional: true |  | ||||||
|       '@types/react-dom': |  | ||||||
|         optional: true |  | ||||||
|  |  | ||||||
|   '@radix-ui/react-dismissable-layer@1.1.11': |  | ||||||
|     resolution: {integrity: sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==} |  | ||||||
|     peerDependencies: |  | ||||||
|       '@types/react': '*' |  | ||||||
|       '@types/react-dom': '*' |  | ||||||
|       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc |  | ||||||
|       react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc |  | ||||||
|     peerDependenciesMeta: |  | ||||||
|       '@types/react': |  | ||||||
|         optional: true |  | ||||||
|       '@types/react-dom': |  | ||||||
|         optional: true |  | ||||||
|  |  | ||||||
|   '@radix-ui/react-focus-guards@1.1.3': |  | ||||||
|     resolution: {integrity: sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw==} |  | ||||||
|     peerDependencies: |  | ||||||
|       '@types/react': '*' |  | ||||||
|       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc |  | ||||||
|     peerDependenciesMeta: |  | ||||||
|       '@types/react': |  | ||||||
|         optional: true |  | ||||||
|  |  | ||||||
|   '@radix-ui/react-focus-scope@1.1.7': |  | ||||||
|     resolution: {integrity: sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==} |  | ||||||
|     peerDependencies: |  | ||||||
|       '@types/react': '*' |  | ||||||
|       '@types/react-dom': '*' |  | ||||||
|       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc |  | ||||||
|       react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc |  | ||||||
|     peerDependenciesMeta: |  | ||||||
|       '@types/react': |  | ||||||
|         optional: true |  | ||||||
|       '@types/react-dom': |  | ||||||
|         optional: true |  | ||||||
|  |  | ||||||
|   '@radix-ui/react-id@1.1.1': |  | ||||||
|     resolution: {integrity: sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==} |  | ||||||
|     peerDependencies: |  | ||||||
|       '@types/react': '*' |  | ||||||
|       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc |  | ||||||
|     peerDependenciesMeta: |  | ||||||
|       '@types/react': |  | ||||||
|         optional: true |  | ||||||
|  |  | ||||||
|   '@radix-ui/react-popper@1.2.8': |  | ||||||
|     resolution: {integrity: sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw==} |  | ||||||
|     peerDependencies: |  | ||||||
|       '@types/react': '*' |  | ||||||
|       '@types/react-dom': '*' |  | ||||||
|       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc |  | ||||||
|       react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc |  | ||||||
|     peerDependenciesMeta: |  | ||||||
|       '@types/react': |  | ||||||
|         optional: true |  | ||||||
|       '@types/react-dom': |  | ||||||
|         optional: true |  | ||||||
|  |  | ||||||
|   '@radix-ui/react-portal@1.1.9': |  | ||||||
|     resolution: {integrity: sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==} |  | ||||||
|     peerDependencies: |  | ||||||
|       '@types/react': '*' |  | ||||||
|       '@types/react-dom': '*' |  | ||||||
|       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc |  | ||||||
|       react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc |  | ||||||
|     peerDependenciesMeta: |  | ||||||
|       '@types/react': |  | ||||||
|         optional: true |  | ||||||
|       '@types/react-dom': |  | ||||||
|         optional: true |  | ||||||
|  |  | ||||||
|   '@radix-ui/react-presence@1.1.5': |  | ||||||
|     resolution: {integrity: sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==} |  | ||||||
|     peerDependencies: |  | ||||||
|       '@types/react': '*' |  | ||||||
|       '@types/react-dom': '*' |  | ||||||
|       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc |  | ||||||
|       react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc |  | ||||||
|     peerDependenciesMeta: |  | ||||||
|       '@types/react': |  | ||||||
|         optional: true |  | ||||||
|       '@types/react-dom': |  | ||||||
|         optional: true |  | ||||||
|  |  | ||||||
|   '@radix-ui/react-primitive@2.1.3': |  | ||||||
|     resolution: {integrity: sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==} |  | ||||||
|     peerDependencies: |  | ||||||
|       '@types/react': '*' |  | ||||||
|       '@types/react-dom': '*' |  | ||||||
|       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc |  | ||||||
|       react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc |  | ||||||
|     peerDependenciesMeta: |  | ||||||
|       '@types/react': |  | ||||||
|         optional: true |  | ||||||
|       '@types/react-dom': |  | ||||||
|         optional: true |  | ||||||
|  |  | ||||||
|   '@radix-ui/react-separator@1.1.7': |  | ||||||
|     resolution: {integrity: sha512-0HEb8R9E8A+jZjvmFCy/J4xhbXy3TV+9XSnGJ3KvTtjlIUy/YQ/p6UYZvi7YbeoeXdyU9+Y3scizK6hkY37baA==} |  | ||||||
|     peerDependencies: |  | ||||||
|       '@types/react': '*' |  | ||||||
|       '@types/react-dom': '*' |  | ||||||
|       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc |  | ||||||
|       react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc |  | ||||||
|     peerDependenciesMeta: |  | ||||||
|       '@types/react': |  | ||||||
|         optional: true |  | ||||||
|       '@types/react-dom': |  | ||||||
|         optional: true |  | ||||||
|  |  | ||||||
|   '@radix-ui/react-slot@1.2.3': |   '@radix-ui/react-slot@1.2.3': | ||||||
|     resolution: {integrity: sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==} |     resolution: {integrity: sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==} | ||||||
|     peerDependencies: |     peerDependencies: | ||||||
| @@ -469,98 +283,6 @@ packages: | |||||||
|       '@types/react': |       '@types/react': | ||||||
|         optional: true |         optional: true | ||||||
|  |  | ||||||
|   '@radix-ui/react-tooltip@1.2.8': |  | ||||||
|     resolution: {integrity: sha512-tY7sVt1yL9ozIxvmbtN5qtmH2krXcBCfjEiCgKGLqunJHvgvZG2Pcl2oQ3kbcZARb1BGEHdkLzcYGO8ynVlieg==} |  | ||||||
|     peerDependencies: |  | ||||||
|       '@types/react': '*' |  | ||||||
|       '@types/react-dom': '*' |  | ||||||
|       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc |  | ||||||
|       react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc |  | ||||||
|     peerDependenciesMeta: |  | ||||||
|       '@types/react': |  | ||||||
|         optional: true |  | ||||||
|       '@types/react-dom': |  | ||||||
|         optional: true |  | ||||||
|  |  | ||||||
|   '@radix-ui/react-use-callback-ref@1.1.1': |  | ||||||
|     resolution: {integrity: sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==} |  | ||||||
|     peerDependencies: |  | ||||||
|       '@types/react': '*' |  | ||||||
|       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc |  | ||||||
|     peerDependenciesMeta: |  | ||||||
|       '@types/react': |  | ||||||
|         optional: true |  | ||||||
|  |  | ||||||
|   '@radix-ui/react-use-controllable-state@1.2.2': |  | ||||||
|     resolution: {integrity: sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==} |  | ||||||
|     peerDependencies: |  | ||||||
|       '@types/react': '*' |  | ||||||
|       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc |  | ||||||
|     peerDependenciesMeta: |  | ||||||
|       '@types/react': |  | ||||||
|         optional: true |  | ||||||
|  |  | ||||||
|   '@radix-ui/react-use-effect-event@0.0.2': |  | ||||||
|     resolution: {integrity: sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==} |  | ||||||
|     peerDependencies: |  | ||||||
|       '@types/react': '*' |  | ||||||
|       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc |  | ||||||
|     peerDependenciesMeta: |  | ||||||
|       '@types/react': |  | ||||||
|         optional: true |  | ||||||
|  |  | ||||||
|   '@radix-ui/react-use-escape-keydown@1.1.1': |  | ||||||
|     resolution: {integrity: sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==} |  | ||||||
|     peerDependencies: |  | ||||||
|       '@types/react': '*' |  | ||||||
|       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc |  | ||||||
|     peerDependenciesMeta: |  | ||||||
|       '@types/react': |  | ||||||
|         optional: true |  | ||||||
|  |  | ||||||
|   '@radix-ui/react-use-layout-effect@1.1.1': |  | ||||||
|     resolution: {integrity: sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==} |  | ||||||
|     peerDependencies: |  | ||||||
|       '@types/react': '*' |  | ||||||
|       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc |  | ||||||
|     peerDependenciesMeta: |  | ||||||
|       '@types/react': |  | ||||||
|         optional: true |  | ||||||
|  |  | ||||||
|   '@radix-ui/react-use-rect@1.1.1': |  | ||||||
|     resolution: {integrity: sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w==} |  | ||||||
|     peerDependencies: |  | ||||||
|       '@types/react': '*' |  | ||||||
|       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc |  | ||||||
|     peerDependenciesMeta: |  | ||||||
|       '@types/react': |  | ||||||
|         optional: true |  | ||||||
|  |  | ||||||
|   '@radix-ui/react-use-size@1.1.1': |  | ||||||
|     resolution: {integrity: sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==} |  | ||||||
|     peerDependencies: |  | ||||||
|       '@types/react': '*' |  | ||||||
|       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc |  | ||||||
|     peerDependenciesMeta: |  | ||||||
|       '@types/react': |  | ||||||
|         optional: true |  | ||||||
|  |  | ||||||
|   '@radix-ui/react-visually-hidden@1.2.3': |  | ||||||
|     resolution: {integrity: sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug==} |  | ||||||
|     peerDependencies: |  | ||||||
|       '@types/react': '*' |  | ||||||
|       '@types/react-dom': '*' |  | ||||||
|       react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc |  | ||||||
|       react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc |  | ||||||
|     peerDependenciesMeta: |  | ||||||
|       '@types/react': |  | ||||||
|         optional: true |  | ||||||
|       '@types/react-dom': |  | ||||||
|         optional: true |  | ||||||
|  |  | ||||||
|   '@radix-ui/rect@1.1.1': |  | ||||||
|     resolution: {integrity: sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==} |  | ||||||
|  |  | ||||||
|   '@rolldown/binding-android-arm64@1.0.0-beta.41': |   '@rolldown/binding-android-arm64@1.0.0-beta.41': | ||||||
|     resolution: {integrity: sha512-Edflndd9lU7JVhVIvJlZhdCj5DkhYDJPIRn4Dx0RUdfc8asP9xHOI5gMd8MesDDx+BJpdIT/uAmVTearteU/mQ==} |     resolution: {integrity: sha512-Edflndd9lU7JVhVIvJlZhdCj5DkhYDJPIRn4Dx0RUdfc8asP9xHOI5gMd8MesDDx+BJpdIT/uAmVTearteU/mQ==} | ||||||
|     engines: {node: ^20.19.0 || >=22.12.0} |     engines: {node: ^20.19.0 || >=22.12.0} | ||||||
| @@ -861,10 +583,6 @@ packages: | |||||||
|   argparse@2.0.1: |   argparse@2.0.1: | ||||||
|     resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} |     resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} | ||||||
|  |  | ||||||
|   aria-hidden@1.2.6: |  | ||||||
|     resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==} |  | ||||||
|     engines: {node: '>=10'} |  | ||||||
|  |  | ||||||
|   balanced-match@1.0.2: |   balanced-match@1.0.2: | ||||||
|     resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} |     resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} | ||||||
|  |  | ||||||
| @@ -918,10 +636,6 @@ packages: | |||||||
|   convert-source-map@2.0.0: |   convert-source-map@2.0.0: | ||||||
|     resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} |     resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} | ||||||
|  |  | ||||||
|   cookie@1.0.2: |  | ||||||
|     resolution: {integrity: sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==} |  | ||||||
|     engines: {node: '>=18'} |  | ||||||
|  |  | ||||||
|   cross-spawn@7.0.6: |   cross-spawn@7.0.6: | ||||||
|     resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} |     resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} | ||||||
|     engines: {node: '>= 8'} |     engines: {node: '>= 8'} | ||||||
| @@ -945,9 +659,6 @@ packages: | |||||||
|     resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} |     resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} | ||||||
|     engines: {node: '>=8'} |     engines: {node: '>=8'} | ||||||
|  |  | ||||||
|   detect-node-es@1.1.0: |  | ||||||
|     resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} |  | ||||||
|  |  | ||||||
|   electron-to-chromium@1.5.240: |   electron-to-chromium@1.5.240: | ||||||
|     resolution: {integrity: sha512-OBwbZjWgrCOH+g6uJsA2/7Twpas2OlepS9uvByJjR2datRDuKGYeD+nP8lBBks2qnB7bGJNHDUx7c/YLaT3QMQ==} |     resolution: {integrity: sha512-OBwbZjWgrCOH+g6uJsA2/7Twpas2OlepS9uvByJjR2datRDuKGYeD+nP8lBBks2qnB7bGJNHDUx7c/YLaT3QMQ==} | ||||||
|  |  | ||||||
| @@ -1069,10 +780,6 @@ packages: | |||||||
|     resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} |     resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} | ||||||
|     engines: {node: '>=6.9.0'} |     engines: {node: '>=6.9.0'} | ||||||
|  |  | ||||||
|   get-nonce@1.0.1: |  | ||||||
|     resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} |  | ||||||
|     engines: {node: '>=6'} |  | ||||||
|  |  | ||||||
|   glob-parent@5.1.2: |   glob-parent@5.1.2: | ||||||
|     resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} |     resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} | ||||||
|     engines: {node: '>= 6'} |     engines: {node: '>= 6'} | ||||||
| @@ -1278,20 +985,9 @@ packages: | |||||||
|     engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} |     engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} | ||||||
|     hasBin: true |     hasBin: true | ||||||
|  |  | ||||||
|   nanoid@5.1.6: |  | ||||||
|     resolution: {integrity: sha512-c7+7RQ+dMB5dPwwCp4ee1/iV/q2P6aK1mTZcfr1BTuVlyW9hJYiMPybJCcnBlQtuSmTIWNeazm/zqNoZSSElBg==} |  | ||||||
|     engines: {node: ^18 || >=20} |  | ||||||
|     hasBin: true |  | ||||||
|  |  | ||||||
|   natural-compare@1.4.0: |   natural-compare@1.4.0: | ||||||
|     resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} |     resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} | ||||||
|  |  | ||||||
|   next-themes@0.4.6: |  | ||||||
|     resolution: {integrity: sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA==} |  | ||||||
|     peerDependencies: |  | ||||||
|       react: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc |  | ||||||
|       react-dom: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc |  | ||||||
|  |  | ||||||
|   node-releases@2.0.26: |   node-releases@2.0.26: | ||||||
|     resolution: {integrity: sha512-S2M9YimhSjBSvYnlr5/+umAnPHE++ODwt5e2Ij6FoX45HA/s4vHdkDx1eax2pAPeAOqu4s9b7ppahsyEFdVqQA==} |     resolution: {integrity: sha512-S2M9YimhSjBSvYnlr5/+umAnPHE++ODwt5e2Ij6FoX45HA/s4vHdkDx1eax2pAPeAOqu4s9b7ppahsyEFdVqQA==} | ||||||
|  |  | ||||||
| @@ -1354,53 +1050,6 @@ packages: | |||||||
|     resolution: {integrity: sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==} |     resolution: {integrity: sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==} | ||||||
|     engines: {node: '>=0.10.0'} |     engines: {node: '>=0.10.0'} | ||||||
|  |  | ||||||
|   react-remove-scroll-bar@2.3.8: |  | ||||||
|     resolution: {integrity: sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==} |  | ||||||
|     engines: {node: '>=10'} |  | ||||||
|     peerDependencies: |  | ||||||
|       '@types/react': '*' |  | ||||||
|       react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 |  | ||||||
|     peerDependenciesMeta: |  | ||||||
|       '@types/react': |  | ||||||
|         optional: true |  | ||||||
|  |  | ||||||
|   react-remove-scroll@2.7.1: |  | ||||||
|     resolution: {integrity: sha512-HpMh8+oahmIdOuS5aFKKY6Pyog+FNaZV/XyJOq7b4YFwsFHe5yYfdbIalI4k3vU2nSDql7YskmUseHsRrJqIPA==} |  | ||||||
|     engines: {node: '>=10'} |  | ||||||
|     peerDependencies: |  | ||||||
|       '@types/react': '*' |  | ||||||
|       react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc |  | ||||||
|     peerDependenciesMeta: |  | ||||||
|       '@types/react': |  | ||||||
|         optional: true |  | ||||||
|  |  | ||||||
|   react-router-dom@7.9.4: |  | ||||||
|     resolution: {integrity: sha512-f30P6bIkmYvnHHa5Gcu65deIXoA2+r3Eb6PJIAddvsT9aGlchMatJ51GgpU470aSqRRbFX22T70yQNUGuW3DfA==} |  | ||||||
|     engines: {node: '>=20.0.0'} |  | ||||||
|     peerDependencies: |  | ||||||
|       react: '>=18' |  | ||||||
|       react-dom: '>=18' |  | ||||||
|  |  | ||||||
|   react-router@7.9.4: |  | ||||||
|     resolution: {integrity: sha512-SD3G8HKviFHg9xj7dNODUKDFgpG4xqD5nhyd0mYoB5iISepuZAvzSr8ywxgxKJ52yRzf/HWtVHc9AWwoTbljvA==} |  | ||||||
|     engines: {node: '>=20.0.0'} |  | ||||||
|     peerDependencies: |  | ||||||
|       react: '>=18' |  | ||||||
|       react-dom: '>=18' |  | ||||||
|     peerDependenciesMeta: |  | ||||||
|       react-dom: |  | ||||||
|         optional: true |  | ||||||
|  |  | ||||||
|   react-style-singleton@2.2.3: |  | ||||||
|     resolution: {integrity: sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==} |  | ||||||
|     engines: {node: '>=10'} |  | ||||||
|     peerDependencies: |  | ||||||
|       '@types/react': '*' |  | ||||||
|       react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc |  | ||||||
|     peerDependenciesMeta: |  | ||||||
|       '@types/react': |  | ||||||
|         optional: true |  | ||||||
|  |  | ||||||
|   react@19.2.0: |   react@19.2.0: | ||||||
|     resolution: {integrity: sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==} |     resolution: {integrity: sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==} | ||||||
|     engines: {node: '>=0.10.0'} |     engines: {node: '>=0.10.0'} | ||||||
| @@ -1473,9 +1122,6 @@ packages: | |||||||
|     engines: {node: '>=10'} |     engines: {node: '>=10'} | ||||||
|     hasBin: true |     hasBin: true | ||||||
|  |  | ||||||
|   set-cookie-parser@2.7.1: |  | ||||||
|     resolution: {integrity: sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==} |  | ||||||
|  |  | ||||||
|   shebang-command@2.0.0: |   shebang-command@2.0.0: | ||||||
|     resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} |     resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} | ||||||
|     engines: {node: '>=8'} |     engines: {node: '>=8'} | ||||||
| @@ -1484,12 +1130,6 @@ packages: | |||||||
|     resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} |     resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} | ||||||
|     engines: {node: '>=8'} |     engines: {node: '>=8'} | ||||||
|  |  | ||||||
|   sonner@2.0.7: |  | ||||||
|     resolution: {integrity: sha512-W6ZN4p58k8aDKA4XPcx2hpIQXBRAgyiWVkYhT7CvK6D3iAu7xjvVyhQHg2/iaKJZ1XVJ4r7XuwGL+WGEK37i9w==} |  | ||||||
|     peerDependencies: |  | ||||||
|       react: ^18.0.0 || ^19.0.0 || ^19.0.0-rc |  | ||||||
|       react-dom: ^18.0.0 || ^19.0.0 || ^19.0.0-rc |  | ||||||
|  |  | ||||||
|   source-map-js@1.2.1: |   source-map-js@1.2.1: | ||||||
|     resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} |     resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} | ||||||
|     engines: {node: '>=0.10.0'} |     engines: {node: '>=0.10.0'} | ||||||
| @@ -1560,30 +1200,6 @@ packages: | |||||||
|   uri-js@4.4.1: |   uri-js@4.4.1: | ||||||
|     resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} |     resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} | ||||||
|  |  | ||||||
|   use-callback-ref@1.3.3: |  | ||||||
|     resolution: {integrity: sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==} |  | ||||||
|     engines: {node: '>=10'} |  | ||||||
|     peerDependencies: |  | ||||||
|       '@types/react': '*' |  | ||||||
|       react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc |  | ||||||
|     peerDependenciesMeta: |  | ||||||
|       '@types/react': |  | ||||||
|         optional: true |  | ||||||
|  |  | ||||||
|   use-sidecar@1.1.3: |  | ||||||
|     resolution: {integrity: sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==} |  | ||||||
|     engines: {node: '>=10'} |  | ||||||
|     peerDependencies: |  | ||||||
|       '@types/react': '*' |  | ||||||
|       react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc |  | ||||||
|     peerDependenciesMeta: |  | ||||||
|       '@types/react': |  | ||||||
|         optional: true |  | ||||||
|  |  | ||||||
|   uuid@13.0.0: |  | ||||||
|     resolution: {integrity: sha512-XQegIaBTVUjSHliKqcnFqYypAd4S+WCYt5NIeRs6w/UAry7z8Y9j5ZwRRL4kzq9U3sD6v+85er9FvkEaBpji2w==} |  | ||||||
|     hasBin: true |  | ||||||
|  |  | ||||||
|   which@2.0.2: |   which@2.0.2: | ||||||
|     resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} |     resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} | ||||||
|     engines: {node: '>= 8'} |     engines: {node: '>= 8'} | ||||||
| @@ -1776,23 +1392,6 @@ snapshots: | |||||||
|       '@eslint/core': 0.16.0 |       '@eslint/core': 0.16.0 | ||||||
|       levn: 0.4.1 |       levn: 0.4.1 | ||||||
|  |  | ||||||
|   '@floating-ui/core@1.7.3': |  | ||||||
|     dependencies: |  | ||||||
|       '@floating-ui/utils': 0.2.10 |  | ||||||
|  |  | ||||||
|   '@floating-ui/dom@1.7.4': |  | ||||||
|     dependencies: |  | ||||||
|       '@floating-ui/core': 1.7.3 |  | ||||||
|       '@floating-ui/utils': 0.2.10 |  | ||||||
|  |  | ||||||
|   '@floating-ui/react-dom@2.1.6(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': |  | ||||||
|     dependencies: |  | ||||||
|       '@floating-ui/dom': 1.7.4 |  | ||||||
|       react: 19.2.0 |  | ||||||
|       react-dom: 19.2.0(react@19.2.0) |  | ||||||
|  |  | ||||||
|   '@floating-ui/utils@0.2.10': {} |  | ||||||
|  |  | ||||||
|   '@humanfs/core@0.19.1': {} |   '@humanfs/core@0.19.1': {} | ||||||
|  |  | ||||||
|   '@humanfs/node@0.16.7': |   '@humanfs/node@0.16.7': | ||||||
| @@ -1846,144 +1445,12 @@ snapshots: | |||||||
|  |  | ||||||
|   '@oxc-project/types@0.93.0': {} |   '@oxc-project/types@0.93.0': {} | ||||||
|  |  | ||||||
|   '@radix-ui/primitive@1.1.3': {} |  | ||||||
|  |  | ||||||
|   '@radix-ui/react-arrow@1.1.7(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': |  | ||||||
|     dependencies: |  | ||||||
|       '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) |  | ||||||
|       react: 19.2.0 |  | ||||||
|       react-dom: 19.2.0(react@19.2.0) |  | ||||||
|     optionalDependencies: |  | ||||||
|       '@types/react': 19.2.2 |  | ||||||
|       '@types/react-dom': 19.2.2(@types/react@19.2.2) |  | ||||||
|  |  | ||||||
|   '@radix-ui/react-compose-refs@1.1.2(@types/react@19.2.2)(react@19.2.0)': |   '@radix-ui/react-compose-refs@1.1.2(@types/react@19.2.2)(react@19.2.0)': | ||||||
|     dependencies: |     dependencies: | ||||||
|       react: 19.2.0 |       react: 19.2.0 | ||||||
|     optionalDependencies: |     optionalDependencies: | ||||||
|       '@types/react': 19.2.2 |       '@types/react': 19.2.2 | ||||||
|  |  | ||||||
|   '@radix-ui/react-context@1.1.2(@types/react@19.2.2)(react@19.2.0)': |  | ||||||
|     dependencies: |  | ||||||
|       react: 19.2.0 |  | ||||||
|     optionalDependencies: |  | ||||||
|       '@types/react': 19.2.2 |  | ||||||
|  |  | ||||||
|   '@radix-ui/react-dialog@1.1.15(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': |  | ||||||
|     dependencies: |  | ||||||
|       '@radix-ui/primitive': 1.1.3 |  | ||||||
|       '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.2)(react@19.2.0) |  | ||||||
|       '@radix-ui/react-context': 1.1.2(@types/react@19.2.2)(react@19.2.0) |  | ||||||
|       '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) |  | ||||||
|       '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.2)(react@19.2.0) |  | ||||||
|       '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) |  | ||||||
|       '@radix-ui/react-id': 1.1.1(@types/react@19.2.2)(react@19.2.0) |  | ||||||
|       '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) |  | ||||||
|       '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) |  | ||||||
|       '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) |  | ||||||
|       '@radix-ui/react-slot': 1.2.3(@types/react@19.2.2)(react@19.2.0) |  | ||||||
|       '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.2)(react@19.2.0) |  | ||||||
|       aria-hidden: 1.2.6 |  | ||||||
|       react: 19.2.0 |  | ||||||
|       react-dom: 19.2.0(react@19.2.0) |  | ||||||
|       react-remove-scroll: 2.7.1(@types/react@19.2.2)(react@19.2.0) |  | ||||||
|     optionalDependencies: |  | ||||||
|       '@types/react': 19.2.2 |  | ||||||
|       '@types/react-dom': 19.2.2(@types/react@19.2.2) |  | ||||||
|  |  | ||||||
|   '@radix-ui/react-dismissable-layer@1.1.11(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': |  | ||||||
|     dependencies: |  | ||||||
|       '@radix-ui/primitive': 1.1.3 |  | ||||||
|       '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.2)(react@19.2.0) |  | ||||||
|       '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) |  | ||||||
|       '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.2)(react@19.2.0) |  | ||||||
|       '@radix-ui/react-use-escape-keydown': 1.1.1(@types/react@19.2.2)(react@19.2.0) |  | ||||||
|       react: 19.2.0 |  | ||||||
|       react-dom: 19.2.0(react@19.2.0) |  | ||||||
|     optionalDependencies: |  | ||||||
|       '@types/react': 19.2.2 |  | ||||||
|       '@types/react-dom': 19.2.2(@types/react@19.2.2) |  | ||||||
|  |  | ||||||
|   '@radix-ui/react-focus-guards@1.1.3(@types/react@19.2.2)(react@19.2.0)': |  | ||||||
|     dependencies: |  | ||||||
|       react: 19.2.0 |  | ||||||
|     optionalDependencies: |  | ||||||
|       '@types/react': 19.2.2 |  | ||||||
|  |  | ||||||
|   '@radix-ui/react-focus-scope@1.1.7(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': |  | ||||||
|     dependencies: |  | ||||||
|       '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.2)(react@19.2.0) |  | ||||||
|       '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) |  | ||||||
|       '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.2)(react@19.2.0) |  | ||||||
|       react: 19.2.0 |  | ||||||
|       react-dom: 19.2.0(react@19.2.0) |  | ||||||
|     optionalDependencies: |  | ||||||
|       '@types/react': 19.2.2 |  | ||||||
|       '@types/react-dom': 19.2.2(@types/react@19.2.2) |  | ||||||
|  |  | ||||||
|   '@radix-ui/react-id@1.1.1(@types/react@19.2.2)(react@19.2.0)': |  | ||||||
|     dependencies: |  | ||||||
|       '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.2)(react@19.2.0) |  | ||||||
|       react: 19.2.0 |  | ||||||
|     optionalDependencies: |  | ||||||
|       '@types/react': 19.2.2 |  | ||||||
|  |  | ||||||
|   '@radix-ui/react-popper@1.2.8(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': |  | ||||||
|     dependencies: |  | ||||||
|       '@floating-ui/react-dom': 2.1.6(react-dom@19.2.0(react@19.2.0))(react@19.2.0) |  | ||||||
|       '@radix-ui/react-arrow': 1.1.7(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) |  | ||||||
|       '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.2)(react@19.2.0) |  | ||||||
|       '@radix-ui/react-context': 1.1.2(@types/react@19.2.2)(react@19.2.0) |  | ||||||
|       '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) |  | ||||||
|       '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.2)(react@19.2.0) |  | ||||||
|       '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.2)(react@19.2.0) |  | ||||||
|       '@radix-ui/react-use-rect': 1.1.1(@types/react@19.2.2)(react@19.2.0) |  | ||||||
|       '@radix-ui/react-use-size': 1.1.1(@types/react@19.2.2)(react@19.2.0) |  | ||||||
|       '@radix-ui/rect': 1.1.1 |  | ||||||
|       react: 19.2.0 |  | ||||||
|       react-dom: 19.2.0(react@19.2.0) |  | ||||||
|     optionalDependencies: |  | ||||||
|       '@types/react': 19.2.2 |  | ||||||
|       '@types/react-dom': 19.2.2(@types/react@19.2.2) |  | ||||||
|  |  | ||||||
|   '@radix-ui/react-portal@1.1.9(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': |  | ||||||
|     dependencies: |  | ||||||
|       '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) |  | ||||||
|       '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.2)(react@19.2.0) |  | ||||||
|       react: 19.2.0 |  | ||||||
|       react-dom: 19.2.0(react@19.2.0) |  | ||||||
|     optionalDependencies: |  | ||||||
|       '@types/react': 19.2.2 |  | ||||||
|       '@types/react-dom': 19.2.2(@types/react@19.2.2) |  | ||||||
|  |  | ||||||
|   '@radix-ui/react-presence@1.1.5(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': |  | ||||||
|     dependencies: |  | ||||||
|       '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.2)(react@19.2.0) |  | ||||||
|       '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.2)(react@19.2.0) |  | ||||||
|       react: 19.2.0 |  | ||||||
|       react-dom: 19.2.0(react@19.2.0) |  | ||||||
|     optionalDependencies: |  | ||||||
|       '@types/react': 19.2.2 |  | ||||||
|       '@types/react-dom': 19.2.2(@types/react@19.2.2) |  | ||||||
|  |  | ||||||
|   '@radix-ui/react-primitive@2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': |  | ||||||
|     dependencies: |  | ||||||
|       '@radix-ui/react-slot': 1.2.3(@types/react@19.2.2)(react@19.2.0) |  | ||||||
|       react: 19.2.0 |  | ||||||
|       react-dom: 19.2.0(react@19.2.0) |  | ||||||
|     optionalDependencies: |  | ||||||
|       '@types/react': 19.2.2 |  | ||||||
|       '@types/react-dom': 19.2.2(@types/react@19.2.2) |  | ||||||
|  |  | ||||||
|   '@radix-ui/react-separator@1.1.7(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': |  | ||||||
|     dependencies: |  | ||||||
|       '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) |  | ||||||
|       react: 19.2.0 |  | ||||||
|       react-dom: 19.2.0(react@19.2.0) |  | ||||||
|     optionalDependencies: |  | ||||||
|       '@types/react': 19.2.2 |  | ||||||
|       '@types/react-dom': 19.2.2(@types/react@19.2.2) |  | ||||||
|  |  | ||||||
|   '@radix-ui/react-slot@1.2.3(@types/react@19.2.2)(react@19.2.0)': |   '@radix-ui/react-slot@1.2.3(@types/react@19.2.2)(react@19.2.0)': | ||||||
|     dependencies: |     dependencies: | ||||||
|       '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.2)(react@19.2.0) |       '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.2)(react@19.2.0) | ||||||
| @@ -1991,85 +1458,6 @@ snapshots: | |||||||
|     optionalDependencies: |     optionalDependencies: | ||||||
|       '@types/react': 19.2.2 |       '@types/react': 19.2.2 | ||||||
|  |  | ||||||
|   '@radix-ui/react-tooltip@1.2.8(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': |  | ||||||
|     dependencies: |  | ||||||
|       '@radix-ui/primitive': 1.1.3 |  | ||||||
|       '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.2)(react@19.2.0) |  | ||||||
|       '@radix-ui/react-context': 1.1.2(@types/react@19.2.2)(react@19.2.0) |  | ||||||
|       '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) |  | ||||||
|       '@radix-ui/react-id': 1.1.1(@types/react@19.2.2)(react@19.2.0) |  | ||||||
|       '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) |  | ||||||
|       '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) |  | ||||||
|       '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) |  | ||||||
|       '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) |  | ||||||
|       '@radix-ui/react-slot': 1.2.3(@types/react@19.2.2)(react@19.2.0) |  | ||||||
|       '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.2)(react@19.2.0) |  | ||||||
|       '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) |  | ||||||
|       react: 19.2.0 |  | ||||||
|       react-dom: 19.2.0(react@19.2.0) |  | ||||||
|     optionalDependencies: |  | ||||||
|       '@types/react': 19.2.2 |  | ||||||
|       '@types/react-dom': 19.2.2(@types/react@19.2.2) |  | ||||||
|  |  | ||||||
|   '@radix-ui/react-use-callback-ref@1.1.1(@types/react@19.2.2)(react@19.2.0)': |  | ||||||
|     dependencies: |  | ||||||
|       react: 19.2.0 |  | ||||||
|     optionalDependencies: |  | ||||||
|       '@types/react': 19.2.2 |  | ||||||
|  |  | ||||||
|   '@radix-ui/react-use-controllable-state@1.2.2(@types/react@19.2.2)(react@19.2.0)': |  | ||||||
|     dependencies: |  | ||||||
|       '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.2.2)(react@19.2.0) |  | ||||||
|       '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.2)(react@19.2.0) |  | ||||||
|       react: 19.2.0 |  | ||||||
|     optionalDependencies: |  | ||||||
|       '@types/react': 19.2.2 |  | ||||||
|  |  | ||||||
|   '@radix-ui/react-use-effect-event@0.0.2(@types/react@19.2.2)(react@19.2.0)': |  | ||||||
|     dependencies: |  | ||||||
|       '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.2)(react@19.2.0) |  | ||||||
|       react: 19.2.0 |  | ||||||
|     optionalDependencies: |  | ||||||
|       '@types/react': 19.2.2 |  | ||||||
|  |  | ||||||
|   '@radix-ui/react-use-escape-keydown@1.1.1(@types/react@19.2.2)(react@19.2.0)': |  | ||||||
|     dependencies: |  | ||||||
|       '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.2)(react@19.2.0) |  | ||||||
|       react: 19.2.0 |  | ||||||
|     optionalDependencies: |  | ||||||
|       '@types/react': 19.2.2 |  | ||||||
|  |  | ||||||
|   '@radix-ui/react-use-layout-effect@1.1.1(@types/react@19.2.2)(react@19.2.0)': |  | ||||||
|     dependencies: |  | ||||||
|       react: 19.2.0 |  | ||||||
|     optionalDependencies: |  | ||||||
|       '@types/react': 19.2.2 |  | ||||||
|  |  | ||||||
|   '@radix-ui/react-use-rect@1.1.1(@types/react@19.2.2)(react@19.2.0)': |  | ||||||
|     dependencies: |  | ||||||
|       '@radix-ui/rect': 1.1.1 |  | ||||||
|       react: 19.2.0 |  | ||||||
|     optionalDependencies: |  | ||||||
|       '@types/react': 19.2.2 |  | ||||||
|  |  | ||||||
|   '@radix-ui/react-use-size@1.1.1(@types/react@19.2.2)(react@19.2.0)': |  | ||||||
|     dependencies: |  | ||||||
|       '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.2)(react@19.2.0) |  | ||||||
|       react: 19.2.0 |  | ||||||
|     optionalDependencies: |  | ||||||
|       '@types/react': 19.2.2 |  | ||||||
|  |  | ||||||
|   '@radix-ui/react-visually-hidden@1.2.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': |  | ||||||
|     dependencies: |  | ||||||
|       '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) |  | ||||||
|       react: 19.2.0 |  | ||||||
|       react-dom: 19.2.0(react@19.2.0) |  | ||||||
|     optionalDependencies: |  | ||||||
|       '@types/react': 19.2.2 |  | ||||||
|       '@types/react-dom': 19.2.2(@types/react@19.2.2) |  | ||||||
|  |  | ||||||
|   '@radix-ui/rect@1.1.1': {} |  | ||||||
|  |  | ||||||
|   '@rolldown/binding-android-arm64@1.0.0-beta.41': |   '@rolldown/binding-android-arm64@1.0.0-beta.41': | ||||||
|     optional: true |     optional: true | ||||||
|  |  | ||||||
| @@ -2354,10 +1742,6 @@ snapshots: | |||||||
|  |  | ||||||
|   argparse@2.0.1: {} |   argparse@2.0.1: {} | ||||||
|  |  | ||||||
|   aria-hidden@1.2.6: |  | ||||||
|     dependencies: |  | ||||||
|       tslib: 2.8.1 |  | ||||||
|  |  | ||||||
|   balanced-match@1.0.2: {} |   balanced-match@1.0.2: {} | ||||||
|  |  | ||||||
|   baseline-browser-mapping@2.8.20: {} |   baseline-browser-mapping@2.8.20: {} | ||||||
| @@ -2408,8 +1792,6 @@ snapshots: | |||||||
|  |  | ||||||
|   convert-source-map@2.0.0: {} |   convert-source-map@2.0.0: {} | ||||||
|  |  | ||||||
|   cookie@1.0.2: {} |  | ||||||
|  |  | ||||||
|   cross-spawn@7.0.6: |   cross-spawn@7.0.6: | ||||||
|     dependencies: |     dependencies: | ||||||
|       path-key: 3.1.1 |       path-key: 3.1.1 | ||||||
| @@ -2426,8 +1808,6 @@ snapshots: | |||||||
|  |  | ||||||
|   detect-libc@2.1.2: {} |   detect-libc@2.1.2: {} | ||||||
|  |  | ||||||
|   detect-node-es@1.1.0: {} |  | ||||||
|  |  | ||||||
|   electron-to-chromium@1.5.240: {} |   electron-to-chromium@1.5.240: {} | ||||||
|  |  | ||||||
|   enhanced-resolve@5.18.3: |   enhanced-resolve@5.18.3: | ||||||
| @@ -2562,8 +1942,6 @@ snapshots: | |||||||
|  |  | ||||||
|   gensync@1.0.0-beta.2: {} |   gensync@1.0.0-beta.2: {} | ||||||
|  |  | ||||||
|   get-nonce@1.0.1: {} |  | ||||||
|  |  | ||||||
|   glob-parent@5.1.2: |   glob-parent@5.1.2: | ||||||
|     dependencies: |     dependencies: | ||||||
|       is-glob: 4.0.3 |       is-glob: 4.0.3 | ||||||
| @@ -2716,15 +2094,8 @@ snapshots: | |||||||
|  |  | ||||||
|   nanoid@3.3.11: {} |   nanoid@3.3.11: {} | ||||||
|  |  | ||||||
|   nanoid@5.1.6: {} |  | ||||||
|  |  | ||||||
|   natural-compare@1.4.0: {} |   natural-compare@1.4.0: {} | ||||||
|  |  | ||||||
|   next-themes@0.4.6(react-dom@19.2.0(react@19.2.0))(react@19.2.0): |  | ||||||
|     dependencies: |  | ||||||
|       react: 19.2.0 |  | ||||||
|       react-dom: 19.2.0(react@19.2.0) |  | ||||||
|  |  | ||||||
|   node-releases@2.0.26: {} |   node-releases@2.0.26: {} | ||||||
|  |  | ||||||
|   optionator@0.9.4: |   optionator@0.9.4: | ||||||
| @@ -2777,47 +2148,6 @@ snapshots: | |||||||
|  |  | ||||||
|   react-refresh@0.18.0: {} |   react-refresh@0.18.0: {} | ||||||
|  |  | ||||||
|   react-remove-scroll-bar@2.3.8(@types/react@19.2.2)(react@19.2.0): |  | ||||||
|     dependencies: |  | ||||||
|       react: 19.2.0 |  | ||||||
|       react-style-singleton: 2.2.3(@types/react@19.2.2)(react@19.2.0) |  | ||||||
|       tslib: 2.8.1 |  | ||||||
|     optionalDependencies: |  | ||||||
|       '@types/react': 19.2.2 |  | ||||||
|  |  | ||||||
|   react-remove-scroll@2.7.1(@types/react@19.2.2)(react@19.2.0): |  | ||||||
|     dependencies: |  | ||||||
|       react: 19.2.0 |  | ||||||
|       react-remove-scroll-bar: 2.3.8(@types/react@19.2.2)(react@19.2.0) |  | ||||||
|       react-style-singleton: 2.2.3(@types/react@19.2.2)(react@19.2.0) |  | ||||||
|       tslib: 2.8.1 |  | ||||||
|       use-callback-ref: 1.3.3(@types/react@19.2.2)(react@19.2.0) |  | ||||||
|       use-sidecar: 1.1.3(@types/react@19.2.2)(react@19.2.0) |  | ||||||
|     optionalDependencies: |  | ||||||
|       '@types/react': 19.2.2 |  | ||||||
|  |  | ||||||
|   react-router-dom@7.9.4(react-dom@19.2.0(react@19.2.0))(react@19.2.0): |  | ||||||
|     dependencies: |  | ||||||
|       react: 19.2.0 |  | ||||||
|       react-dom: 19.2.0(react@19.2.0) |  | ||||||
|       react-router: 7.9.4(react-dom@19.2.0(react@19.2.0))(react@19.2.0) |  | ||||||
|  |  | ||||||
|   react-router@7.9.4(react-dom@19.2.0(react@19.2.0))(react@19.2.0): |  | ||||||
|     dependencies: |  | ||||||
|       cookie: 1.0.2 |  | ||||||
|       react: 19.2.0 |  | ||||||
|       set-cookie-parser: 2.7.1 |  | ||||||
|     optionalDependencies: |  | ||||||
|       react-dom: 19.2.0(react@19.2.0) |  | ||||||
|  |  | ||||||
|   react-style-singleton@2.2.3(@types/react@19.2.2)(react@19.2.0): |  | ||||||
|     dependencies: |  | ||||||
|       get-nonce: 1.0.1 |  | ||||||
|       react: 19.2.0 |  | ||||||
|       tslib: 2.8.1 |  | ||||||
|     optionalDependencies: |  | ||||||
|       '@types/react': 19.2.2 |  | ||||||
|  |  | ||||||
|   react@19.2.0: {} |   react@19.2.0: {} | ||||||
|  |  | ||||||
|   resolve-from@4.0.0: {} |   resolve-from@4.0.0: {} | ||||||
| @@ -2869,19 +2199,12 @@ snapshots: | |||||||
|  |  | ||||||
|   semver@7.7.3: {} |   semver@7.7.3: {} | ||||||
|  |  | ||||||
|   set-cookie-parser@2.7.1: {} |  | ||||||
|  |  | ||||||
|   shebang-command@2.0.0: |   shebang-command@2.0.0: | ||||||
|     dependencies: |     dependencies: | ||||||
|       shebang-regex: 3.0.0 |       shebang-regex: 3.0.0 | ||||||
|  |  | ||||||
|   shebang-regex@3.0.0: {} |   shebang-regex@3.0.0: {} | ||||||
|  |  | ||||||
|   sonner@2.0.7(react-dom@19.2.0(react@19.2.0))(react@19.2.0): |  | ||||||
|     dependencies: |  | ||||||
|       react: 19.2.0 |  | ||||||
|       react-dom: 19.2.0(react@19.2.0) |  | ||||||
|  |  | ||||||
|   source-map-js@1.2.1: {} |   source-map-js@1.2.1: {} | ||||||
|  |  | ||||||
|   strip-json-comments@3.1.1: {} |   strip-json-comments@3.1.1: {} | ||||||
| @@ -2909,7 +2232,8 @@ snapshots: | |||||||
|     dependencies: |     dependencies: | ||||||
|       typescript: 5.9.3 |       typescript: 5.9.3 | ||||||
|  |  | ||||||
|   tslib@2.8.1: {} |   tslib@2.8.1: | ||||||
|  |     optional: true | ||||||
|  |  | ||||||
|   tw-animate-css@1.4.0: {} |   tw-animate-css@1.4.0: {} | ||||||
|  |  | ||||||
| @@ -2942,23 +2266,6 @@ snapshots: | |||||||
|     dependencies: |     dependencies: | ||||||
|       punycode: 2.3.1 |       punycode: 2.3.1 | ||||||
|  |  | ||||||
|   use-callback-ref@1.3.3(@types/react@19.2.2)(react@19.2.0): |  | ||||||
|     dependencies: |  | ||||||
|       react: 19.2.0 |  | ||||||
|       tslib: 2.8.1 |  | ||||||
|     optionalDependencies: |  | ||||||
|       '@types/react': 19.2.2 |  | ||||||
|  |  | ||||||
|   use-sidecar@1.1.3(@types/react@19.2.2)(react@19.2.0): |  | ||||||
|     dependencies: |  | ||||||
|       detect-node-es: 1.1.0 |  | ||||||
|       react: 19.2.0 |  | ||||||
|       tslib: 2.8.1 |  | ||||||
|     optionalDependencies: |  | ||||||
|       '@types/react': 19.2.2 |  | ||||||
|  |  | ||||||
|   uuid@13.0.0: {} |  | ||||||
|  |  | ||||||
|   which@2.0.2: |   which@2.0.2: | ||||||
|     dependencies: |     dependencies: | ||||||
|       isexe: 2.0.0 |       isexe: 2.0.0 | ||||||
|   | |||||||
| @@ -1,35 +0,0 @@ | |||||||
| import { Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarMenuButton, SidebarMenuItem } from "@/components/ui/sidebar"; |  | ||||||
| import { tools } from "@/components/tool"; |  | ||||||
| import { Link } from "react-router-dom"; |  | ||||||
|  |  | ||||||
| export const AppSidebar = () => ( |  | ||||||
|   <Sidebar> |  | ||||||
|     <SidebarHeader className="text-2xl font-bold flex justify-center items-center"> |  | ||||||
|       Lite Kit |  | ||||||
|     </SidebarHeader> |  | ||||||
|     <SidebarContent> |  | ||||||
|       <SidebarGroup> |  | ||||||
|         <SidebarGroupLabel> |  | ||||||
|           Tools |  | ||||||
|         </SidebarGroupLabel> |  | ||||||
|         <SidebarGroupContent> |  | ||||||
|           { |  | ||||||
|             tools.map((tool) => ( |  | ||||||
|               <SidebarMenuItem key={tool.name}> |  | ||||||
|                 <SidebarMenuButton asChild> |  | ||||||
|                   <Link to={`/tool/${tool.path}`} title={tool.description}> |  | ||||||
|                     {tool.icon} |  | ||||||
|                     {tool.name} |  | ||||||
|                   </Link> |  | ||||||
|                 </SidebarMenuButton> |  | ||||||
|               </SidebarMenuItem> |  | ||||||
|             )) |  | ||||||
|           } |  | ||||||
|         </SidebarGroupContent> |  | ||||||
|       </SidebarGroup> |  | ||||||
|     </SidebarContent> |  | ||||||
|     <SidebarFooter> |  | ||||||
|       <a href="mailto:litek@mail.typist.cc">contact us</a> |  | ||||||
|     </SidebarFooter> |  | ||||||
|   </Sidebar> |  | ||||||
| ) |  | ||||||
| @@ -1,70 +0,0 @@ | |||||||
| import { useState, type FC } from "react"; |  | ||||||
| import { Textarea } from "@/components/ui/textarea"; |  | ||||||
| import { Button } from "@/components/ui/button"; |  | ||||||
| import { toast } from "sonner"; |  | ||||||
| import { ArrowLeftIcon, ArrowRightIcon } from "lucide-react"; |  | ||||||
|  |  | ||||||
| const Tool: FC = () => { |  | ||||||
|   const [decoded, setDecoded] = useState<string>(""); |  | ||||||
|   const [encoded, setEncoded] = useState<string>(""); |  | ||||||
|  |  | ||||||
|   const encode = () => { |  | ||||||
|     try { |  | ||||||
|       const encoded64 = btoa(decoded); |  | ||||||
|       setEncoded(encoded64); |  | ||||||
|       setDecoded(""); |  | ||||||
|       toast.success("encoded successfully"); |  | ||||||
|     } catch (error: unknown) { |  | ||||||
|       if (error instanceof Error) { |  | ||||||
|         toast.error(error.message); |  | ||||||
|       } else { |  | ||||||
|         toast.error("encoding failed"); |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   }; |  | ||||||
|  |  | ||||||
|   const decode = () => { |  | ||||||
|     try { |  | ||||||
|       const decoded64 = atob(encoded); |  | ||||||
|       setDecoded(decoded64); |  | ||||||
|       setEncoded(""); |  | ||||||
|       toast.success("decoded successfully"); |  | ||||||
|     } catch (error: unknown) { |  | ||||||
|       if (error instanceof Error) { |  | ||||||
|         toast.error(error.message); |  | ||||||
|       } else { |  | ||||||
|         toast.error("decoding failed"); |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   }; |  | ||||||
|  |  | ||||||
|   return ( |  | ||||||
|     <div className="h-[50vh] flex flex-row gap-4 pt-[20vh]"> |  | ||||||
|       <Textarea |  | ||||||
|         className="flex-1 resize-none" |  | ||||||
|         placeholder="Enter the original text" |  | ||||||
|         value={decoded} |  | ||||||
|         onChange={(e) => setDecoded(e.target.value)} |  | ||||||
|       /> |  | ||||||
|       <div className="flex flex-col gap-2 justify-center"> |  | ||||||
|         <Button onClick={encode}> |  | ||||||
|           <ArrowRightIcon className="size-4" /> |  | ||||||
|           Encode |  | ||||||
|         </Button> |  | ||||||
|         <Button onClick={decode}> |  | ||||||
|           <ArrowLeftIcon className="size-4" /> |  | ||||||
|           Decode |  | ||||||
|         </Button> |  | ||||||
|       </div> |  | ||||||
|       <Textarea |  | ||||||
|         className="flex-1 resize-none" |  | ||||||
|         placeholder="Enter the Base64 encoded text" |  | ||||||
|         value={encoded} |  | ||||||
|         onChange={(e) => setEncoded(e.target.value)} |  | ||||||
|       /> |  | ||||||
|     </div> |  | ||||||
|   ); |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| export default Tool; |  | ||||||
|  |  | ||||||
| @@ -1,38 +0,0 @@ | |||||||
| import type { ReactNode } from 'react'; |  | ||||||
| import { FileJson, Hash, Binary } from 'lucide-react' |  | ||||||
|  |  | ||||||
| import UUID from './uuid' |  | ||||||
| import JSON from './json' |  | ||||||
| import Base64 from './base64' |  | ||||||
|  |  | ||||||
| export interface Tool { |  | ||||||
|   path: string; |  | ||||||
|   name: string; |  | ||||||
|   icon: ReactNode; |  | ||||||
|   description: string; |  | ||||||
|   component: ReactNode; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| export const tools: Tool[] = [ |  | ||||||
|   { |  | ||||||
|     path: "uuid", |  | ||||||
|     name: "UUID Generator", |  | ||||||
|     description: "Generate a UUID", |  | ||||||
|     icon: <Hash />, |  | ||||||
|     component: <UUID />, |  | ||||||
|   }, |  | ||||||
|   { |  | ||||||
|     path: "json", |  | ||||||
|     name: "JSON Formatter", |  | ||||||
|     description: "Format and validate JSON", |  | ||||||
|     icon: <FileJson />, |  | ||||||
|     component: <JSON />, |  | ||||||
|   }, |  | ||||||
|   { |  | ||||||
|     path: "base64", |  | ||||||
|     name: "Base64 Encoder/Decoder", |  | ||||||
|     description: "Encode and decode Base64", |  | ||||||
|     icon: <Binary />, |  | ||||||
|     component: <Base64 />, |  | ||||||
|   } |  | ||||||
| ]; |  | ||||||
| @@ -1,48 +0,0 @@ | |||||||
| import { useState, type FC } from "react"; |  | ||||||
| import { Textarea } from "@/components/ui/textarea"; |  | ||||||
| import { Button } from "@/components/ui/button"; |  | ||||||
| import { toast } from "sonner"; |  | ||||||
|  |  | ||||||
| const Tool: FC = () => { |  | ||||||
|   const [json, setJson] = useState<string>(""); |  | ||||||
|  |  | ||||||
|   const validateJson = () => { |  | ||||||
|     try { |  | ||||||
|       JSON.parse(json); |  | ||||||
|       return true; |  | ||||||
|     } catch (error: unknown) { |  | ||||||
|       if (error instanceof Error) { |  | ||||||
|         toast.error(error.message); |  | ||||||
|       } else { |  | ||||||
|         toast.error("Invalid JSON"); |  | ||||||
|       } |  | ||||||
|       return false; |  | ||||||
|     } |  | ||||||
|   }; |  | ||||||
|  |  | ||||||
|   const minifyJson = () => { |  | ||||||
|     if (!validateJson()) return; |  | ||||||
|     const formattedJson = JSON.stringify(JSON.parse(json), null, 0); |  | ||||||
|     setJson(formattedJson); |  | ||||||
|     toast.success("Minified successfully"); |  | ||||||
|   }; |  | ||||||
|  |  | ||||||
|   const prettifyJson = () => { |  | ||||||
|     if (!validateJson()) return; |  | ||||||
|     const formattedJson = JSON.stringify(JSON.parse(json), null, 2); |  | ||||||
|     setJson(formattedJson); |  | ||||||
|     toast.success("JSON prettified successfully"); |  | ||||||
|   }; |  | ||||||
|  |  | ||||||
|   return ( |  | ||||||
|     <div className="h-full flex flex-col gap-4"> |  | ||||||
|       <Textarea className="flex-1 w-full resize-none" placeholder="Enter your JSON here" value={json} onChange={(e) => setJson(e.target.value)} /> |  | ||||||
|       <div className="flex flex-row gap-2"> |  | ||||||
|         <Button onClick={minifyJson}>Minify</Button> |  | ||||||
|         <Button onClick={prettifyJson}>Pretty</Button> |  | ||||||
|       </div> |  | ||||||
|     </div> |  | ||||||
|   ); |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| export default Tool; |  | ||||||
| @@ -1,24 +0,0 @@ | |||||||
| import { type FC } from "react"; |  | ||||||
|  |  | ||||||
| import * as uuid from 'uuid' |  | ||||||
| import { nanoid } from 'nanoid' |  | ||||||
|  |  | ||||||
| const Tool: FC = () => { |  | ||||||
|   return ( |  | ||||||
|     <div className="flex flex-col gap-4"> |  | ||||||
|       <span className="text-sm text-muted-foreground">Refresh the page to generate new UUID</span> |  | ||||||
|       <label>UUID Version 1</label> |  | ||||||
|       <span>{uuid.v1()}</span> |  | ||||||
|       <label>UUID Version 4</label> |  | ||||||
|       <span>{uuid.v4()}</span> |  | ||||||
|       <label>UUID Version 6</label> |  | ||||||
|       <span>{uuid.v6()}</span> |  | ||||||
|       <label>UUID Version 7</label> |  | ||||||
|       <span>{uuid.v7()}</span> |  | ||||||
|       <label>Nano ID</label> |  | ||||||
|       <span>{nanoid()}</span> |  | ||||||
|     </div> |  | ||||||
|   ); |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| export default Tool; |  | ||||||
| @@ -1,66 +0,0 @@ | |||||||
| import * as React from "react" |  | ||||||
| import { cva, type VariantProps } from "class-variance-authority" |  | ||||||
|  |  | ||||||
| import { cn } from "@/lib/utils" |  | ||||||
|  |  | ||||||
| const alertVariants = cva( |  | ||||||
|   "relative w-full rounded-lg border px-4 py-3 text-sm grid has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] grid-cols-[0_1fr] has-[>svg]:gap-x-3 gap-y-0.5 items-start [&>svg]:size-4 [&>svg]:translate-y-0.5 [&>svg]:text-current", |  | ||||||
|   { |  | ||||||
|     variants: { |  | ||||||
|       variant: { |  | ||||||
|         default: "bg-card text-card-foreground", |  | ||||||
|         destructive: |  | ||||||
|           "text-destructive bg-card [&>svg]:text-current *:data-[slot=alert-description]:text-destructive/90", |  | ||||||
|       }, |  | ||||||
|     }, |  | ||||||
|     defaultVariants: { |  | ||||||
|       variant: "default", |  | ||||||
|     }, |  | ||||||
|   } |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| function Alert({ |  | ||||||
|   className, |  | ||||||
|   variant, |  | ||||||
|   ...props |  | ||||||
| }: React.ComponentProps<"div"> & VariantProps<typeof alertVariants>) { |  | ||||||
|   return ( |  | ||||||
|     <div |  | ||||||
|       data-slot="alert" |  | ||||||
|       role="alert" |  | ||||||
|       className={cn(alertVariants({ variant }), className)} |  | ||||||
|       {...props} |  | ||||||
|     /> |  | ||||||
|   ) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function AlertTitle({ className, ...props }: React.ComponentProps<"div">) { |  | ||||||
|   return ( |  | ||||||
|     <div |  | ||||||
|       data-slot="alert-title" |  | ||||||
|       className={cn( |  | ||||||
|         "col-start-2 line-clamp-1 min-h-4 font-medium tracking-tight", |  | ||||||
|         className |  | ||||||
|       )} |  | ||||||
|       {...props} |  | ||||||
|     /> |  | ||||||
|   ) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function AlertDescription({ |  | ||||||
|   className, |  | ||||||
|   ...props |  | ||||||
| }: React.ComponentProps<"div">) { |  | ||||||
|   return ( |  | ||||||
|     <div |  | ||||||
|       data-slot="alert-description" |  | ||||||
|       className={cn( |  | ||||||
|         "text-muted-foreground col-start-2 grid justify-items-start gap-1 text-sm [&_p]:leading-relaxed", |  | ||||||
|         className |  | ||||||
|       )} |  | ||||||
|       {...props} |  | ||||||
|     /> |  | ||||||
|   ) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| export { Alert, AlertTitle, AlertDescription } |  | ||||||
| @@ -1,21 +0,0 @@ | |||||||
| import * as React from "react" |  | ||||||
|  |  | ||||||
| import { cn } from "@/lib/utils" |  | ||||||
|  |  | ||||||
| function Input({ className, type, ...props }: React.ComponentProps<"input">) { |  | ||||||
|   return ( |  | ||||||
|     <input |  | ||||||
|       type={type} |  | ||||||
|       data-slot="input" |  | ||||||
|       className={cn( |  | ||||||
|         "file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm", |  | ||||||
|         "focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]", |  | ||||||
|         "aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive", |  | ||||||
|         className |  | ||||||
|       )} |  | ||||||
|       {...props} |  | ||||||
|     /> |  | ||||||
|   ) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| export { Input } |  | ||||||
| @@ -1,26 +0,0 @@ | |||||||
| import * as React from "react" |  | ||||||
| import * as SeparatorPrimitive from "@radix-ui/react-separator" |  | ||||||
|  |  | ||||||
| import { cn } from "@/lib/utils" |  | ||||||
|  |  | ||||||
| function Separator({ |  | ||||||
|   className, |  | ||||||
|   orientation = "horizontal", |  | ||||||
|   decorative = true, |  | ||||||
|   ...props |  | ||||||
| }: React.ComponentProps<typeof SeparatorPrimitive.Root>) { |  | ||||||
|   return ( |  | ||||||
|     <SeparatorPrimitive.Root |  | ||||||
|       data-slot="separator" |  | ||||||
|       decorative={decorative} |  | ||||||
|       orientation={orientation} |  | ||||||
|       className={cn( |  | ||||||
|         "bg-border shrink-0 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px", |  | ||||||
|         className |  | ||||||
|       )} |  | ||||||
|       {...props} |  | ||||||
|     /> |  | ||||||
|   ) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| export { Separator } |  | ||||||
| @@ -1,139 +0,0 @@ | |||||||
| "use client" |  | ||||||
|  |  | ||||||
| import * as React from "react" |  | ||||||
| import * as SheetPrimitive from "@radix-ui/react-dialog" |  | ||||||
| import { XIcon } from "lucide-react" |  | ||||||
|  |  | ||||||
| import { cn } from "@/lib/utils" |  | ||||||
|  |  | ||||||
| function Sheet({ ...props }: React.ComponentProps<typeof SheetPrimitive.Root>) { |  | ||||||
|   return <SheetPrimitive.Root data-slot="sheet" {...props} /> |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function SheetTrigger({ |  | ||||||
|   ...props |  | ||||||
| }: React.ComponentProps<typeof SheetPrimitive.Trigger>) { |  | ||||||
|   return <SheetPrimitive.Trigger data-slot="sheet-trigger" {...props} /> |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function SheetClose({ |  | ||||||
|   ...props |  | ||||||
| }: React.ComponentProps<typeof SheetPrimitive.Close>) { |  | ||||||
|   return <SheetPrimitive.Close data-slot="sheet-close" {...props} /> |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function SheetPortal({ |  | ||||||
|   ...props |  | ||||||
| }: React.ComponentProps<typeof SheetPrimitive.Portal>) { |  | ||||||
|   return <SheetPrimitive.Portal data-slot="sheet-portal" {...props} /> |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function SheetOverlay({ |  | ||||||
|   className, |  | ||||||
|   ...props |  | ||||||
| }: React.ComponentProps<typeof SheetPrimitive.Overlay>) { |  | ||||||
|   return ( |  | ||||||
|     <SheetPrimitive.Overlay |  | ||||||
|       data-slot="sheet-overlay" |  | ||||||
|       className={cn( |  | ||||||
|         "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50", |  | ||||||
|         className |  | ||||||
|       )} |  | ||||||
|       {...props} |  | ||||||
|     /> |  | ||||||
|   ) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function SheetContent({ |  | ||||||
|   className, |  | ||||||
|   children, |  | ||||||
|   side = "right", |  | ||||||
|   ...props |  | ||||||
| }: React.ComponentProps<typeof SheetPrimitive.Content> & { |  | ||||||
|   side?: "top" | "right" | "bottom" | "left" |  | ||||||
| }) { |  | ||||||
|   return ( |  | ||||||
|     <SheetPortal> |  | ||||||
|       <SheetOverlay /> |  | ||||||
|       <SheetPrimitive.Content |  | ||||||
|         data-slot="sheet-content" |  | ||||||
|         className={cn( |  | ||||||
|           "bg-background data-[state=open]:animate-in data-[state=closed]:animate-out fixed z-50 flex flex-col gap-4 shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500", |  | ||||||
|           side === "right" && |  | ||||||
|             "data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right inset-y-0 right-0 h-full w-3/4 border-l sm:max-w-sm", |  | ||||||
|           side === "left" && |  | ||||||
|             "data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left inset-y-0 left-0 h-full w-3/4 border-r sm:max-w-sm", |  | ||||||
|           side === "top" && |  | ||||||
|             "data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top inset-x-0 top-0 h-auto border-b", |  | ||||||
|           side === "bottom" && |  | ||||||
|             "data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom inset-x-0 bottom-0 h-auto border-t", |  | ||||||
|           className |  | ||||||
|         )} |  | ||||||
|         {...props} |  | ||||||
|       > |  | ||||||
|         {children} |  | ||||||
|         <SheetPrimitive.Close className="ring-offset-background focus:ring-ring data-[state=open]:bg-secondary absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none"> |  | ||||||
|           <XIcon className="size-4" /> |  | ||||||
|           <span className="sr-only">Close</span> |  | ||||||
|         </SheetPrimitive.Close> |  | ||||||
|       </SheetPrimitive.Content> |  | ||||||
|     </SheetPortal> |  | ||||||
|   ) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function SheetHeader({ className, ...props }: React.ComponentProps<"div">) { |  | ||||||
|   return ( |  | ||||||
|     <div |  | ||||||
|       data-slot="sheet-header" |  | ||||||
|       className={cn("flex flex-col gap-1.5 p-4", className)} |  | ||||||
|       {...props} |  | ||||||
|     /> |  | ||||||
|   ) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function SheetFooter({ className, ...props }: React.ComponentProps<"div">) { |  | ||||||
|   return ( |  | ||||||
|     <div |  | ||||||
|       data-slot="sheet-footer" |  | ||||||
|       className={cn("mt-auto flex flex-col gap-2 p-4", className)} |  | ||||||
|       {...props} |  | ||||||
|     /> |  | ||||||
|   ) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function SheetTitle({ |  | ||||||
|   className, |  | ||||||
|   ...props |  | ||||||
| }: React.ComponentProps<typeof SheetPrimitive.Title>) { |  | ||||||
|   return ( |  | ||||||
|     <SheetPrimitive.Title |  | ||||||
|       data-slot="sheet-title" |  | ||||||
|       className={cn("text-foreground font-semibold", className)} |  | ||||||
|       {...props} |  | ||||||
|     /> |  | ||||||
|   ) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function SheetDescription({ |  | ||||||
|   className, |  | ||||||
|   ...props |  | ||||||
| }: React.ComponentProps<typeof SheetPrimitive.Description>) { |  | ||||||
|   return ( |  | ||||||
|     <SheetPrimitive.Description |  | ||||||
|       data-slot="sheet-description" |  | ||||||
|       className={cn("text-muted-foreground text-sm", className)} |  | ||||||
|       {...props} |  | ||||||
|     /> |  | ||||||
|   ) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| export { |  | ||||||
|   Sheet, |  | ||||||
|   SheetTrigger, |  | ||||||
|   SheetClose, |  | ||||||
|   SheetContent, |  | ||||||
|   SheetHeader, |  | ||||||
|   SheetFooter, |  | ||||||
|   SheetTitle, |  | ||||||
|   SheetDescription, |  | ||||||
| } |  | ||||||
| @@ -1,726 +0,0 @@ | |||||||
| "use client" |  | ||||||
|  |  | ||||||
| import * as React from "react" |  | ||||||
| import { Slot } from "@radix-ui/react-slot" |  | ||||||
| import { cva, type VariantProps } from "class-variance-authority" |  | ||||||
| import { PanelLeftIcon } from "lucide-react" |  | ||||||
|  |  | ||||||
| import { useIsMobile } from "@/hooks/use-mobile" |  | ||||||
| import { cn } from "@/lib/utils" |  | ||||||
| import { Button } from "@/components/ui/button" |  | ||||||
| import { Input } from "@/components/ui/input" |  | ||||||
| import { Separator } from "@/components/ui/separator" |  | ||||||
| import { |  | ||||||
|   Sheet, |  | ||||||
|   SheetContent, |  | ||||||
|   SheetDescription, |  | ||||||
|   SheetHeader, |  | ||||||
|   SheetTitle, |  | ||||||
| } from "@/components/ui/sheet" |  | ||||||
| import { Skeleton } from "@/components/ui/skeleton" |  | ||||||
| import { |  | ||||||
|   Tooltip, |  | ||||||
|   TooltipContent, |  | ||||||
|   TooltipProvider, |  | ||||||
|   TooltipTrigger, |  | ||||||
| } from "@/components/ui/tooltip" |  | ||||||
|  |  | ||||||
| const SIDEBAR_COOKIE_NAME = "sidebar_state" |  | ||||||
| const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7 |  | ||||||
| const SIDEBAR_WIDTH = "16rem" |  | ||||||
| const SIDEBAR_WIDTH_MOBILE = "18rem" |  | ||||||
| const SIDEBAR_WIDTH_ICON = "3rem" |  | ||||||
| const SIDEBAR_KEYBOARD_SHORTCUT = "b" |  | ||||||
|  |  | ||||||
| type SidebarContextProps = { |  | ||||||
|   state: "expanded" | "collapsed" |  | ||||||
|   open: boolean |  | ||||||
|   setOpen: (open: boolean) => void |  | ||||||
|   openMobile: boolean |  | ||||||
|   setOpenMobile: (open: boolean) => void |  | ||||||
|   isMobile: boolean |  | ||||||
|   toggleSidebar: () => void |  | ||||||
| } |  | ||||||
|  |  | ||||||
| const SidebarContext = React.createContext<SidebarContextProps | null>(null) |  | ||||||
|  |  | ||||||
| function useSidebar() { |  | ||||||
|   const context = React.useContext(SidebarContext) |  | ||||||
|   if (!context) { |  | ||||||
|     throw new Error("useSidebar must be used within a SidebarProvider.") |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   return context |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function SidebarProvider({ |  | ||||||
|   defaultOpen = true, |  | ||||||
|   open: openProp, |  | ||||||
|   onOpenChange: setOpenProp, |  | ||||||
|   className, |  | ||||||
|   style, |  | ||||||
|   children, |  | ||||||
|   ...props |  | ||||||
| }: React.ComponentProps<"div"> & { |  | ||||||
|   defaultOpen?: boolean |  | ||||||
|   open?: boolean |  | ||||||
|   onOpenChange?: (open: boolean) => void |  | ||||||
| }) { |  | ||||||
|   const isMobile = useIsMobile() |  | ||||||
|   const [openMobile, setOpenMobile] = React.useState(false) |  | ||||||
|  |  | ||||||
|   // This is the internal state of the sidebar. |  | ||||||
|   // We use openProp and setOpenProp for control from outside the component. |  | ||||||
|   const [_open, _setOpen] = React.useState(defaultOpen) |  | ||||||
|   const open = openProp ?? _open |  | ||||||
|   const setOpen = React.useCallback( |  | ||||||
|     (value: boolean | ((value: boolean) => boolean)) => { |  | ||||||
|       const openState = typeof value === "function" ? value(open) : value |  | ||||||
|       if (setOpenProp) { |  | ||||||
|         setOpenProp(openState) |  | ||||||
|       } else { |  | ||||||
|         _setOpen(openState) |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       // This sets the cookie to keep the sidebar state. |  | ||||||
|       document.cookie = `${SIDEBAR_COOKIE_NAME}=${openState}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}` |  | ||||||
|     }, |  | ||||||
|     [setOpenProp, open] |  | ||||||
|   ) |  | ||||||
|  |  | ||||||
|   // Helper to toggle the sidebar. |  | ||||||
|   const toggleSidebar = React.useCallback(() => { |  | ||||||
|     return isMobile ? setOpenMobile((open) => !open) : setOpen((open) => !open) |  | ||||||
|   }, [isMobile, setOpen, setOpenMobile]) |  | ||||||
|  |  | ||||||
|   // Adds a keyboard shortcut to toggle the sidebar. |  | ||||||
|   React.useEffect(() => { |  | ||||||
|     const handleKeyDown = (event: KeyboardEvent) => { |  | ||||||
|       if ( |  | ||||||
|         event.key === SIDEBAR_KEYBOARD_SHORTCUT && |  | ||||||
|         (event.metaKey || event.ctrlKey) |  | ||||||
|       ) { |  | ||||||
|         event.preventDefault() |  | ||||||
|         toggleSidebar() |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     window.addEventListener("keydown", handleKeyDown) |  | ||||||
|     return () => window.removeEventListener("keydown", handleKeyDown) |  | ||||||
|   }, [toggleSidebar]) |  | ||||||
|  |  | ||||||
|   // We add a state so that we can do data-state="expanded" or "collapsed". |  | ||||||
|   // This makes it easier to style the sidebar with Tailwind classes. |  | ||||||
|   const state = open ? "expanded" : "collapsed" |  | ||||||
|  |  | ||||||
|   const contextValue = React.useMemo<SidebarContextProps>( |  | ||||||
|     () => ({ |  | ||||||
|       state, |  | ||||||
|       open, |  | ||||||
|       setOpen, |  | ||||||
|       isMobile, |  | ||||||
|       openMobile, |  | ||||||
|       setOpenMobile, |  | ||||||
|       toggleSidebar, |  | ||||||
|     }), |  | ||||||
|     [state, open, setOpen, isMobile, openMobile, setOpenMobile, toggleSidebar] |  | ||||||
|   ) |  | ||||||
|  |  | ||||||
|   return ( |  | ||||||
|     <SidebarContext.Provider value={contextValue}> |  | ||||||
|       <TooltipProvider delayDuration={0}> |  | ||||||
|         <div |  | ||||||
|           data-slot="sidebar-wrapper" |  | ||||||
|           style={ |  | ||||||
|             { |  | ||||||
|               "--sidebar-width": SIDEBAR_WIDTH, |  | ||||||
|               "--sidebar-width-icon": SIDEBAR_WIDTH_ICON, |  | ||||||
|               ...style, |  | ||||||
|             } as React.CSSProperties |  | ||||||
|           } |  | ||||||
|           className={cn( |  | ||||||
|             "group/sidebar-wrapper has-data-[variant=inset]:bg-sidebar flex min-h-svh w-full", |  | ||||||
|             className |  | ||||||
|           )} |  | ||||||
|           {...props} |  | ||||||
|         > |  | ||||||
|           {children} |  | ||||||
|         </div> |  | ||||||
|       </TooltipProvider> |  | ||||||
|     </SidebarContext.Provider> |  | ||||||
|   ) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function Sidebar({ |  | ||||||
|   side = "left", |  | ||||||
|   variant = "sidebar", |  | ||||||
|   collapsible = "offcanvas", |  | ||||||
|   className, |  | ||||||
|   children, |  | ||||||
|   ...props |  | ||||||
| }: React.ComponentProps<"div"> & { |  | ||||||
|   side?: "left" | "right" |  | ||||||
|   variant?: "sidebar" | "floating" | "inset" |  | ||||||
|   collapsible?: "offcanvas" | "icon" | "none" |  | ||||||
| }) { |  | ||||||
|   const { isMobile, state, openMobile, setOpenMobile } = useSidebar() |  | ||||||
|  |  | ||||||
|   if (collapsible === "none") { |  | ||||||
|     return ( |  | ||||||
|       <div |  | ||||||
|         data-slot="sidebar" |  | ||||||
|         className={cn( |  | ||||||
|           "bg-sidebar text-sidebar-foreground flex h-full w-(--sidebar-width) flex-col", |  | ||||||
|           className |  | ||||||
|         )} |  | ||||||
|         {...props} |  | ||||||
|       > |  | ||||||
|         {children} |  | ||||||
|       </div> |  | ||||||
|     ) |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   if (isMobile) { |  | ||||||
|     return ( |  | ||||||
|       <Sheet open={openMobile} onOpenChange={setOpenMobile} {...props}> |  | ||||||
|         <SheetContent |  | ||||||
|           data-sidebar="sidebar" |  | ||||||
|           data-slot="sidebar" |  | ||||||
|           data-mobile="true" |  | ||||||
|           className="bg-sidebar text-sidebar-foreground w-(--sidebar-width) p-0 [&>button]:hidden" |  | ||||||
|           style={ |  | ||||||
|             { |  | ||||||
|               "--sidebar-width": SIDEBAR_WIDTH_MOBILE, |  | ||||||
|             } as React.CSSProperties |  | ||||||
|           } |  | ||||||
|           side={side} |  | ||||||
|         > |  | ||||||
|           <SheetHeader className="sr-only"> |  | ||||||
|             <SheetTitle>Sidebar</SheetTitle> |  | ||||||
|             <SheetDescription>Displays the mobile sidebar.</SheetDescription> |  | ||||||
|           </SheetHeader> |  | ||||||
|           <div className="flex h-full w-full flex-col">{children}</div> |  | ||||||
|         </SheetContent> |  | ||||||
|       </Sheet> |  | ||||||
|     ) |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   return ( |  | ||||||
|     <div |  | ||||||
|       className="group peer text-sidebar-foreground hidden md:block" |  | ||||||
|       data-state={state} |  | ||||||
|       data-collapsible={state === "collapsed" ? collapsible : ""} |  | ||||||
|       data-variant={variant} |  | ||||||
|       data-side={side} |  | ||||||
|       data-slot="sidebar" |  | ||||||
|     > |  | ||||||
|       {/* This is what handles the sidebar gap on desktop */} |  | ||||||
|       <div |  | ||||||
|         data-slot="sidebar-gap" |  | ||||||
|         className={cn( |  | ||||||
|           "relative w-(--sidebar-width) bg-transparent transition-[width] duration-200 ease-linear", |  | ||||||
|           "group-data-[collapsible=offcanvas]:w-0", |  | ||||||
|           "group-data-[side=right]:rotate-180", |  | ||||||
|           variant === "floating" || variant === "inset" |  | ||||||
|             ? "group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]" |  | ||||||
|             : "group-data-[collapsible=icon]:w-(--sidebar-width-icon)" |  | ||||||
|         )} |  | ||||||
|       /> |  | ||||||
|       <div |  | ||||||
|         data-slot="sidebar-container" |  | ||||||
|         className={cn( |  | ||||||
|           "fixed inset-y-0 z-10 hidden h-svh w-(--sidebar-width) transition-[left,right,width] duration-200 ease-linear md:flex", |  | ||||||
|           side === "left" |  | ||||||
|             ? "left-0 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)]" |  | ||||||
|             : "right-0 group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)]", |  | ||||||
|           // Adjust the padding for floating and inset variants. |  | ||||||
|           variant === "floating" || variant === "inset" |  | ||||||
|             ? "p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]" |  | ||||||
|             : "group-data-[collapsible=icon]:w-(--sidebar-width-icon) group-data-[side=left]:border-r group-data-[side=right]:border-l", |  | ||||||
|           className |  | ||||||
|         )} |  | ||||||
|         {...props} |  | ||||||
|       > |  | ||||||
|         <div |  | ||||||
|           data-sidebar="sidebar" |  | ||||||
|           data-slot="sidebar-inner" |  | ||||||
|           className="bg-sidebar group-data-[variant=floating]:border-sidebar-border flex h-full w-full flex-col group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:border group-data-[variant=floating]:shadow-sm" |  | ||||||
|         > |  | ||||||
|           {children} |  | ||||||
|         </div> |  | ||||||
|       </div> |  | ||||||
|     </div> |  | ||||||
|   ) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function SidebarTrigger({ |  | ||||||
|   className, |  | ||||||
|   onClick, |  | ||||||
|   ...props |  | ||||||
| }: React.ComponentProps<typeof Button>) { |  | ||||||
|   const { toggleSidebar } = useSidebar() |  | ||||||
|  |  | ||||||
|   return ( |  | ||||||
|     <Button |  | ||||||
|       data-sidebar="trigger" |  | ||||||
|       data-slot="sidebar-trigger" |  | ||||||
|       variant="ghost" |  | ||||||
|       size="icon" |  | ||||||
|       className={cn("size-7", className)} |  | ||||||
|       onClick={(event) => { |  | ||||||
|         onClick?.(event) |  | ||||||
|         toggleSidebar() |  | ||||||
|       }} |  | ||||||
|       {...props} |  | ||||||
|     > |  | ||||||
|       <PanelLeftIcon /> |  | ||||||
|       <span className="sr-only">Toggle Sidebar</span> |  | ||||||
|     </Button> |  | ||||||
|   ) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function SidebarRail({ className, ...props }: React.ComponentProps<"button">) { |  | ||||||
|   const { toggleSidebar } = useSidebar() |  | ||||||
|  |  | ||||||
|   return ( |  | ||||||
|     <button |  | ||||||
|       data-sidebar="rail" |  | ||||||
|       data-slot="sidebar-rail" |  | ||||||
|       aria-label="Toggle Sidebar" |  | ||||||
|       tabIndex={-1} |  | ||||||
|       onClick={toggleSidebar} |  | ||||||
|       title="Toggle Sidebar" |  | ||||||
|       className={cn( |  | ||||||
|         "hover:after:bg-sidebar-border absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 transition-all ease-linear group-data-[side=left]:-right-4 group-data-[side=right]:left-0 after:absolute after:inset-y-0 after:left-1/2 after:w-[2px] sm:flex", |  | ||||||
|         "in-data-[side=left]:cursor-w-resize in-data-[side=right]:cursor-e-resize", |  | ||||||
|         "[[data-side=left][data-state=collapsed]_&]:cursor-e-resize [[data-side=right][data-state=collapsed]_&]:cursor-w-resize", |  | ||||||
|         "hover:group-data-[collapsible=offcanvas]:bg-sidebar group-data-[collapsible=offcanvas]:translate-x-0 group-data-[collapsible=offcanvas]:after:left-full", |  | ||||||
|         "[[data-side=left][data-collapsible=offcanvas]_&]:-right-2", |  | ||||||
|         "[[data-side=right][data-collapsible=offcanvas]_&]:-left-2", |  | ||||||
|         className |  | ||||||
|       )} |  | ||||||
|       {...props} |  | ||||||
|     /> |  | ||||||
|   ) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function SidebarInset({ className, ...props }: React.ComponentProps<"main">) { |  | ||||||
|   return ( |  | ||||||
|     <main |  | ||||||
|       data-slot="sidebar-inset" |  | ||||||
|       className={cn( |  | ||||||
|         "bg-background relative flex w-full flex-1 flex-col", |  | ||||||
|         "md:peer-data-[variant=inset]:m-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow-sm md:peer-data-[variant=inset]:peer-data-[state=collapsed]:ml-2", |  | ||||||
|         className |  | ||||||
|       )} |  | ||||||
|       {...props} |  | ||||||
|     /> |  | ||||||
|   ) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function SidebarInput({ |  | ||||||
|   className, |  | ||||||
|   ...props |  | ||||||
| }: React.ComponentProps<typeof Input>) { |  | ||||||
|   return ( |  | ||||||
|     <Input |  | ||||||
|       data-slot="sidebar-input" |  | ||||||
|       data-sidebar="input" |  | ||||||
|       className={cn("bg-background h-8 w-full shadow-none", className)} |  | ||||||
|       {...props} |  | ||||||
|     /> |  | ||||||
|   ) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function SidebarHeader({ className, ...props }: React.ComponentProps<"div">) { |  | ||||||
|   return ( |  | ||||||
|     <div |  | ||||||
|       data-slot="sidebar-header" |  | ||||||
|       data-sidebar="header" |  | ||||||
|       className={cn("flex flex-col gap-2 p-2", className)} |  | ||||||
|       {...props} |  | ||||||
|     /> |  | ||||||
|   ) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function SidebarFooter({ className, ...props }: React.ComponentProps<"div">) { |  | ||||||
|   return ( |  | ||||||
|     <div |  | ||||||
|       data-slot="sidebar-footer" |  | ||||||
|       data-sidebar="footer" |  | ||||||
|       className={cn("flex flex-col gap-2 p-2", className)} |  | ||||||
|       {...props} |  | ||||||
|     /> |  | ||||||
|   ) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function SidebarSeparator({ |  | ||||||
|   className, |  | ||||||
|   ...props |  | ||||||
| }: React.ComponentProps<typeof Separator>) { |  | ||||||
|   return ( |  | ||||||
|     <Separator |  | ||||||
|       data-slot="sidebar-separator" |  | ||||||
|       data-sidebar="separator" |  | ||||||
|       className={cn("bg-sidebar-border mx-2 w-auto", className)} |  | ||||||
|       {...props} |  | ||||||
|     /> |  | ||||||
|   ) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function SidebarContent({ className, ...props }: React.ComponentProps<"div">) { |  | ||||||
|   return ( |  | ||||||
|     <div |  | ||||||
|       data-slot="sidebar-content" |  | ||||||
|       data-sidebar="content" |  | ||||||
|       className={cn( |  | ||||||
|         "flex min-h-0 flex-1 flex-col gap-2 overflow-auto group-data-[collapsible=icon]:overflow-hidden", |  | ||||||
|         className |  | ||||||
|       )} |  | ||||||
|       {...props} |  | ||||||
|     /> |  | ||||||
|   ) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function SidebarGroup({ className, ...props }: React.ComponentProps<"div">) { |  | ||||||
|   return ( |  | ||||||
|     <div |  | ||||||
|       data-slot="sidebar-group" |  | ||||||
|       data-sidebar="group" |  | ||||||
|       className={cn("relative flex w-full min-w-0 flex-col p-2", className)} |  | ||||||
|       {...props} |  | ||||||
|     /> |  | ||||||
|   ) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function SidebarGroupLabel({ |  | ||||||
|   className, |  | ||||||
|   asChild = false, |  | ||||||
|   ...props |  | ||||||
| }: React.ComponentProps<"div"> & { asChild?: boolean }) { |  | ||||||
|   const Comp = asChild ? Slot : "div" |  | ||||||
|  |  | ||||||
|   return ( |  | ||||||
|     <Comp |  | ||||||
|       data-slot="sidebar-group-label" |  | ||||||
|       data-sidebar="group-label" |  | ||||||
|       className={cn( |  | ||||||
|         "text-sidebar-foreground/70 ring-sidebar-ring flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium outline-hidden transition-[margin,opacity] duration-200 ease-linear focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0", |  | ||||||
|         "group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0", |  | ||||||
|         className |  | ||||||
|       )} |  | ||||||
|       {...props} |  | ||||||
|     /> |  | ||||||
|   ) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function SidebarGroupAction({ |  | ||||||
|   className, |  | ||||||
|   asChild = false, |  | ||||||
|   ...props |  | ||||||
| }: React.ComponentProps<"button"> & { asChild?: boolean }) { |  | ||||||
|   const Comp = asChild ? Slot : "button" |  | ||||||
|  |  | ||||||
|   return ( |  | ||||||
|     <Comp |  | ||||||
|       data-slot="sidebar-group-action" |  | ||||||
|       data-sidebar="group-action" |  | ||||||
|       className={cn( |  | ||||||
|         "text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground absolute top-3.5 right-3 flex aspect-square w-5 items-center justify-center rounded-md p-0 outline-hidden transition-transform focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0", |  | ||||||
|         // Increases the hit area of the button on mobile. |  | ||||||
|         "after:absolute after:-inset-2 md:after:hidden", |  | ||||||
|         "group-data-[collapsible=icon]:hidden", |  | ||||||
|         className |  | ||||||
|       )} |  | ||||||
|       {...props} |  | ||||||
|     /> |  | ||||||
|   ) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function SidebarGroupContent({ |  | ||||||
|   className, |  | ||||||
|   ...props |  | ||||||
| }: React.ComponentProps<"div">) { |  | ||||||
|   return ( |  | ||||||
|     <div |  | ||||||
|       data-slot="sidebar-group-content" |  | ||||||
|       data-sidebar="group-content" |  | ||||||
|       className={cn("w-full text-sm", className)} |  | ||||||
|       {...props} |  | ||||||
|     /> |  | ||||||
|   ) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function SidebarMenu({ className, ...props }: React.ComponentProps<"ul">) { |  | ||||||
|   return ( |  | ||||||
|     <ul |  | ||||||
|       data-slot="sidebar-menu" |  | ||||||
|       data-sidebar="menu" |  | ||||||
|       className={cn("flex w-full min-w-0 flex-col gap-1", className)} |  | ||||||
|       {...props} |  | ||||||
|     /> |  | ||||||
|   ) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function SidebarMenuItem({ className, ...props }: React.ComponentProps<"li">) { |  | ||||||
|   return ( |  | ||||||
|     <li |  | ||||||
|       data-slot="sidebar-menu-item" |  | ||||||
|       data-sidebar="menu-item" |  | ||||||
|       className={cn("group/menu-item relative", className)} |  | ||||||
|       {...props} |  | ||||||
|     /> |  | ||||||
|   ) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| const sidebarMenuButtonVariants = cva( |  | ||||||
|   "peer/menu-button flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left text-sm outline-hidden ring-sidebar-ring transition-[width,height,padding] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 group-has-data-[sidebar=menu-action]/menu-item:pr-8 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-sidebar-accent data-[active=true]:font-medium data-[active=true]:text-sidebar-accent-foreground data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0", |  | ||||||
|   { |  | ||||||
|     variants: { |  | ||||||
|       variant: { |  | ||||||
|         default: "hover:bg-sidebar-accent hover:text-sidebar-accent-foreground", |  | ||||||
|         outline: |  | ||||||
|           "bg-background shadow-[0_0_0_1px_hsl(var(--sidebar-border))] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_hsl(var(--sidebar-accent))]", |  | ||||||
|       }, |  | ||||||
|       size: { |  | ||||||
|         default: "h-8 text-sm", |  | ||||||
|         sm: "h-7 text-xs", |  | ||||||
|         lg: "h-12 text-sm group-data-[collapsible=icon]:p-0!", |  | ||||||
|       }, |  | ||||||
|     }, |  | ||||||
|     defaultVariants: { |  | ||||||
|       variant: "default", |  | ||||||
|       size: "default", |  | ||||||
|     }, |  | ||||||
|   } |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| function SidebarMenuButton({ |  | ||||||
|   asChild = false, |  | ||||||
|   isActive = false, |  | ||||||
|   variant = "default", |  | ||||||
|   size = "default", |  | ||||||
|   tooltip, |  | ||||||
|   className, |  | ||||||
|   ...props |  | ||||||
| }: React.ComponentProps<"button"> & { |  | ||||||
|   asChild?: boolean |  | ||||||
|   isActive?: boolean |  | ||||||
|   tooltip?: string | React.ComponentProps<typeof TooltipContent> |  | ||||||
| } & VariantProps<typeof sidebarMenuButtonVariants>) { |  | ||||||
|   const Comp = asChild ? Slot : "button" |  | ||||||
|   const { isMobile, state } = useSidebar() |  | ||||||
|  |  | ||||||
|   const button = ( |  | ||||||
|     <Comp |  | ||||||
|       data-slot="sidebar-menu-button" |  | ||||||
|       data-sidebar="menu-button" |  | ||||||
|       data-size={size} |  | ||||||
|       data-active={isActive} |  | ||||||
|       className={cn(sidebarMenuButtonVariants({ variant, size }), className)} |  | ||||||
|       {...props} |  | ||||||
|     /> |  | ||||||
|   ) |  | ||||||
|  |  | ||||||
|   if (!tooltip) { |  | ||||||
|     return button |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   if (typeof tooltip === "string") { |  | ||||||
|     tooltip = { |  | ||||||
|       children: tooltip, |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   return ( |  | ||||||
|     <Tooltip> |  | ||||||
|       <TooltipTrigger asChild>{button}</TooltipTrigger> |  | ||||||
|       <TooltipContent |  | ||||||
|         side="right" |  | ||||||
|         align="center" |  | ||||||
|         hidden={state !== "collapsed" || isMobile} |  | ||||||
|         {...tooltip} |  | ||||||
|       /> |  | ||||||
|     </Tooltip> |  | ||||||
|   ) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function SidebarMenuAction({ |  | ||||||
|   className, |  | ||||||
|   asChild = false, |  | ||||||
|   showOnHover = false, |  | ||||||
|   ...props |  | ||||||
| }: React.ComponentProps<"button"> & { |  | ||||||
|   asChild?: boolean |  | ||||||
|   showOnHover?: boolean |  | ||||||
| }) { |  | ||||||
|   const Comp = asChild ? Slot : "button" |  | ||||||
|  |  | ||||||
|   return ( |  | ||||||
|     <Comp |  | ||||||
|       data-slot="sidebar-menu-action" |  | ||||||
|       data-sidebar="menu-action" |  | ||||||
|       className={cn( |  | ||||||
|         "text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground peer-hover/menu-button:text-sidebar-accent-foreground absolute top-1.5 right-1 flex aspect-square w-5 items-center justify-center rounded-md p-0 outline-hidden transition-transform focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0", |  | ||||||
|         // Increases the hit area of the button on mobile. |  | ||||||
|         "after:absolute after:-inset-2 md:after:hidden", |  | ||||||
|         "peer-data-[size=sm]/menu-button:top-1", |  | ||||||
|         "peer-data-[size=default]/menu-button:top-1.5", |  | ||||||
|         "peer-data-[size=lg]/menu-button:top-2.5", |  | ||||||
|         "group-data-[collapsible=icon]:hidden", |  | ||||||
|         showOnHover && |  | ||||||
|           "peer-data-[active=true]/menu-button:text-sidebar-accent-foreground group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 data-[state=open]:opacity-100 md:opacity-0", |  | ||||||
|         className |  | ||||||
|       )} |  | ||||||
|       {...props} |  | ||||||
|     /> |  | ||||||
|   ) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function SidebarMenuBadge({ |  | ||||||
|   className, |  | ||||||
|   ...props |  | ||||||
| }: React.ComponentProps<"div">) { |  | ||||||
|   return ( |  | ||||||
|     <div |  | ||||||
|       data-slot="sidebar-menu-badge" |  | ||||||
|       data-sidebar="menu-badge" |  | ||||||
|       className={cn( |  | ||||||
|         "text-sidebar-foreground pointer-events-none absolute right-1 flex h-5 min-w-5 items-center justify-center rounded-md px-1 text-xs font-medium tabular-nums select-none", |  | ||||||
|         "peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[active=true]/menu-button:text-sidebar-accent-foreground", |  | ||||||
|         "peer-data-[size=sm]/menu-button:top-1", |  | ||||||
|         "peer-data-[size=default]/menu-button:top-1.5", |  | ||||||
|         "peer-data-[size=lg]/menu-button:top-2.5", |  | ||||||
|         "group-data-[collapsible=icon]:hidden", |  | ||||||
|         className |  | ||||||
|       )} |  | ||||||
|       {...props} |  | ||||||
|     /> |  | ||||||
|   ) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function SidebarMenuSkeleton({ |  | ||||||
|   className, |  | ||||||
|   showIcon = false, |  | ||||||
|   ...props |  | ||||||
| }: React.ComponentProps<"div"> & { |  | ||||||
|   showIcon?: boolean |  | ||||||
| }) { |  | ||||||
|   // Random width between 50 to 90%. |  | ||||||
|   const width = React.useMemo(() => { |  | ||||||
|     return `${Math.floor(Math.random() * 40) + 50}%` |  | ||||||
|   }, []) |  | ||||||
|  |  | ||||||
|   return ( |  | ||||||
|     <div |  | ||||||
|       data-slot="sidebar-menu-skeleton" |  | ||||||
|       data-sidebar="menu-skeleton" |  | ||||||
|       className={cn("flex h-8 items-center gap-2 rounded-md px-2", className)} |  | ||||||
|       {...props} |  | ||||||
|     > |  | ||||||
|       {showIcon && ( |  | ||||||
|         <Skeleton |  | ||||||
|           className="size-4 rounded-md" |  | ||||||
|           data-sidebar="menu-skeleton-icon" |  | ||||||
|         /> |  | ||||||
|       )} |  | ||||||
|       <Skeleton |  | ||||||
|         className="h-4 max-w-(--skeleton-width) flex-1" |  | ||||||
|         data-sidebar="menu-skeleton-text" |  | ||||||
|         style={ |  | ||||||
|           { |  | ||||||
|             "--skeleton-width": width, |  | ||||||
|           } as React.CSSProperties |  | ||||||
|         } |  | ||||||
|       /> |  | ||||||
|     </div> |  | ||||||
|   ) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function SidebarMenuSub({ className, ...props }: React.ComponentProps<"ul">) { |  | ||||||
|   return ( |  | ||||||
|     <ul |  | ||||||
|       data-slot="sidebar-menu-sub" |  | ||||||
|       data-sidebar="menu-sub" |  | ||||||
|       className={cn( |  | ||||||
|         "border-sidebar-border mx-3.5 flex min-w-0 translate-x-px flex-col gap-1 border-l px-2.5 py-0.5", |  | ||||||
|         "group-data-[collapsible=icon]:hidden", |  | ||||||
|         className |  | ||||||
|       )} |  | ||||||
|       {...props} |  | ||||||
|     /> |  | ||||||
|   ) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function SidebarMenuSubItem({ |  | ||||||
|   className, |  | ||||||
|   ...props |  | ||||||
| }: React.ComponentProps<"li">) { |  | ||||||
|   return ( |  | ||||||
|     <li |  | ||||||
|       data-slot="sidebar-menu-sub-item" |  | ||||||
|       data-sidebar="menu-sub-item" |  | ||||||
|       className={cn("group/menu-sub-item relative", className)} |  | ||||||
|       {...props} |  | ||||||
|     /> |  | ||||||
|   ) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function SidebarMenuSubButton({ |  | ||||||
|   asChild = false, |  | ||||||
|   size = "md", |  | ||||||
|   isActive = false, |  | ||||||
|   className, |  | ||||||
|   ...props |  | ||||||
| }: React.ComponentProps<"a"> & { |  | ||||||
|   asChild?: boolean |  | ||||||
|   size?: "sm" | "md" |  | ||||||
|   isActive?: boolean |  | ||||||
| }) { |  | ||||||
|   const Comp = asChild ? Slot : "a" |  | ||||||
|  |  | ||||||
|   return ( |  | ||||||
|     <Comp |  | ||||||
|       data-slot="sidebar-menu-sub-button" |  | ||||||
|       data-sidebar="menu-sub-button" |  | ||||||
|       data-size={size} |  | ||||||
|       data-active={isActive} |  | ||||||
|       className={cn( |  | ||||||
|         "text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground active:bg-sidebar-accent active:text-sidebar-accent-foreground [&>svg]:text-sidebar-accent-foreground flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 outline-hidden focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0", |  | ||||||
|         "data-[active=true]:bg-sidebar-accent data-[active=true]:text-sidebar-accent-foreground", |  | ||||||
|         size === "sm" && "text-xs", |  | ||||||
|         size === "md" && "text-sm", |  | ||||||
|         "group-data-[collapsible=icon]:hidden", |  | ||||||
|         className |  | ||||||
|       )} |  | ||||||
|       {...props} |  | ||||||
|     /> |  | ||||||
|   ) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| export { |  | ||||||
|   Sidebar, |  | ||||||
|   SidebarContent, |  | ||||||
|   SidebarFooter, |  | ||||||
|   SidebarGroup, |  | ||||||
|   SidebarGroupAction, |  | ||||||
|   SidebarGroupContent, |  | ||||||
|   SidebarGroupLabel, |  | ||||||
|   SidebarHeader, |  | ||||||
|   SidebarInput, |  | ||||||
|   SidebarInset, |  | ||||||
|   SidebarMenu, |  | ||||||
|   SidebarMenuAction, |  | ||||||
|   SidebarMenuBadge, |  | ||||||
|   SidebarMenuButton, |  | ||||||
|   SidebarMenuItem, |  | ||||||
|   SidebarMenuSkeleton, |  | ||||||
|   SidebarMenuSub, |  | ||||||
|   SidebarMenuSubButton, |  | ||||||
|   SidebarMenuSubItem, |  | ||||||
|   SidebarProvider, |  | ||||||
|   SidebarRail, |  | ||||||
|   SidebarSeparator, |  | ||||||
|   SidebarTrigger, |  | ||||||
|   useSidebar, |  | ||||||
| } |  | ||||||
| @@ -1,13 +0,0 @@ | |||||||
| import { cn } from "@/lib/utils" |  | ||||||
|  |  | ||||||
| function Skeleton({ className, ...props }: React.ComponentProps<"div">) { |  | ||||||
|   return ( |  | ||||||
|     <div |  | ||||||
|       data-slot="skeleton" |  | ||||||
|       className={cn("bg-accent animate-pulse rounded-md", className)} |  | ||||||
|       {...props} |  | ||||||
|     /> |  | ||||||
|   ) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| export { Skeleton } |  | ||||||
| @@ -1,38 +0,0 @@ | |||||||
| import { |  | ||||||
|   CircleCheckIcon, |  | ||||||
|   InfoIcon, |  | ||||||
|   Loader2Icon, |  | ||||||
|   OctagonXIcon, |  | ||||||
|   TriangleAlertIcon, |  | ||||||
| } from "lucide-react" |  | ||||||
| import { useTheme } from "next-themes" |  | ||||||
| import { Toaster as Sonner, type ToasterProps } from "sonner" |  | ||||||
|  |  | ||||||
| const Toaster = ({ ...props }: ToasterProps) => { |  | ||||||
|   const { theme = "system" } = useTheme() |  | ||||||
|  |  | ||||||
|   return ( |  | ||||||
|     <Sonner |  | ||||||
|       theme={theme as ToasterProps["theme"]} |  | ||||||
|       className="toaster group" |  | ||||||
|       icons={{ |  | ||||||
|         success: <CircleCheckIcon className="size-4" />, |  | ||||||
|         info: <InfoIcon className="size-4" />, |  | ||||||
|         warning: <TriangleAlertIcon className="size-4" />, |  | ||||||
|         error: <OctagonXIcon className="size-4" />, |  | ||||||
|         loading: <Loader2Icon className="size-4 animate-spin" />, |  | ||||||
|       }} |  | ||||||
|       style={ |  | ||||||
|         { |  | ||||||
|           "--normal-bg": "var(--popover)", |  | ||||||
|           "--normal-text": "var(--popover-foreground)", |  | ||||||
|           "--normal-border": "var(--border)", |  | ||||||
|           "--border-radius": "var(--radius)", |  | ||||||
|         } as React.CSSProperties |  | ||||||
|       } |  | ||||||
|       {...props} |  | ||||||
|     /> |  | ||||||
|   ) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| export { Toaster } |  | ||||||
| @@ -1,18 +0,0 @@ | |||||||
| import * as React from "react" |  | ||||||
|  |  | ||||||
| import { cn } from "@/lib/utils" |  | ||||||
|  |  | ||||||
| function Textarea({ className, ...props }: React.ComponentProps<"textarea">) { |  | ||||||
|   return ( |  | ||||||
|     <textarea |  | ||||||
|       data-slot="textarea" |  | ||||||
|       className={cn( |  | ||||||
|         "border-input placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm", |  | ||||||
|         className |  | ||||||
|       )} |  | ||||||
|       {...props} |  | ||||||
|     /> |  | ||||||
|   ) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| export { Textarea } |  | ||||||
| @@ -1,59 +0,0 @@ | |||||||
| import * as React from "react" |  | ||||||
| import * as TooltipPrimitive from "@radix-ui/react-tooltip" |  | ||||||
|  |  | ||||||
| import { cn } from "@/lib/utils" |  | ||||||
|  |  | ||||||
| function TooltipProvider({ |  | ||||||
|   delayDuration = 0, |  | ||||||
|   ...props |  | ||||||
| }: React.ComponentProps<typeof TooltipPrimitive.Provider>) { |  | ||||||
|   return ( |  | ||||||
|     <TooltipPrimitive.Provider |  | ||||||
|       data-slot="tooltip-provider" |  | ||||||
|       delayDuration={delayDuration} |  | ||||||
|       {...props} |  | ||||||
|     /> |  | ||||||
|   ) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function Tooltip({ |  | ||||||
|   ...props |  | ||||||
| }: React.ComponentProps<typeof TooltipPrimitive.Root>) { |  | ||||||
|   return ( |  | ||||||
|     <TooltipProvider> |  | ||||||
|       <TooltipPrimitive.Root data-slot="tooltip" {...props} /> |  | ||||||
|     </TooltipProvider> |  | ||||||
|   ) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function TooltipTrigger({ |  | ||||||
|   ...props |  | ||||||
| }: React.ComponentProps<typeof TooltipPrimitive.Trigger>) { |  | ||||||
|   return <TooltipPrimitive.Trigger data-slot="tooltip-trigger" {...props} /> |  | ||||||
| } |  | ||||||
|  |  | ||||||
| function TooltipContent({ |  | ||||||
|   className, |  | ||||||
|   sideOffset = 0, |  | ||||||
|   children, |  | ||||||
|   ...props |  | ||||||
| }: React.ComponentProps<typeof TooltipPrimitive.Content>) { |  | ||||||
|   return ( |  | ||||||
|     <TooltipPrimitive.Portal> |  | ||||||
|       <TooltipPrimitive.Content |  | ||||||
|         data-slot="tooltip-content" |  | ||||||
|         sideOffset={sideOffset} |  | ||||||
|         className={cn( |  | ||||||
|           "bg-foreground text-background animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-fit origin-(--radix-tooltip-content-transform-origin) rounded-md px-3 py-1.5 text-xs text-balance", |  | ||||||
|           className |  | ||||||
|         )} |  | ||||||
|         {...props} |  | ||||||
|       > |  | ||||||
|         {children} |  | ||||||
|         <TooltipPrimitive.Arrow className="bg-foreground fill-foreground z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]" /> |  | ||||||
|       </TooltipPrimitive.Content> |  | ||||||
|     </TooltipPrimitive.Portal> |  | ||||||
|   ) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider } |  | ||||||
| @@ -1,23 +0,0 @@ | |||||||
| @layer base { |  | ||||||
|   :root { |  | ||||||
|     --sidebar: oklch(0.985 0 0); |  | ||||||
|     --sidebar-foreground: oklch(0.145 0 0); |  | ||||||
|     --sidebar-primary: oklch(0.205 0 0); |  | ||||||
|     --sidebar-primary-foreground: oklch(0.985 0 0); |  | ||||||
|     --sidebar-accent: oklch(0.97 0 0); |  | ||||||
|     --sidebar-accent-foreground: oklch(0.205 0 0); |  | ||||||
|     --sidebar-border: oklch(0.922 0 0); |  | ||||||
|     --sidebar-ring: oklch(0.708 0 0); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   .dark { |  | ||||||
|     --sidebar: oklch(0.205 0 0); |  | ||||||
|     --sidebar-foreground: oklch(0.985 0 0); |  | ||||||
|     --sidebar-primary: oklch(0.488 0.243 264.376); |  | ||||||
|     --sidebar-primary-foreground: oklch(0.985 0 0); |  | ||||||
|     --sidebar-accent: oklch(0.269 0 0); |  | ||||||
|     --sidebar-accent-foreground: oklch(0.985 0 0); |  | ||||||
|     --sidebar-border: oklch(1 0 0 / 10%); |  | ||||||
|     --sidebar-ring: oklch(0.439 0 0); |  | ||||||
|   } |  | ||||||
| } |  | ||||||
| @@ -1,19 +0,0 @@ | |||||||
| import * as React from "react" |  | ||||||
|  |  | ||||||
| const MOBILE_BREAKPOINT = 768 |  | ||||||
|  |  | ||||||
| export function useIsMobile() { |  | ||||||
|   const [isMobile, setIsMobile] = React.useState<boolean | undefined>(undefined) |  | ||||||
|  |  | ||||||
|   React.useEffect(() => { |  | ||||||
|     const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`) |  | ||||||
|     const onChange = () => { |  | ||||||
|       setIsMobile(window.innerWidth < MOBILE_BREAKPOINT) |  | ||||||
|     } |  | ||||||
|     mql.addEventListener("change", onChange) |  | ||||||
|     setIsMobile(window.innerWidth < MOBILE_BREAKPOINT) |  | ||||||
|     return () => mql.removeEventListener("change", onChange) |  | ||||||
|   }, []) |  | ||||||
|  |  | ||||||
|   return !!isMobile |  | ||||||
| } |  | ||||||
| @@ -1,20 +0,0 @@ | |||||||
| import type { FC } from "react" |  | ||||||
| import { Outlet } from "react-router-dom"; |  | ||||||
|  |  | ||||||
| import { SidebarProvider, SidebarTrigger } from "@/components/ui/sidebar" |  | ||||||
| import { AppSidebar } from "@/components/sidebar"; |  | ||||||
|  |  | ||||||
| export const Layout: FC = () => ( |  | ||||||
|   <SidebarProvider> |  | ||||||
|     <AppSidebar /> |  | ||||||
|     <div className="p-4 flex flex-col w-full h-[100vh] overflow-hidden"> |  | ||||||
|       <nav className="flex items-center justify-between"> |  | ||||||
|         <SidebarTrigger className="size-10" /> |  | ||||||
|         <div role="actions" /> |  | ||||||
|       </nav> |  | ||||||
|       <main className="flex-1 overflow-auto p-4 overflow-hidden"> |  | ||||||
|         <Outlet /> |  | ||||||
|       </main> |  | ||||||
|     </div> |  | ||||||
|   </SidebarProvider> |  | ||||||
| ); |  | ||||||
| @@ -1,14 +1,9 @@ | |||||||
| import { StrictMode } from 'react' | import { StrictMode } from 'react' | ||||||
| import { createRoot } from 'react-dom/client' | import { createRoot } from 'react-dom/client' | ||||||
|  |  | ||||||
| import { Toaster } from '@/components/ui/sonner' |  | ||||||
|  |  | ||||||
| import './index.css' | import './index.css' | ||||||
| import { AppRouter } from './router' |  | ||||||
|  |  | ||||||
| createRoot(document.getElementById('root')!).render( | createRoot(document.getElementById('root')!).render( | ||||||
|   <StrictMode> |   <StrictMode> | ||||||
|     <AppRouter /> |     {null} | ||||||
|     <Toaster /> |  | ||||||
|   </StrictMode> |   </StrictMode> | ||||||
| ) | ) | ||||||
|   | |||||||
| @@ -1,44 +0,0 @@ | |||||||
| import { |  | ||||||
|   createBrowserRouter, |  | ||||||
|   redirect, |  | ||||||
|   RouterProvider, |  | ||||||
| } from "react-router-dom"; |  | ||||||
|  |  | ||||||
| import { tools } from "@/components/tool"; |  | ||||||
| import { Layout } from "./layout"; |  | ||||||
|  |  | ||||||
| // 路由配置 |  | ||||||
| const router = createBrowserRouter([ |  | ||||||
|   { |  | ||||||
|     path: "", |  | ||||||
|     element: <Layout />, |  | ||||||
|     children: [ |  | ||||||
|       { |  | ||||||
|         path: "tool", |  | ||||||
|         children: [ |  | ||||||
|           ...tools.map((tool) => ( |  | ||||||
|             { |  | ||||||
|               path: tool.path, |  | ||||||
|               element: tool.component, |  | ||||||
|             } |  | ||||||
|           )), |  | ||||||
|           { |  | ||||||
|             index: true, |  | ||||||
|             loader: () => redirect("/tool/uuid"), |  | ||||||
|           }, |  | ||||||
|         ] |  | ||||||
|       }, |  | ||||||
|     ] |  | ||||||
|   }, |  | ||||||
|   { |  | ||||||
|     index: true, |  | ||||||
|     loader: () => redirect("/tool"), |  | ||||||
|   }, |  | ||||||
|   { |  | ||||||
|     path: "*", |  | ||||||
|     loader: () => redirect("/tool"), |  | ||||||
|   }, |  | ||||||
| ]); |  | ||||||
|  |  | ||||||
| // 路由提供者组件 |  | ||||||
| export const AppRouter = () => <RouterProvider router={router} />; |  | ||||||
		Reference in New Issue
	
	Block a user