From a12183d4a8d377c39d85069a3c43c59748d95b1d Mon Sep 17 00:00:00 2001 From: Daniel Luiz Alves Date: Sun, 27 Apr 2025 23:23:49 -0300 Subject: [PATCH] Squashed commit of the following: commit 359d0a0403405fe85810174f89500202e21fa36c Author: Daniel Luiz Alves Date: Fri Apr 25 14:11:09 2025 -0300 docs(installation): add command to generate .env file Add a command to generate a .env file with the `server_ip` configuration to simplify the setup process for users. This command can be executed in the server terminal at the same path as the docker-compose.yaml file. commit c3967eca72b7beffe46ffbcea0ce60d4d41c8e27 Author: Daniel Luiz Alves Date: Fri Apr 25 13:42:26 2025 -0300 refactor(web): remove unused config fetch in layout metadata Simplify the metadata generation in the layout component by removing the unnecessary fetch of app configurations. This reduces complexity and improves maintainability. commit 6898dd8d1b60435272ad886ed4ca0fdd6d24d7ed Author: Daniel Luiz Alves Date: Fri Apr 25 01:22:53 2025 -0300 refactor(layout): remove unused changeLayout prop from Banner component The changeLayout prop was not utilized in the Banner component, so it has been removed to simplify the code and improve maintainability. style(home): add version tag to the hero section title Added a small version tag "v2.0.0-beta" to the hero section title for better visibility and user awareness of the current version. commit e80de3576c5e88a558ad71b840f937d0cc4c22fe Author: Daniel Luiz Alves Date: Fri Apr 25 01:11:45 2025 -0300 build(docs): disable eslint and typescript checks during builds To streamline the build process and avoid unnecessary interruptions, eslint and typescript checks are now ignored during builds commit 17dd85241cb59922d16c54fd8048a31c0dce430f Merge: da64d65 f7124ec Author: Daniel Luiz Alves Date: Fri Apr 25 01:01:28 2025 -0300 Upgrade to v2.0.0-beta (#16) commit f7124ec34674130a432bad4b8c3c468984668e30 Author: Daniel Luiz Alves Date: Fri Apr 25 00:56:04 2025 -0300 chore: update environment and docker configurations Update .env.example to include SERVER_IP, add metadata to docs layout, and switch docker-compose image tags to 'latest' for consistency and clarity. commit b443fcb0103a8f676c598507860314d2c24a5e92 Author: Daniel Luiz Alves Date: Thu Apr 24 23:31:40 2025 -0300 docs: update image URLs in README.md Update the image URLs in the README.md file to use the new Cloudinary links for better reliability and consistency commit d106b5346fbcd6f20a7c2baafccc1c5af6bb6ad9 Author: Daniel Luiz Alves Date: Thu Apr 24 23:28:30 2025 -0300 docs: update documentation links and README content Update all documentation links from 'palmr-docs.kyantech.com.br' to 'palmr.kyantech.com.br' to reflect the new URL. Additionally, update the README.md to include the latest frontend technology stack and correct the screenshot image link. Also, add a hyperlink to the core maintainer's GitHub profile. commit 7a6df5130823f3bcd7a9f1ef38bcd18c19098bfe Author: Daniel Luiz Alves Date: Thu Apr 24 23:14:25 2025 -0300 refactor(home): update layout, image URLs, and documentation links - Remove unnecessary spaces in JSX elements for cleaner code - Add images configuration to next.config.mjs to support remote image sources - Replace old image URLs with new Cloudinary-hosted images - Update documentation links to include an icon for better UX commit e40254fea6e2de276c4ffea5d91bcdc398b50262 Author: Daniel Luiz Alves Date: Thu Apr 24 20:17:04 2025 -0300 feat(home-page): redesign home page with interactive components Added new interactive components like animated grids, pulsating buttons, and ripple effects to enhance the user experience. Updated the layout to include sections for features, architecture, and file sharing. Improved the overall design with modern animations and typography. commit a3ed862ed97262616ffb3ff146ec4f8e42af201e Author: Daniel Luiz Alves Date: Thu Apr 24 12:12:11 2025 -0300 docs: add new documentation pages for Palmr 2.0.0-beta This commit introduces several new documentation pages for the Palmr 2.0.0-beta release. The added pages cover topics such as SMTP configuration, available languages, GitHub sponsorship, starring the repository, opening issues, generating shares, and contributing to the project. These additions aim to provide comprehensive guidance for users and contributors, enhancing the overall user experience and supporting the project's growth. commit 7904333b157de86128d59d3bd5564853024914fc Author: Daniel Luiz Alves Date: Wed Apr 23 16:59:06 2025 -0300 docs: add API documentation and update meta.json for 1.1.7-beta and 2.0.0-beta This commit introduces API documentation files for both 1.1.7-beta and 2.0.0-beta versions, including detailed guides on accessing and using Scalar and Swagger-based API documentation. Additionally, it updates the meta.json files for both versions to include the new API section and other relevant entries. The global.css file has also been updated to improve styling for code blocks and headings. commit 57af56ff7ee6606776e461d748f9dd9dd40989cc Author: Daniel Luiz Alves Date: Tue Apr 22 17:46:31 2025 -0300 feat(docs): update and enhance documentation for v2.0.0-beta Add new architecture, installation, and GitHub architecture documentation. Include new banner and architecture images. Refactor meta.json and index.mdx for better structure and clarity. Add sponsor and footer components to the docs layout. Update docker-compose.yaml with new environment variables and port configurations. Remove outdated files and streamline content for v2.0.0-beta release. commit a2a5b6a88b32d7bb0f4fff9966c3a29ec18044b8 Author: Daniel Luiz Alves Date: Thu Apr 17 11:49:32 2025 -0300 refactor: replace Image component with img tag for app logo The commit replaces the Next.js `Image` component with the standard HTML `img` tag in the app logo rendering. This change simplifies the implementation and removes unnecessary dependencies. Additionally, the `env` import was removed from the seed file, the docker-compose image tag was updated to a specific version, and remote image patterns were added to the Next.js config. commit fccc9d559ff7299b583c14dac64ef9f482602975 Author: Daniel Luiz Alves Date: Thu Apr 17 01:16:38 2025 -0300 chore: remove docker-compose-local.yaml file The file was deleted as it is no longer needed for the local development setup. This change simplifies the project structure and reduces maintenance overhead. commit c1fc52c30227af2f1c4e57a15cee6b607569215d Author: Daniel Luiz Alves Date: Thu Apr 17 01:15:19 2025 -0300 feat(docs): migrate documentation to Next.js with Fumadocs This commit migrates the documentation site from Astro to Next.js, leveraging Fumadocs for enhanced functionality and maintainability. The migration includes: - New Next.js configuration and setup - Integration of Fumadocs for documentation rendering - Addition of new documentation assets and images - Removal of Astro-related files and configurations The migration aims to improve the documentation site's performance, scalability, and developer experience. commit dca252827caa95a1cf3fd2b0ebc95766b0ef2d20 Author: Daniel Luiz Alves Date: Wed Apr 16 15:24:20 2025 -0300 refactor: remove deprecated Makefile and generate-docker-compose.sh The Makefile and generate-docker-compose.sh script were removed as they are no longer needed. The docker-compose.yaml file was updated to include inline comments and use the latest image tag for the palmr-app service. This cleanup simplifies the project structure and ensures clarity in the docker-compose configuration. commit 32bc17c373cd188675eb41d54cd9812044bb6710 Author: Daniel Luiz Alves Date: Wed Apr 16 14:36:16 2025 -0300 chore: update .gitignore and docker-compose.yaml for better configuration - Add `.env` to .gitignore to ignore environment variables file - Update docker-compose.yaml to use environment variables for configuration and improve comments for clarity commit efba0b75dcc46f6f408ac6e731c51dfa6a64a32f Author: Daniel Luiz Alves Date: Wed Apr 16 13:53:51 2025 -0300 refactor(web): restructure and clean up project files Restructured the project by moving and deleting unused files, updating configurations, and organizing code for better maintainability. This includes removing deprecated models, updating environment settings, and consolidating utility functions. commit a119ab4d4699ae2edc159e5ddeaab915f8cbba0b Author: Daniel Luiz Alves Date: Wed Apr 16 13:40:54 2025 -0300 build(web): add Dockerfile and docker-compose.yml for production deployment Refactor image handling in components to use Next.js Image component Remove unused imports and disable ESLint during builds Add error logging for i18n and login functionality Update Next.js config for standalone output and build optimizations commit d25f493c7ae2527c5abacbe27a68bb703d758be7 Author: Daniel Luiz Alves Date: Wed Apr 16 11:17:48 2025 -0300 feat(i18n): add theme translation support for multiple languages Add theme-related translations (toggle, light, dark, system) to JSON files for all supported languages. Update the mode-toggle component to use these translations for theme switching. Also, refactor API route files to improve code consistency and readability. commit 78e2d05d6c8cfe7e0a3858be988ccf6fe64708a3 Author: Daniel Luiz Alves Date: Wed Apr 16 10:52:20 2025 -0300 refactor(api): migrate API endpoints to use proxy routes and update axios instance This commit introduces proxy routes for all API endpoints and updates the axios instance to use the new proxy routes. The changes ensure that all API requests are routed through the Next.js API routes, improving security and consistency. Additionally, the axios instance is renamed to `apiInstance` to reflect its purpose more accurately. The metadata generation in layout files is also simplified by removing unnecessary API calls. commit 564ff43843e1f41219ea165db9c3eb3ab717a885 Author: Daniel Luiz Alves Date: Tue Apr 15 10:21:30 2025 -0300 chore: remove unused SVG files and refactor login types Clean up the codebase by deleting unused SVG assets and improve code readability by adding proper spacing and type definitions in the login module commit 5aea36fd98d2ba2f527092ff40ecc292f9ae728f Author: Daniel Luiz Alves Date: Mon Apr 14 16:55:36 2025 -0300 feat: add forgot and reset password functionality Implement forgot and reset password features, including form components, hooks for form handling, and layout/page components. This allows users to request a password reset and set a new password securely. commit 7d6e484c2b5f15f8f024fb420779090eca9be3ba Author: Daniel Luiz Alves Date: Mon Apr 14 15:55:15 2025 -0300 feat(shares): add share management and public share components This commit introduces new components and hooks for managing shares and viewing public shares. It includes the following key changes: - Added components for share management, such as `SharesHeader`, `SharesSearch`, and `SharesTableContainer`. - Implemented `useShares` hook to handle share data fetching and state management. - Created `PublicSharePage` and related components for viewing public shares, including `ShareDetails`, `PasswordModal`, and `ShareNotFound`. - Added `usePublicShare` hook to manage public share data and password handling. - Updated layout and types to support the new features. commit e50abf953ebdef7c0a5efa32109ab5f35510e16e Author: Daniel Luiz Alves Date: Mon Apr 14 15:21:31 2025 -0300 feat(shares): add shares page with search, table, and modals Introduce a new shares page that includes a search bar, shares table, and various modals for managing shares. The page supports creating, editing, deleting, and generating links for shares. Additionally, it includes functionality for notifying recipients and viewing share details. The layout and components are designed to be reusable and maintainable. commit 15dce5dab129ac6007dc6875c1c914faab8e07a8 Author: Daniel Luiz Alves Date: Mon Apr 14 11:53:43 2025 -0300 feat(layout): add app name to page titles and implement favicon component Add app name to page titles by fetching it from the configs endpoint. Introduce a new `Favicon` component to handle dynamic favicon rendering based on the app logo. Remove manual favicon updates from the app info context as it is now handled by the `Favicon` component. commit 20fee6b449c970bfce5008ce9f70291911c75339 Author: Daniel Luiz Alves Date: Mon Apr 14 10:37:00 2025 -0300 refactor(users-management): reorganize imports and clean up code for better readability This commit focuses on improving the readability and maintainability of the users-management module by reorganizing imports, removing unnecessary whitespace, and standardizing code formatting. No functional changes were made. commit e03ca7e0dc69e1d5895bde6a3b6a868129c948ab Author: Daniel Luiz Alves Date: Mon Apr 14 10:30:45 2025 -0300 feat(users-management): add users management module Introduce a new users management module that includes features for creating, reading, updating, and deleting users. The module includes components for user tables, modals for user actions, and hooks for managing user state and interactions. This replaces the previous admin page with a more comprehensive and modular approach to user management. commit ab6c634782e4501715c8ae40afa4f7ad51027ed8 Author: Daniel Luiz Alves Date: Fri Apr 11 16:45:03 2025 -0300 feat(profile): add profile page with form, password, and image components Introduce a new profile page that includes forms for updating user profile information, changing passwords, and managing profile pictures. The page is protected and integrates with the existing authentication system. Additionally, update validation messages for better clarity and consistency. commit 6a933891c84ff0e4fccfc120c7fc41ed63d51e4e Author: Daniel Luiz Alves Date: Fri Apr 11 16:43:51 2025 -0300 refactor(settings): reorganize imports and improve code readability Restructured imports across multiple files to follow a consistent order and improve readability. Also, adjusted some code formatting for better maintainability. commit 5cd7acc1589b19455009950ad019ed3050ecc343 Author: Daniel Luiz Alves Date: Fri Apr 11 15:47:42 2025 -0300 feat(settings): add settings page with layout, form, and components Introduce a new settings page with a structured layout, form components, and hooks for managing application settings. This includes the addition of settings-specific types, constants, and UI components such as `SettingsForm`, `SettingsGroup`, and `SettingsInput`. The `useSettings` hook handles configuration loading and updates, while the `LogoInput` component manages logo uploads and removal. The `Select` component from Radix UI is also added to support dropdown functionality. commit b4cecf9e32329e53012ff24ac498546b0b1b31a3 Author: Daniel Luiz Alves Date: Fri Apr 11 15:01:32 2025 -0300 style: reorganize imports and format code for consistency Refactor import statements and code formatting across multiple files to improve readability and maintain consistency. This includes reordering imports, fixing linting issues, and standardizing code style. commit e55f090235e5b61dd5dbd16333d41f93341c7c23 Author: Daniel Luiz Alves Date: Fri Apr 11 14:59:52 2025 -0300 feat(files): add file management components and hooks Introduce new components and hooks for managing files, including file list, search bar, empty state, and modals. This includes the addition of a breadcrumb component for better navigation and the use of client-side rendering for specific components. The changes aim to improve the user experience and maintainability of the file management system. commit 0a738430e7f6b8342fda1234e2e0680b5a401e51 Author: Daniel Luiz Alves Date: Fri Apr 11 14:18:11 2025 -0300 feat: add new utility functions and UI components for file management This commit introduces several new utility functions and UI components to enhance file management capabilities. Key additions include: - `generateSafeFileName` utility for creating safe file names. - `customNanoid` utility for generating custom IDs. - New UI components: `AspectRatio`, `Loader`, `Switch`, `ScrollArea`, and various modals for file actions, share management, and file preview. - Updated translations and package dependencies to support new features. commit 6c7117cc149fa37547a9078f1edf4cf09a727b08 Author: Daniel Luiz Alves Date: Wed Apr 9 15:57:09 2025 -0300 style: format code and fix linting issues across multiple files Refactor code to improve readability and consistency by applying Prettier formatting rules. This includes fixing trailing commas, sorting imports, and ensuring consistent code style. No functional changes were made. commit 61cf88b41f7c1e78a1e02e654d83e6a2fcd7d2f8 Author: Daniel Luiz Alves Date: Wed Apr 9 15:48:00 2025 -0300 feat(dashboard): add dashboard components and utilities This commit introduces new components and utilities for the dashboard, including storage usage, quick access cards, recent files, and recent shares. It also adds file and share management hooks, along with new UI components like progress bars, separators, and avatars. The changes enhance the dashboard's functionality and improve user experience by providing quick access to essential features and better visual feedback. The commit includes: - New components for storage usage, quick access, recent files, and shares - File and share management hooks for CRUD operations - Utility functions for file size formatting and file icons - New UI components like progress bars, separators, and avatars - Updated translations and styles for consistency commit b077154c22f027a3c3d0557c20b431bb3fb413e6 Author: Daniel Luiz Alves Date: Tue Apr 8 15:06:17 2025 -0300 feat(auth): add protected routes and enhance auth context Implement protected routes for admin and dashboard pages to restrict access based on authentication and admin status. Enhance the auth context to handle user data validation and improve error handling during authentication checks. commit 9e35d27497f2c3c23ca6a9c2cc3d73bb875dab7d Author: Daniel Luiz Alves Date: Mon Apr 7 16:14:18 2025 -0300 feat: add initial project setup with config, models, and assets This commit introduces the initial project setup including configuration files, API models, and necessary assets. The changes include: - Added Prettier and PostCSS configuration files - Included favicon and public assets like SVGs - Set up Next.js and theme provider configurations - Added TypeScript models for API endpoints and responses commit da64d65401c4a7619d152924aed71c7af6bb7adf Merge: ca7bdef 7b2f15d Author: Daniel Luiz Alves Date: Fri Apr 4 23:40:35 2025 -0300 feat: enable reverse proxy support and add pnpm.lock for custom builds in apps/web (#13) commit 7b2f15dcd599ee1ff388b0cc9a5e548e6f1c5cfc Author: Daniel Luiz Alves Date: Fri Apr 4 23:37:08 2025 -0300 refactor: remove lock files from .gitignore and update vite config Remove unnecessary lock files from .gitignore to streamline version control. Update Vite configuration to allow all hosts in both development and preview modes for better accessibility commit ca7bdefcdb3d507e6dce6ab23d46585bba257607 Merge: 92b437e 1768aa8 Author: Daniel Luiz Alves Date: Fri Apr 4 00:44:02 2025 -0300 Merge branch 'main' of github.com:kyantech/Palmr commit 92b437ee369149ff7a878ba9cfa80520b012a08d Author: Daniel Luiz Alves Date: Fri Apr 4 00:41:55 2025 -0300 chore: bump version to 1.1.6 across all apps commit fcaef88850ec953b75c71b409492f5bbb46f45f3 Author: Daniel Luiz Alves Date: Fri Apr 4 00:40:49 2025 -0300 docs: update installation guide with security and deployment details Add a new section "Quick Start with Default Docker Compose" to emphasize the risks of using default credentials and provide recommendations for secure deployment. Clarify the usage of Docker Compose for different environments (local, production) and update port configuration recommendations with a warning about ReactJS limitations. commit 68d6fd09afac484063ca23df738b93eab1112f46 Author: Daniel Luiz Alves Date: Fri Apr 4 00:12:02 2025 -0300 chore: add docker-compose.yaml and update .gitignore Add docker-compose.yaml to define services for the application stack, including API, app, MinIO, and PostgreSQL. Remove docker-compose.yaml from .gitignore to track it in version control commit 1768aa81b777bf8fbdc184fabd628a18e4451071 Author: Daniel Luiz Alves Date: Thu Apr 3 16:16:27 2025 -0300 Update README.md commit 644fc7aa309841f0914d8d2c03a790605385b0d2 Author: Daniel Luiz Alves Date: Thu Apr 3 16:15:34 2025 -0300 Update README.md commit cc6fe6d62e337ec2fed6eaf44c8242d4291d440c Author: Daniel Luiz Alves Date: Thu Apr 3 16:15:06 2025 -0300 Update README.md --- .gitignore | 4 +- Makefile | 3 - README.md | 24 +- apps/docs/.eslintrc.json | 3 + apps/docs/.gitignore | 31 +- apps/docs/.vscode/css.json | 55 - apps/docs/.vscode/extensions.json | 10 - apps/docs/.vscode/settings.json | 51 - apps/docs/README.md | 26 + apps/docs/astro.config.mjs | 58 - apps/docs/components.json | 21 + .../docs/1.1.7-beta/api.md} | 8 +- .../docs/1.1.7-beta}/architecture.md | 2 +- .../docs/1.1.7-beta}/available-languages.md | 2 +- .../docs/1.1.7-beta}/configuring-smtp.md | 8 +- .../docs/1.1.7-beta}/contribute.md | 2 +- .../docs/1.1.7-beta}/generate-share.md | 38 +- .../docs/1.1.7-beta}/gh-sponsor.md | 4 +- .../docs/1.1.7-beta}/gh-star.md | 4 +- .../docs/1.1.7-beta}/github-architecture.md | 0 .../docs => content/docs/1.1.7-beta}/index.md | 4 +- .../docs/1.1.7-beta}/installation.mdx | 48 +- .../main => content/docs/1.1.7-beta}/login.md | 12 +- .../docs/1.1.7-beta}/manage-users.md | 17 +- .../docs/1.1.7-beta}/manual-installation.mdx | 0 apps/docs/content/docs/1.1.7-beta/meta.json | 28 + .../docs/1.1.7-beta}/open-an-issue.md | 6 +- .../docs/1.1.7-beta}/upload.md | 22 +- apps/docs/content/docs/2.0.0-beta/api.mdx | 48 + .../content/docs/2.0.0-beta/architecture.mdx | 62 + .../docs/2.0.0-beta/available-languages.mdx | 52 + .../docs/2.0.0-beta/configuring-smtp.mdx | 67 + .../content/docs/2.0.0-beta/contribute.mdx | 217 + .../content/docs/2.0.0-beta/first-login.mdx | 108 + .../docs/2.0.0-beta/generate-share.mdx | 152 + .../content/docs/2.0.0-beta/gh-sponsor.mdx | 110 + apps/docs/content/docs/2.0.0-beta/gh-star.mdx | 127 + .../docs/2.0.0-beta/github-architecture.mdx | 145 + apps/docs/content/docs/2.0.0-beta/index.mdx | 52 + .../content/docs/2.0.0-beta/installation.mdx | 260 + .../content/docs/2.0.0-beta/manage-users.mdx | 81 + .../docs/2.0.0-beta/manual-installation.mdx | 212 + apps/docs/content/docs/2.0.0-beta/meta.json | 29 + .../content/docs/2.0.0-beta/open-an-issue.mdx | 137 + .../docs/2.0.0-beta/uploading-files.mdx | 91 + apps/docs/content/docs/meta.json | 3 + apps/docs/next.config.mjs | 29 + apps/docs/package.json | 42 +- apps/docs/pnpm-lock.yaml | 6541 +++++++++++------ apps/docs/postcss.config.mjs | 5 + .../{ => assets/v1}/api-docs/scalar.png | Bin .../{ => assets/v1}/api-docs/swagger.png | Bin .../{ => assets/v1}/developers/issues-tab.png | Bin .../v1}/developers/new-issue-btn.png | Bin .../v1}/developers/new-issue-form.png | Bin .../{ => assets/v1}/general/architecture.png | Bin .../public/{ => assets/v1}/general/banner.png | Bin .../public/{ => assets/v1}/general/lp.png | Bin .../v1}/main/files/actions-dropdown.png | Bin .../{ => assets/v1}/main/files/edit-modal.png | Bin .../v1}/main/files/my-files-card.png | Bin .../v1}/main/files/my-files-page.png | Bin .../v1}/main/language/language-selector.png | Bin .../v1}/main/shares/actions-column.png | Bin .../v1}/main/shares/copy-link-modal.png | Bin .../v1}/main/shares/create-first-share.png | Bin .../v1}/main/shares/create-share-modal.png | Bin .../v1}/main/shares/delete-share-modal.png | Bin .../v1}/main/shares/dropdown-with-copy.png | Bin .../v1}/main/shares/edit-share-modal.png | Bin .../main/shares/generate-share-link-modal.png | Bin .../v1}/main/shares/manage-files-modal.png | Bin .../main/shares/manage-recipients-modal.png | Bin .../v1}/main/shares/my-shares-card.png | Bin .../v1}/main/shares/my-shares-page.png | Bin .../v1}/main/shares/new-share-btn.png | Bin .../v1}/main/shares/recent-shares-filled.png | Bin .../v1}/main/shares/share-details-modal.png | Bin .../v1}/main/shares/share-screen.png | Bin .../v1}/main/shares/share-section.png | Bin .../v1}/main/shares/shares-table.png | Bin .../v1}/main/shares/view-all-button.png | Bin .../{ => assets/v1}/main/smtp/closed-card.png | Bin .../v1}/main/smtp/dropdown-menu.png | Bin .../{ => assets/v1}/main/smtp/opened-card.png | Bin .../v1}/main/smtp/smtp-enabled.png | Bin .../v1}/main/upload/new-upload-button.png | Bin .../v1}/main/upload/preview-example.png | Bin .../v1}/main/upload/recent-uploads-filled.png | Bin .../v1}/main/upload/recent-uploads.png | Bin .../v1}/main/upload/upload-cancel-buttons.png | Bin .../v1}/main/upload/upload-file-button.png | Bin .../v1}/main/upload/view-all-button.png | Bin .../main/users/add-user-actions-dropdown.png | Bin .../v1}/main/users/add-user-modal.png | Bin .../v1}/main/users/add-users-btn.png | Bin .../v1}/main/users/edit-user-modal.png | Bin .../v1}/main/users/new-user-table.png | Bin .../v1}/main/users/users-management.png | Bin .../{ => assets/v1}/sponsor/sponsor-btn.png | Bin .../{ => assets/v1}/sponsor/sponsor-page.png | Bin .../{ => assets/v1}/sponsor/star-btn.png | Bin .../v1}/sponsor/starred-button.png | Bin .../public/{ => assets/v1}/ui/dashboard.png | Bin apps/docs/public/{ => assets/v1}/ui/login.png | Bin apps/docs/public/{ => assets/v1}/ui/menu.png | Bin .../public/{ => assets/v1}/ui/profile.png | Bin .../{ => assets/v1}/ui/profile_picture.png | Bin .../docs/public/assets/v2/api-docs/scalar.png | Bin 0 -> 227725 bytes .../public/assets/v2/api-docs/swagger.png | Bin 0 -> 185853 bytes .../public/assets/v2/general/architecture.png | Bin 0 -> 237710 bytes apps/docs/public/assets/v2/general/banner.png | Bin 0 -> 46372 bytes apps/docs/public/favicon.ico | Bin 0 -> 4286 bytes apps/docs/public/favicon.svg | 10 - apps/docs/source.config.ts | 12 + apps/docs/src/app/(home)/layout.tsx | 13 + apps/docs/src/app/(home)/page.tsx | 370 + apps/docs/src/app/api/search/route.ts | 16 + apps/docs/src/app/docs/[[...slug]]/page.tsx | 62 + apps/docs/src/app/docs/components/footer.tsx | 19 + apps/docs/src/app/docs/components/sponsor.tsx | 17 + apps/docs/src/app/docs/layout.tsx | 12 + apps/docs/src/app/global.css | 196 + apps/docs/src/app/layout.config.tsx | 25 + apps/docs/src/app/layout.tsx | 51 + .../magicui/animated-grid-pattern.tsx | 154 + .../docs/src/components/magicui/particles.tsx | 313 + .../components/magicui/pulsating-button.tsx | 46 + .../src/components/magicui/ripple-button.tsx | 91 + .../components/magicui/typing-animation.tsx | 90 + .../src/components/magicui/word-rotate.tsx | 50 + apps/docs/src/components/ui/3d-marquee.tsx | 142 + .../src/components/ui/text-hover-effect.tsx | 134 + apps/docs/src/content.config.ts | 7 - apps/docs/src/lib/source.ts | 9 + apps/docs/src/lib/utils.ts | 6 + apps/docs/src/mdx-components.tsx | 10 + apps/docs/src/styles/custom.css | 162 - apps/docs/tsconfig.json | 48 +- apps/server/.env.example | 4 +- apps/server/package.json | 2 +- apps/server/prisma/seed.ts | 1 - apps/server/src/config/minio.config.local.ts | 2 +- apps/server/src/env.ts | 3 +- apps/web/.env | 1 - apps/web/.env.example | 2 +- apps/web/.eslintignore | 20 - apps/web/.eslintrc.json | 120 - apps/web/.gitignore | 59 +- apps/web/.npmrc | 2 - apps/web/.prettierignore | 4 + apps/web/.prettierrc.json | 11 +- apps/web/Dockerfile | 48 +- apps/web/README.md | 1 - apps/web/components.json | 21 + apps/web/docker-compose.yml | 17 + apps/web/eslint.config.mjs | 66 + apps/web/index.html | 36 - apps/web/{src/locales => messages}/ar-SA.json | 508 +- apps/web/{src/locales => messages}/de-DE.json | 508 +- apps/web/{src/locales => messages}/en-US.json | 523 +- apps/web/{src/locales => messages}/es-ES.json | 508 +- apps/web/{src/locales => messages}/fr-FR.json | 508 +- apps/web/{src/locales => messages}/hi-IN.json | 508 +- apps/web/{src/locales => messages}/ja-JP.json | 508 +- apps/web/{src/locales => messages}/ko-KR.json | 508 +- apps/web/{src/locales => messages}/pt-BR.json | 508 +- apps/web/{src/locales => messages}/ru-RU.json | 508 +- apps/web/{src/locales => messages}/tr-TR.json | 508 +- apps/web/{src/locales => messages}/zh-CN.json | 506 +- apps/web/next.config.ts | 27 + apps/web/orval.config.ts | 10 - apps/web/package.json | 133 +- apps/web/pnpm-lock.yaml | 5687 ++++++++++++++ apps/web/postcss.config.js | 6 - apps/web/postcss.config.mjs | 5 + apps/web/routes.json | 1 - apps/web/src/App.tsx | 85 - .../app/(home)/components/home-content.tsx | 73 + .../src/app/(home)/components/home-header.tsx | 50 + apps/web/src/app/(home)/components/navbar.tsx | 91 + apps/web/src/app/(home)/hooks/use-home.ts | 52 + apps/web/src/app/(home)/layout.tsx | 14 + .../src/{pages/home => app/(home)}/page.tsx | 14 +- .../{pages/home => app/(home)}/types/index.ts | 5 + .../s/[alias]/components/files-table.tsx | 78 + .../s/[alias]/components/password-modal.tsx | 42 + .../s}/[alias]/components/share-details.tsx | 21 +- .../s}/[alias]/components/share-header.tsx | 10 +- .../s/[alias]/components/share-not-found.tsx | 24 + .../s}/[alias]/hooks/use-public-share.ts | 18 +- .../web/src/app/(shares)/s/[alias]/layout.tsx | 18 + .../share => app/(shares)/s}/[alias]/page.tsx | 13 +- .../(shares)/s}/[alias]/types/index.tsx | 0 .../shares/components/empty-shares-state.tsx | 14 +- .../shares/components/shares-header.tsx | 44 + .../shares/components/shares-modals.tsx | 2 +- .../shares/components/shares-search.tsx | 48 + .../components/shares-table-container.tsx | 2 +- .../(shares)}/shares/hooks/use-shares.ts | 22 +- apps/web/src/app/(shares)/shares/layout.tsx | 18 + apps/web/src/app/(shares)/shares/page.tsx | 84 + .../(shares)}/shares/types/index.ts | 26 +- .../app/api/(proxy)/app/check-upload/route.ts | 28 + .../src/app/api/(proxy)/app/configs/route.ts | 30 + .../app/api/(proxy)/app/disk-space/route.ts | 28 + .../src/app/api/(proxy)/app/health/route.ts | 28 + .../web/src/app/api/(proxy)/app/info/route.ts | 28 + .../app/api/(proxy)/app/remove-logo/route.ts | 28 + .../app/api/(proxy)/app/upload-logo/route.ts | 29 + .../api/(proxy)/auth/forgot-password/route.ts | 28 + .../src/app/api/(proxy)/auth/login/route.ts | 29 + .../src/app/api/(proxy)/auth/logout/route.ts | 28 + apps/web/src/app/api/(proxy)/auth/me/route.ts | 28 + .../api/(proxy)/auth/reset-password/route.ts | 28 + .../src/app/api/(proxy)/config/list/route.ts | 28 + .../api/(proxy)/config/update/[key]/route.ts | 33 + .../api/(proxy)/config/update/bulk/route.ts | 32 + .../(download)/[objectName]/download/route.ts | 33 + .../api/(proxy)/files/delete/[id]/route.ts | 30 + .../files/generate-presigned-url/route.ts | 31 + .../src/app/api/(proxy)/files/list/route.ts | 28 + .../app/api/(proxy)/files/register/route.ts | 32 + .../api/(proxy)/files/update/[id]/route.ts | 33 + .../shares/alias/create/[shareId]/route.ts | 32 + .../(proxy)/shares/alias/get/[alias]/route.ts | 32 + .../app/api/(proxy)/shares/create/route.ts | 32 + .../api/(proxy)/shares/delete/[id]/route.ts | 29 + .../(proxy)/shares/details/[shareId]/route.ts | 34 + .../shares/files/add/[shareId]/route.ts | 32 + .../shares/files/remove/[shareId]/route.ts | 32 + .../src/app/api/(proxy)/shares/list/route.ts | 29 + .../shares/password/update/shareId/route.ts | 32 + .../shares/recipients/add/[shareId]/route.ts | 32 + .../recipients/notify/[shareId]/route.ts | 32 + .../recipients/remove/[shareId]/route.ts | 32 + .../app/api/(proxy)/shares/update/route.ts | 32 + .../api/(proxy)/users/activate/[id]/route.ts | 29 + .../api/(proxy)/users/avatar/remove/route.ts | 29 + .../api/(proxy)/users/avatar/upload/route.ts | 29 + .../(proxy)/users/deactivate/[id]/route.ts | 29 + .../api/(proxy)/users/delete/[id]/route.ts | 29 + .../api/(proxy)/users/details/[id]/route.ts | 32 + .../src/app/api/(proxy)/users/list/route.ts | 32 + .../app/api/(proxy)/users/register/route.ts | 32 + .../(proxy)/users/update-image/[id]/route.ts | 32 + .../src/app/api/(proxy)/users/update/route.ts | 32 + .../dashboard/components/empty-file-state.tsx | 19 + .../components/empty-shares-state.tsx | 21 + .../components/quick-access-cards.tsx | 34 +- .../app/dashboard/components/recent-files.tsx | 59 + .../dashboard/components/recent-shares.tsx | 62 +- .../dashboard/components/storage-usage.tsx | 42 + .../dashboard/hooks/use-dashboard.ts | 25 +- apps/web/src/app/dashboard/layout.tsx | 18 + .../dashboard/modals/dashboard-modals.tsx | 2 +- apps/web/src/app/dashboard/page.tsx | 72 + .../{pages => app}/dashboard/types/index.ts | 0 .../dashboard/utils/format-storage-size.ts | 0 apps/web/{ => src/app}/favicon.ico | Bin .../src/app/files/components/empty-state.tsx | 20 + .../files/components/file-list.tsx | 8 +- .../files/components/header.tsx | 12 +- .../src/app/files/components/search-bar.tsx | 28 + .../{pages => app}/files/hooks/use-files.ts | 18 +- apps/web/src/app/files/layout.tsx | 18 + .../files/modals/files-modals.tsx | 2 +- apps/web/src/app/files/page.tsx | 42 + .../src/{pages => app}/files/types/index.ts | 0 .../components/forgot-password-form.tsx | 48 + .../components/forgot-password-header.tsx | 10 +- .../hooks/use-forgot-password.ts | 15 +- apps/web/src/app/forgot-password/layout.tsx | 18 + .../{pages => app}/forgot-password/page.tsx | 16 +- .../forgot-password/types/index.ts | 3 +- apps/web/src/app/globals.css | 122 + apps/web/src/app/layout.tsx | 56 + .../src/app/login/components/login-form.tsx | 106 + .../src/app/login/components/login-header.tsx | 28 + .../components/password-visibility-toggle.tsx | 25 + .../components/static-background-lights.tsx | 0 apps/web/src/app/login/hooks/use-login.ts | 87 + apps/web/src/app/login/layout.tsx | 18 + apps/web/src/{pages => app}/login/page.tsx | 27 +- apps/web/src/app/login/schemas/schema.ts | 12 + .../src/{pages => app}/login/types/index.ts | 3 +- .../app/profile/components/password-form.tsx | 79 + .../app/profile/components/profile-form.tsx | 77 + .../app/profile/components/profile-header.tsx | 44 + .../profile/components/profile-picture.tsx | 84 + .../profile/hooks/use-profile.ts | 16 +- apps/web/src/app/profile/layout.tsx | 18 + apps/web/src/app/profile/page.tsx | 49 + .../src/{pages => app}/profile/types/index.ts | 3 +- .../components/reset-password-form.tsx | 94 + .../components/reset-password-header.tsx | 8 +- .../hooks/use-reset-password.ts | 22 +- apps/web/src/app/reset-password/layout.tsx | 18 + .../{pages => app}/reset-password/page.tsx | 29 +- .../reset-password/types/index.ts | 3 +- .../settings/components/logo-input.tsx | 43 +- .../settings/components/settings-form.tsx | 3 +- .../settings/components/settings-group.tsx | 49 +- .../settings/components/settings-header.tsx | 44 + .../settings/components/settings-input.tsx | 57 +- .../src/{pages => app}/settings/constants.ts | 18 +- .../settings/hooks/use-settings.ts | 29 +- apps/web/src/app/settings/layout.tsx | 18 + apps/web/src/app/settings/page.tsx | 38 + .../{pages => app}/settings/types/index.ts | 2 +- .../components/user-actions-dropdown.tsx | 45 + .../components/user-delete-modal.tsx | 35 + .../components/user-form-modal.tsx | 109 + .../components/user-management-modals.tsx | 0 .../components/user-status-modal.tsx | 31 +- .../components/users-header.tsx | 52 + .../components/users-table.tsx | 78 + .../hooks/use-user-management.ts | 25 +- apps/web/src/app/users-management/layout.tsx | 18 + apps/web/src/app/users-management/page.tsx | 71 + .../users-management/types/index.ts | 5 +- .../src/components/auth/protected-route.tsx | 35 + .../src/components/general/file-selector.tsx | 41 +- .../components/general/language-switcher.tsx | 95 +- .../src/components/general/mode-toggle.tsx | 36 + .../components/general/recipient-selector.tsx | 55 +- .../src/components/general/theme-switch.tsx | 29 - apps/web/src/components/layout/favicon.tsx | 14 + .../components/layout/file-manager-layout.tsx | 51 +- .../src/components/layout/loading-screen.tsx | 9 +- apps/web/src/components/layout/navbar.tsx | 157 +- .../layout/share-manager-layout.tsx | 36 - .../components/modals/create-share-modal.tsx | 116 +- .../components/modals/file-actions-modals.tsx | 125 +- .../components/modals/file-preview-modal.tsx | 82 +- .../modals/generate-share-link-modal.tsx | 85 +- .../modals/share-actions-modals.tsx | 195 +- .../components/modals/share-details-modal.tsx | 117 +- .../components/modals/upload-file-modal.tsx | 125 +- .../route-protector/admin-protected-route.tsx | 21 - .../route-protector/protected-route.tsx | 17 - .../web/src/components/tables/files-table.tsx | 159 +- .../src/components/tables/shares-table.tsx | 272 +- apps/web/src/components/ui/aspect-ratio.tsx | 9 + apps/web/src/components/ui/avatar.tsx | 34 + .../ui}/background-lights.tsx | 0 apps/web/src/components/ui/badge.tsx | 36 + apps/web/src/components/ui/breadcrumb.tsx | 92 + apps/web/src/components/ui/button.tsx | 50 + apps/web/src/components/ui/card.tsx | 59 + apps/web/src/components/ui/default-footer.tsx | 9 +- apps/web/src/components/ui/dialog.tsx | 111 + apps/web/src/components/ui/dropdown-menu.tsx | 219 + apps/web/src/components/ui/form.tsx | 138 + apps/web/src/components/ui/grid-pattern.tsx | 15 - apps/web/src/components/ui/input.tsx | 21 + apps/web/src/components/ui/label.tsx | 21 + apps/web/src/components/ui/loader.tsx | 30 + apps/web/src/components/ui/progress.tsx | 24 + apps/web/src/components/ui/scroll-area.tsx | 48 + apps/web/src/components/ui/select.tsx | 160 + apps/web/src/components/ui/separator.tsx | 28 + apps/web/src/components/ui/sheet.tsx | 103 + apps/web/src/components/ui/switch.tsx | 28 + apps/web/src/components/ui/table.tsx | 75 + apps/web/src/config/{axios.ts => api.ts} | 5 +- apps/web/src/config/i18n.ts | 79 - apps/web/src/config/site.ts | 6 +- apps/web/src/contexts/app-info-context.tsx | 107 +- apps/web/src/contexts/auth-context.tsx | 13 +- .../{ShareContext.tsx => share-context.tsx} | 5 +- apps/web/src/hooks/use-disclosure.ts | 18 + apps/web/src/hooks/use-file-manager.ts | 3 +- apps/web/src/hooks/use-page-title.ts | 10 - apps/web/src/hooks/use-share-manager.ts | 20 +- apps/web/src/hooks/use-theme.ts | 44 - apps/web/src/http/endpoints/app/index.ts | 35 +- apps/web/src/http/endpoints/app/types.ts | 13 +- apps/web/src/http/endpoints/auth/index.ts | 33 +- apps/web/src/http/endpoints/auth/types.ts | 5 +- apps/web/src/http/endpoints/config/index.ts | 23 +- apps/web/src/http/endpoints/config/types.ts | 9 +- apps/web/src/http/endpoints/files/index.ts | 37 +- apps/web/src/http/endpoints/files/types.ts | 9 +- apps/web/src/http/endpoints/shares/index.ts | 81 +- apps/web/src/http/endpoints/shares/types.ts | 31 +- apps/web/src/http/endpoints/users/index.ts | 41 +- apps/web/src/http/endpoints/users/types.ts | 19 +- apps/web/src/i18n/request.ts | 25 + apps/web/src/lib/i18n-mock.ts | 25 + apps/web/src/lib/utils.ts | 11 + apps/web/src/main.tsx | 18 - .../dashboard/components/recent-files.tsx | 73 - .../dashboard/components/storage-usage.tsx | 36 - apps/web/src/pages/dashboard/page.tsx | 69 - .../pages/files/components/empty-state.tsx | 18 - .../src/pages/files/components/search-bar.tsx | 25 - apps/web/src/pages/files/page.tsx | 39 - .../components/forgot-password-form.tsx | 44 - .../pages/home/components/home-content.tsx | 71 - .../src/pages/home/components/home-header.tsx | 45 - apps/web/src/pages/home/components/navbar.tsx | 90 - apps/web/src/pages/home/hooks/use-home.ts | 33 - .../src/pages/login/components/login-form.tsx | 72 - .../pages/login/components/login-header.tsx | 18 - apps/web/src/pages/login/hooks/use-login.ts | 66 - .../profile/components/password-form.tsx | 82 - .../pages/profile/components/profile-form.tsx | 73 - .../profile/components/profile-header.tsx | 29 - .../profile/components/profile-picture.tsx | 71 - apps/web/src/pages/profile/page.tsx | 49 - .../components/reset-password-form.tsx | 85 - .../settings/components/settings-header.tsx | 28 - apps/web/src/pages/settings/page.tsx | 38 - .../share/[alias]/components/files-table.tsx | 54 - .../[alias]/components/password-modal.tsx | 44 - .../[alias]/components/share-not-found.tsx | 23 - .../pages/shares/components/shares-header.tsx | 29 - .../pages/shares/components/shares-search.tsx | 44 - apps/web/src/pages/shares/page.tsx | 84 - .../components/user-actions-dropdown.tsx | 46 - .../components/user-delete-modal.tsx | 34 - .../components/user-form-modal.tsx | 89 - .../components/users-header.tsx | 41 - .../components/users-table.tsx | 63 - apps/web/src/pages/users-management/page.tsx | 68 - apps/web/src/providers.tsx | 27 - apps/web/src/providers/theme-provider.tsx | 8 + apps/web/src/styles/globals.css | 13 - apps/web/src/types/layout.ts | 4 + apps/web/src/types/share.ts | 3 - apps/web/src/utils/file-icons.tsx | 52 +- apps/web/src/vite-env.d.ts | 1 - apps/web/tailwind.config.js | 73 - apps/web/tsconfig.json | 41 +- apps/web/tsconfig.node.json | 11 - apps/web/vercel.json | 3 - apps/web/vite.config.ts | 16 - composes/docker-compose-base.yaml | 103 - composes/docker-compose-local.yaml | 110 - docker-compose.yaml | 110 + scripts/generate-docker-compose.sh | 48 - 442 files changed, 24579 insertions(+), 9863 deletions(-) delete mode 100644 Makefile create mode 100644 apps/docs/.eslintrc.json delete mode 100644 apps/docs/.vscode/css.json delete mode 100644 apps/docs/.vscode/extensions.json delete mode 100644 apps/docs/.vscode/settings.json create mode 100644 apps/docs/README.md delete mode 100644 apps/docs/astro.config.mjs create mode 100644 apps/docs/components.json rename apps/docs/{src/content/docs/core/api-docs.md => content/docs/1.1.7-beta/api.md} (91%) rename apps/docs/{src/content/docs/core => content/docs/1.1.7-beta}/architecture.md (98%) rename apps/docs/{src/content/docs/main => content/docs/1.1.7-beta}/available-languages.md (95%) rename apps/docs/{src/content/docs/main => content/docs/1.1.7-beta}/configuring-smtp.md (92%) rename apps/docs/{src/content/docs/developers => content/docs/1.1.7-beta}/contribute.md (99%) rename apps/docs/{src/content/docs/main => content/docs/1.1.7-beta}/generate-share.md (75%) rename apps/docs/{src/content/docs/sponsor => content/docs/1.1.7-beta}/gh-sponsor.md (96%) rename apps/docs/{src/content/docs/sponsor => content/docs/1.1.7-beta}/gh-star.md (96%) rename apps/docs/{src/content/docs/core => content/docs/1.1.7-beta}/github-architecture.md (100%) rename apps/docs/{src/content/docs => content/docs/1.1.7-beta}/index.md (96%) rename apps/docs/{src/content/docs/core => content/docs/1.1.7-beta}/installation.mdx (59%) rename apps/docs/{src/content/docs/main => content/docs/1.1.7-beta}/login.md (92%) rename apps/docs/{src/content/docs/main => content/docs/1.1.7-beta}/manage-users.md (77%) rename apps/docs/{src/content/docs/core => content/docs/1.1.7-beta}/manual-installation.mdx (100%) create mode 100644 apps/docs/content/docs/1.1.7-beta/meta.json rename apps/docs/{src/content/docs/developers => content/docs/1.1.7-beta}/open-an-issue.md (94%) rename apps/docs/{src/content/docs/main => content/docs/1.1.7-beta}/upload.md (81%) create mode 100644 apps/docs/content/docs/2.0.0-beta/api.mdx create mode 100644 apps/docs/content/docs/2.0.0-beta/architecture.mdx create mode 100644 apps/docs/content/docs/2.0.0-beta/available-languages.mdx create mode 100644 apps/docs/content/docs/2.0.0-beta/configuring-smtp.mdx create mode 100644 apps/docs/content/docs/2.0.0-beta/contribute.mdx create mode 100644 apps/docs/content/docs/2.0.0-beta/first-login.mdx create mode 100644 apps/docs/content/docs/2.0.0-beta/generate-share.mdx create mode 100644 apps/docs/content/docs/2.0.0-beta/gh-sponsor.mdx create mode 100644 apps/docs/content/docs/2.0.0-beta/gh-star.mdx create mode 100644 apps/docs/content/docs/2.0.0-beta/github-architecture.mdx create mode 100644 apps/docs/content/docs/2.0.0-beta/index.mdx create mode 100644 apps/docs/content/docs/2.0.0-beta/installation.mdx create mode 100644 apps/docs/content/docs/2.0.0-beta/manage-users.mdx create mode 100644 apps/docs/content/docs/2.0.0-beta/manual-installation.mdx create mode 100644 apps/docs/content/docs/2.0.0-beta/meta.json create mode 100644 apps/docs/content/docs/2.0.0-beta/open-an-issue.mdx create mode 100644 apps/docs/content/docs/2.0.0-beta/uploading-files.mdx create mode 100644 apps/docs/content/docs/meta.json create mode 100644 apps/docs/next.config.mjs create mode 100644 apps/docs/postcss.config.mjs rename apps/docs/public/{ => assets/v1}/api-docs/scalar.png (100%) rename apps/docs/public/{ => assets/v1}/api-docs/swagger.png (100%) rename apps/docs/public/{ => assets/v1}/developers/issues-tab.png (100%) rename apps/docs/public/{ => assets/v1}/developers/new-issue-btn.png (100%) rename apps/docs/public/{ => assets/v1}/developers/new-issue-form.png (100%) rename apps/docs/public/{ => assets/v1}/general/architecture.png (100%) rename apps/docs/public/{ => assets/v1}/general/banner.png (100%) rename apps/docs/public/{ => assets/v1}/general/lp.png (100%) rename apps/docs/public/{ => assets/v1}/main/files/actions-dropdown.png (100%) rename apps/docs/public/{ => assets/v1}/main/files/edit-modal.png (100%) rename apps/docs/public/{ => assets/v1}/main/files/my-files-card.png (100%) rename apps/docs/public/{ => assets/v1}/main/files/my-files-page.png (100%) rename apps/docs/public/{ => assets/v1}/main/language/language-selector.png (100%) rename apps/docs/public/{ => assets/v1}/main/shares/actions-column.png (100%) rename apps/docs/public/{ => assets/v1}/main/shares/copy-link-modal.png (100%) rename apps/docs/public/{ => assets/v1}/main/shares/create-first-share.png (100%) rename apps/docs/public/{ => assets/v1}/main/shares/create-share-modal.png (100%) rename apps/docs/public/{ => assets/v1}/main/shares/delete-share-modal.png (100%) rename apps/docs/public/{ => assets/v1}/main/shares/dropdown-with-copy.png (100%) rename apps/docs/public/{ => assets/v1}/main/shares/edit-share-modal.png (100%) rename apps/docs/public/{ => assets/v1}/main/shares/generate-share-link-modal.png (100%) rename apps/docs/public/{ => assets/v1}/main/shares/manage-files-modal.png (100%) rename apps/docs/public/{ => assets/v1}/main/shares/manage-recipients-modal.png (100%) rename apps/docs/public/{ => assets/v1}/main/shares/my-shares-card.png (100%) rename apps/docs/public/{ => assets/v1}/main/shares/my-shares-page.png (100%) rename apps/docs/public/{ => assets/v1}/main/shares/new-share-btn.png (100%) rename apps/docs/public/{ => assets/v1}/main/shares/recent-shares-filled.png (100%) rename apps/docs/public/{ => assets/v1}/main/shares/share-details-modal.png (100%) rename apps/docs/public/{ => assets/v1}/main/shares/share-screen.png (100%) rename apps/docs/public/{ => assets/v1}/main/shares/share-section.png (100%) rename apps/docs/public/{ => assets/v1}/main/shares/shares-table.png (100%) rename apps/docs/public/{ => assets/v1}/main/shares/view-all-button.png (100%) rename apps/docs/public/{ => assets/v1}/main/smtp/closed-card.png (100%) rename apps/docs/public/{ => assets/v1}/main/smtp/dropdown-menu.png (100%) rename apps/docs/public/{ => assets/v1}/main/smtp/opened-card.png (100%) rename apps/docs/public/{ => assets/v1}/main/smtp/smtp-enabled.png (100%) rename apps/docs/public/{ => assets/v1}/main/upload/new-upload-button.png (100%) rename apps/docs/public/{ => assets/v1}/main/upload/preview-example.png (100%) rename apps/docs/public/{ => assets/v1}/main/upload/recent-uploads-filled.png (100%) rename apps/docs/public/{ => assets/v1}/main/upload/recent-uploads.png (100%) rename apps/docs/public/{ => assets/v1}/main/upload/upload-cancel-buttons.png (100%) rename apps/docs/public/{ => assets/v1}/main/upload/upload-file-button.png (100%) rename apps/docs/public/{ => assets/v1}/main/upload/view-all-button.png (100%) rename apps/docs/public/{ => assets/v1}/main/users/add-user-actions-dropdown.png (100%) rename apps/docs/public/{ => assets/v1}/main/users/add-user-modal.png (100%) rename apps/docs/public/{ => assets/v1}/main/users/add-users-btn.png (100%) rename apps/docs/public/{ => assets/v1}/main/users/edit-user-modal.png (100%) rename apps/docs/public/{ => assets/v1}/main/users/new-user-table.png (100%) rename apps/docs/public/{ => assets/v1}/main/users/users-management.png (100%) rename apps/docs/public/{ => assets/v1}/sponsor/sponsor-btn.png (100%) rename apps/docs/public/{ => assets/v1}/sponsor/sponsor-page.png (100%) rename apps/docs/public/{ => assets/v1}/sponsor/star-btn.png (100%) rename apps/docs/public/{ => assets/v1}/sponsor/starred-button.png (100%) rename apps/docs/public/{ => assets/v1}/ui/dashboard.png (100%) rename apps/docs/public/{ => assets/v1}/ui/login.png (100%) rename apps/docs/public/{ => assets/v1}/ui/menu.png (100%) rename apps/docs/public/{ => assets/v1}/ui/profile.png (100%) rename apps/docs/public/{ => assets/v1}/ui/profile_picture.png (100%) create mode 100644 apps/docs/public/assets/v2/api-docs/scalar.png create mode 100644 apps/docs/public/assets/v2/api-docs/swagger.png create mode 100644 apps/docs/public/assets/v2/general/architecture.png create mode 100644 apps/docs/public/assets/v2/general/banner.png create mode 100644 apps/docs/public/favicon.ico delete mode 100644 apps/docs/public/favicon.svg create mode 100644 apps/docs/source.config.ts create mode 100644 apps/docs/src/app/(home)/layout.tsx create mode 100644 apps/docs/src/app/(home)/page.tsx create mode 100644 apps/docs/src/app/api/search/route.ts create mode 100644 apps/docs/src/app/docs/[[...slug]]/page.tsx create mode 100644 apps/docs/src/app/docs/components/footer.tsx create mode 100644 apps/docs/src/app/docs/components/sponsor.tsx create mode 100644 apps/docs/src/app/docs/layout.tsx create mode 100644 apps/docs/src/app/global.css create mode 100644 apps/docs/src/app/layout.config.tsx create mode 100644 apps/docs/src/app/layout.tsx create mode 100644 apps/docs/src/components/magicui/animated-grid-pattern.tsx create mode 100644 apps/docs/src/components/magicui/particles.tsx create mode 100644 apps/docs/src/components/magicui/pulsating-button.tsx create mode 100644 apps/docs/src/components/magicui/ripple-button.tsx create mode 100644 apps/docs/src/components/magicui/typing-animation.tsx create mode 100644 apps/docs/src/components/magicui/word-rotate.tsx create mode 100644 apps/docs/src/components/ui/3d-marquee.tsx create mode 100644 apps/docs/src/components/ui/text-hover-effect.tsx delete mode 100644 apps/docs/src/content.config.ts create mode 100644 apps/docs/src/lib/source.ts create mode 100644 apps/docs/src/lib/utils.ts create mode 100644 apps/docs/src/mdx-components.tsx delete mode 100644 apps/docs/src/styles/custom.css delete mode 100644 apps/web/.env delete mode 100644 apps/web/.eslintignore delete mode 100644 apps/web/.eslintrc.json delete mode 100644 apps/web/.npmrc create mode 100644 apps/web/.prettierignore delete mode 100644 apps/web/README.md create mode 100644 apps/web/components.json create mode 100644 apps/web/docker-compose.yml create mode 100644 apps/web/eslint.config.mjs delete mode 100644 apps/web/index.html rename apps/web/{src/locales => messages}/ar-SA.json (97%) rename apps/web/{src/locales => messages}/de-DE.json (97%) rename apps/web/{src/locales => messages}/en-US.json (93%) rename apps/web/{src/locales => messages}/es-ES.json (97%) rename apps/web/{src/locales => messages}/fr-FR.json (97%) rename apps/web/{src/locales => messages}/hi-IN.json (97%) rename apps/web/{src/locales => messages}/ja-JP.json (97%) rename apps/web/{src/locales => messages}/ko-KR.json (97%) rename apps/web/{src/locales => messages}/pt-BR.json (97%) rename apps/web/{src/locales => messages}/ru-RU.json (97%) rename apps/web/{src/locales => messages}/tr-TR.json (97%) rename apps/web/{src/locales => messages}/zh-CN.json (97%) create mode 100644 apps/web/next.config.ts delete mode 100644 apps/web/orval.config.ts create mode 100644 apps/web/pnpm-lock.yaml delete mode 100644 apps/web/postcss.config.js create mode 100644 apps/web/postcss.config.mjs delete mode 100644 apps/web/routes.json delete mode 100644 apps/web/src/App.tsx create mode 100644 apps/web/src/app/(home)/components/home-content.tsx create mode 100644 apps/web/src/app/(home)/components/home-header.tsx create mode 100644 apps/web/src/app/(home)/components/navbar.tsx create mode 100644 apps/web/src/app/(home)/hooks/use-home.ts create mode 100644 apps/web/src/app/(home)/layout.tsx rename apps/web/src/{pages/home => app/(home)}/page.tsx (72%) rename apps/web/src/{pages/home => app/(home)}/types/index.ts (65%) create mode 100644 apps/web/src/app/(shares)/s/[alias]/components/files-table.tsx create mode 100644 apps/web/src/app/(shares)/s/[alias]/components/password-modal.tsx rename apps/web/src/{pages/share => app/(shares)/s}/[alias]/components/share-details.tsx (70%) rename apps/web/src/{pages/share => app/(shares)/s}/[alias]/components/share-header.tsx (80%) create mode 100644 apps/web/src/app/(shares)/s/[alias]/components/share-not-found.tsx rename apps/web/src/{pages/share => app/(shares)/s}/[alias]/hooks/use-public-share.ts (91%) create mode 100644 apps/web/src/app/(shares)/s/[alias]/layout.tsx rename apps/web/src/{pages/share => app/(shares)/s}/[alias]/page.tsx (85%) rename apps/web/src/{pages/share => app/(shares)/s}/[alias]/types/index.tsx (100%) rename apps/web/src/{pages => app/(shares)}/shares/components/empty-shares-state.tsx (50%) create mode 100644 apps/web/src/app/(shares)/shares/components/shares-header.tsx rename apps/web/src/{pages => app/(shares)}/shares/components/shares-modals.tsx (100%) create mode 100644 apps/web/src/app/(shares)/shares/components/shares-search.tsx rename apps/web/src/{pages => app/(shares)}/shares/components/shares-table-container.tsx (100%) rename apps/web/src/{pages => app/(shares)}/shares/hooks/use-shares.ts (87%) create mode 100644 apps/web/src/app/(shares)/shares/layout.tsx create mode 100644 apps/web/src/app/(shares)/shares/page.tsx rename apps/web/src/{pages => app/(shares)}/shares/types/index.ts (54%) create mode 100644 apps/web/src/app/api/(proxy)/app/check-upload/route.ts create mode 100644 apps/web/src/app/api/(proxy)/app/configs/route.ts create mode 100644 apps/web/src/app/api/(proxy)/app/disk-space/route.ts create mode 100644 apps/web/src/app/api/(proxy)/app/health/route.ts create mode 100644 apps/web/src/app/api/(proxy)/app/info/route.ts create mode 100644 apps/web/src/app/api/(proxy)/app/remove-logo/route.ts create mode 100644 apps/web/src/app/api/(proxy)/app/upload-logo/route.ts create mode 100644 apps/web/src/app/api/(proxy)/auth/forgot-password/route.ts create mode 100644 apps/web/src/app/api/(proxy)/auth/login/route.ts create mode 100644 apps/web/src/app/api/(proxy)/auth/logout/route.ts create mode 100644 apps/web/src/app/api/(proxy)/auth/me/route.ts create mode 100644 apps/web/src/app/api/(proxy)/auth/reset-password/route.ts create mode 100644 apps/web/src/app/api/(proxy)/config/list/route.ts create mode 100644 apps/web/src/app/api/(proxy)/config/update/[key]/route.ts create mode 100644 apps/web/src/app/api/(proxy)/config/update/bulk/route.ts create mode 100644 apps/web/src/app/api/(proxy)/files/(download)/[objectName]/download/route.ts create mode 100644 apps/web/src/app/api/(proxy)/files/delete/[id]/route.ts create mode 100644 apps/web/src/app/api/(proxy)/files/generate-presigned-url/route.ts create mode 100644 apps/web/src/app/api/(proxy)/files/list/route.ts create mode 100644 apps/web/src/app/api/(proxy)/files/register/route.ts create mode 100644 apps/web/src/app/api/(proxy)/files/update/[id]/route.ts create mode 100644 apps/web/src/app/api/(proxy)/shares/alias/create/[shareId]/route.ts create mode 100644 apps/web/src/app/api/(proxy)/shares/alias/get/[alias]/route.ts create mode 100644 apps/web/src/app/api/(proxy)/shares/create/route.ts create mode 100644 apps/web/src/app/api/(proxy)/shares/delete/[id]/route.ts create mode 100644 apps/web/src/app/api/(proxy)/shares/details/[shareId]/route.ts create mode 100644 apps/web/src/app/api/(proxy)/shares/files/add/[shareId]/route.ts create mode 100644 apps/web/src/app/api/(proxy)/shares/files/remove/[shareId]/route.ts create mode 100644 apps/web/src/app/api/(proxy)/shares/list/route.ts create mode 100644 apps/web/src/app/api/(proxy)/shares/password/update/shareId/route.ts create mode 100644 apps/web/src/app/api/(proxy)/shares/recipients/add/[shareId]/route.ts create mode 100644 apps/web/src/app/api/(proxy)/shares/recipients/notify/[shareId]/route.ts create mode 100644 apps/web/src/app/api/(proxy)/shares/recipients/remove/[shareId]/route.ts create mode 100644 apps/web/src/app/api/(proxy)/shares/update/route.ts create mode 100644 apps/web/src/app/api/(proxy)/users/activate/[id]/route.ts create mode 100644 apps/web/src/app/api/(proxy)/users/avatar/remove/route.ts create mode 100644 apps/web/src/app/api/(proxy)/users/avatar/upload/route.ts create mode 100644 apps/web/src/app/api/(proxy)/users/deactivate/[id]/route.ts create mode 100644 apps/web/src/app/api/(proxy)/users/delete/[id]/route.ts create mode 100644 apps/web/src/app/api/(proxy)/users/details/[id]/route.ts create mode 100644 apps/web/src/app/api/(proxy)/users/list/route.ts create mode 100644 apps/web/src/app/api/(proxy)/users/register/route.ts create mode 100644 apps/web/src/app/api/(proxy)/users/update-image/[id]/route.ts create mode 100644 apps/web/src/app/api/(proxy)/users/update/route.ts create mode 100644 apps/web/src/app/dashboard/components/empty-file-state.tsx create mode 100644 apps/web/src/app/dashboard/components/empty-shares-state.tsx rename apps/web/src/{pages => app}/dashboard/components/quick-access-cards.tsx (57%) create mode 100644 apps/web/src/app/dashboard/components/recent-files.tsx rename apps/web/src/{pages => app}/dashboard/components/recent-shares.tsx (51%) create mode 100644 apps/web/src/app/dashboard/components/storage-usage.tsx rename apps/web/src/{pages => app}/dashboard/hooks/use-dashboard.ts (82%) create mode 100644 apps/web/src/app/dashboard/layout.tsx rename apps/web/src/{pages => app}/dashboard/modals/dashboard-modals.tsx (100%) create mode 100644 apps/web/src/app/dashboard/page.tsx rename apps/web/src/{pages => app}/dashboard/types/index.ts (100%) rename apps/web/src/{pages => app}/dashboard/utils/format-storage-size.ts (100%) rename apps/web/{ => src/app}/favicon.ico (100%) create mode 100644 apps/web/src/app/files/components/empty-state.tsx rename apps/web/src/{pages => app}/files/components/file-list.tsx (91%) rename apps/web/src/{pages => app}/files/components/header.tsx (51%) create mode 100644 apps/web/src/app/files/components/search-bar.tsx rename apps/web/src/{pages => app}/files/hooks/use-files.ts (80%) create mode 100644 apps/web/src/app/files/layout.tsx rename apps/web/src/{pages => app}/files/modals/files-modals.tsx (100%) create mode 100644 apps/web/src/app/files/page.tsx rename apps/web/src/{pages => app}/files/types/index.ts (100%) create mode 100644 apps/web/src/app/forgot-password/components/forgot-password-form.tsx rename apps/web/src/{pages => app}/forgot-password/components/forgot-password-header.tsx (51%) rename apps/web/src/{pages => app}/forgot-password/hooks/use-forgot-password.ts (83%) create mode 100644 apps/web/src/app/forgot-password/layout.tsx rename apps/web/src/{pages => app}/forgot-password/page.tsx (78%) rename apps/web/src/{pages => app}/forgot-password/types/index.ts (99%) create mode 100644 apps/web/src/app/globals.css create mode 100644 apps/web/src/app/layout.tsx create mode 100644 apps/web/src/app/login/components/login-form.tsx create mode 100644 apps/web/src/app/login/components/login-header.tsx create mode 100644 apps/web/src/app/login/components/password-visibility-toggle.tsx rename apps/web/src/{pages => app}/login/components/static-background-lights.tsx (100%) create mode 100644 apps/web/src/app/login/hooks/use-login.ts create mode 100644 apps/web/src/app/login/layout.tsx rename apps/web/src/{pages => app}/login/page.tsx (77%) create mode 100644 apps/web/src/app/login/schemas/schema.ts rename apps/web/src/{pages => app}/login/types/index.ts (99%) create mode 100644 apps/web/src/app/profile/components/password-form.tsx create mode 100644 apps/web/src/app/profile/components/profile-form.tsx create mode 100644 apps/web/src/app/profile/components/profile-header.tsx create mode 100644 apps/web/src/app/profile/components/profile-picture.tsx rename apps/web/src/{pages => app}/profile/hooks/use-profile.ts (95%) create mode 100644 apps/web/src/app/profile/layout.tsx create mode 100644 apps/web/src/app/profile/page.tsx rename apps/web/src/{pages => app}/profile/types/index.ts (99%) create mode 100644 apps/web/src/app/reset-password/components/reset-password-form.tsx rename apps/web/src/{pages => app}/reset-password/components/reset-password-header.tsx (66%) rename apps/web/src/{pages => app}/reset-password/hooks/use-reset-password.ts (83%) create mode 100644 apps/web/src/app/reset-password/layout.tsx rename apps/web/src/{pages => app}/reset-password/page.tsx (79%) rename apps/web/src/{pages => app}/reset-password/types/index.ts (99%) rename apps/web/src/{pages => app}/settings/components/logo-input.tsx (72%) rename apps/web/src/{pages => app}/settings/components/settings-form.tsx (92%) rename apps/web/src/{pages => app}/settings/components/settings-group.tsx (63%) create mode 100644 apps/web/src/app/settings/components/settings-header.tsx rename apps/web/src/{pages => app}/settings/components/settings-input.tsx (60%) rename apps/web/src/{pages => app}/settings/constants.ts (85%) rename apps/web/src/{pages => app}/settings/hooks/use-settings.ts (86%) create mode 100644 apps/web/src/app/settings/layout.tsx create mode 100644 apps/web/src/app/settings/page.tsx rename apps/web/src/{pages => app}/settings/types/index.ts (95%) create mode 100644 apps/web/src/app/users-management/components/user-actions-dropdown.tsx create mode 100644 apps/web/src/app/users-management/components/user-delete-modal.tsx create mode 100644 apps/web/src/app/users-management/components/user-form-modal.tsx rename apps/web/src/{pages => app}/users-management/components/user-management-modals.tsx (100%) rename apps/web/src/{pages => app}/users-management/components/user-status-modal.tsx (50%) create mode 100644 apps/web/src/app/users-management/components/users-header.tsx create mode 100644 apps/web/src/app/users-management/components/users-table.tsx rename apps/web/src/{pages => app}/users-management/hooks/use-user-management.ts (91%) create mode 100644 apps/web/src/app/users-management/layout.tsx create mode 100644 apps/web/src/app/users-management/page.tsx rename apps/web/src/{pages => app}/users-management/types/index.ts (99%) create mode 100644 apps/web/src/components/auth/protected-route.tsx create mode 100644 apps/web/src/components/general/mode-toggle.tsx delete mode 100644 apps/web/src/components/general/theme-switch.tsx create mode 100644 apps/web/src/components/layout/favicon.tsx delete mode 100644 apps/web/src/components/layout/share-manager-layout.tsx delete mode 100644 apps/web/src/components/route-protector/admin-protected-route.tsx delete mode 100644 apps/web/src/components/route-protector/protected-route.tsx create mode 100644 apps/web/src/components/ui/aspect-ratio.tsx create mode 100644 apps/web/src/components/ui/avatar.tsx rename apps/web/src/{pages/home/components => components/ui}/background-lights.tsx (100%) create mode 100644 apps/web/src/components/ui/badge.tsx create mode 100644 apps/web/src/components/ui/breadcrumb.tsx create mode 100644 apps/web/src/components/ui/button.tsx create mode 100644 apps/web/src/components/ui/card.tsx create mode 100644 apps/web/src/components/ui/dialog.tsx create mode 100644 apps/web/src/components/ui/dropdown-menu.tsx create mode 100644 apps/web/src/components/ui/form.tsx delete mode 100644 apps/web/src/components/ui/grid-pattern.tsx create mode 100644 apps/web/src/components/ui/input.tsx create mode 100644 apps/web/src/components/ui/label.tsx create mode 100644 apps/web/src/components/ui/loader.tsx create mode 100644 apps/web/src/components/ui/progress.tsx create mode 100644 apps/web/src/components/ui/scroll-area.tsx create mode 100644 apps/web/src/components/ui/select.tsx create mode 100644 apps/web/src/components/ui/separator.tsx create mode 100644 apps/web/src/components/ui/sheet.tsx create mode 100644 apps/web/src/components/ui/switch.tsx create mode 100644 apps/web/src/components/ui/table.tsx rename apps/web/src/config/{axios.ts => api.ts} (51%) delete mode 100644 apps/web/src/config/i18n.ts rename apps/web/src/contexts/{ShareContext.tsx => share-context.tsx} (92%) create mode 100644 apps/web/src/hooks/use-disclosure.ts delete mode 100644 apps/web/src/hooks/use-page-title.ts delete mode 100644 apps/web/src/hooks/use-theme.ts create mode 100644 apps/web/src/i18n/request.ts create mode 100644 apps/web/src/lib/i18n-mock.ts create mode 100644 apps/web/src/lib/utils.ts delete mode 100644 apps/web/src/main.tsx delete mode 100644 apps/web/src/pages/dashboard/components/recent-files.tsx delete mode 100644 apps/web/src/pages/dashboard/components/storage-usage.tsx delete mode 100644 apps/web/src/pages/dashboard/page.tsx delete mode 100644 apps/web/src/pages/files/components/empty-state.tsx delete mode 100644 apps/web/src/pages/files/components/search-bar.tsx delete mode 100644 apps/web/src/pages/files/page.tsx delete mode 100644 apps/web/src/pages/forgot-password/components/forgot-password-form.tsx delete mode 100644 apps/web/src/pages/home/components/home-content.tsx delete mode 100644 apps/web/src/pages/home/components/home-header.tsx delete mode 100644 apps/web/src/pages/home/components/navbar.tsx delete mode 100644 apps/web/src/pages/home/hooks/use-home.ts delete mode 100644 apps/web/src/pages/login/components/login-form.tsx delete mode 100644 apps/web/src/pages/login/components/login-header.tsx delete mode 100644 apps/web/src/pages/login/hooks/use-login.ts delete mode 100644 apps/web/src/pages/profile/components/password-form.tsx delete mode 100644 apps/web/src/pages/profile/components/profile-form.tsx delete mode 100644 apps/web/src/pages/profile/components/profile-header.tsx delete mode 100644 apps/web/src/pages/profile/components/profile-picture.tsx delete mode 100644 apps/web/src/pages/profile/page.tsx delete mode 100644 apps/web/src/pages/reset-password/components/reset-password-form.tsx delete mode 100644 apps/web/src/pages/settings/components/settings-header.tsx delete mode 100644 apps/web/src/pages/settings/page.tsx delete mode 100644 apps/web/src/pages/share/[alias]/components/files-table.tsx delete mode 100644 apps/web/src/pages/share/[alias]/components/password-modal.tsx delete mode 100644 apps/web/src/pages/share/[alias]/components/share-not-found.tsx delete mode 100644 apps/web/src/pages/shares/components/shares-header.tsx delete mode 100644 apps/web/src/pages/shares/components/shares-search.tsx delete mode 100644 apps/web/src/pages/shares/page.tsx delete mode 100644 apps/web/src/pages/users-management/components/user-actions-dropdown.tsx delete mode 100644 apps/web/src/pages/users-management/components/user-delete-modal.tsx delete mode 100644 apps/web/src/pages/users-management/components/user-form-modal.tsx delete mode 100644 apps/web/src/pages/users-management/components/users-header.tsx delete mode 100644 apps/web/src/pages/users-management/components/users-table.tsx delete mode 100644 apps/web/src/pages/users-management/page.tsx delete mode 100644 apps/web/src/providers.tsx create mode 100644 apps/web/src/providers/theme-provider.tsx delete mode 100644 apps/web/src/styles/globals.css create mode 100644 apps/web/src/types/layout.ts delete mode 100644 apps/web/src/types/share.ts delete mode 100644 apps/web/src/vite-env.d.ts delete mode 100644 apps/web/tailwind.config.js delete mode 100644 apps/web/tsconfig.node.json delete mode 100644 apps/web/vercel.json delete mode 100644 apps/web/vite.config.ts delete mode 100644 composes/docker-compose-base.yaml delete mode 100644 composes/docker-compose-local.yaml create mode 100644 docker-compose.yaml delete mode 100755 scripts/generate-docker-compose.sh diff --git a/.gitignore b/.gitignore index f23e614..f172cdb 100644 --- a/.gitignore +++ b/.gitignore @@ -28,5 +28,5 @@ apps/server/node_modules apps/server/.env apps/server/dist/* -#COMPOSE -docker-compose.yaml \ No newline at end of file +#DEFAULT +.env \ No newline at end of file diff --git a/Makefile b/Makefile deleted file mode 100644 index 7aa4fc6..0000000 --- a/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -gen-compose: - chmod +x ./scripts/generate-docker-compose.sh - ./scripts/generate-docker-compose.sh diff --git a/README.md b/README.md index 2a53971..b193366 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,13 @@ # 🌴 Palmr. - Open-Source File Transfer

- Palmr Logo + Palmr Logo

**Palmr.** is a **flexible** and **open-source** alternative to file transfer services like **WeTransfer**, **SendGB**, **Send Anywhere**, and **Files.fm**. -🔗 **For detailed documentation visit:** [Palmr. - Documentation](https://palmr-docs.kyantech.com.br) +🔗 **For detailed documentation visit:** [Palmr. - Documentation](https://palmr.kyantech.com.br) ## 📌 Why Choose Palmr.? @@ -20,7 +20,7 @@ ### **Palmr.** is built with a focus on **performance**, **scalability**, and **security**.
- +
@@ -30,12 +30,12 @@ - **MinIO (Object Storage)** – AWS S3-compatible storage for high availability. ### **Frontend** -- **React + TypeScript + Vite** – Modern, interactive, and fast web interface. +- **NextJS 15 + TypeScript + Shadcn/ui** – Modern and fast web interface. ## 🛠️ How It Works -1. **Web Interface** → Built with React, TypeScript, and Vite for a seamless user experience. +1. **Web Interface** → Built with Next, React and TypeScript for a seamless user experience. 2. **Backend API** → Fastify handles requests and interacts with storage. 3. **Database** → PostgreSQL stores metadata and transactional data. 4. **Storage** → MinIO ensures reliable file storage and retrieval. @@ -43,10 +43,22 @@ ## 👨‍💻 Core Maintainers -| **Daniel Luiz Alves** | +| [**Daniel Luiz Alves**](https://github.com/danielalves96) | |------------------| | Daniel Luiz Alves | +
+ +## ⭐ Star History + + + + + + Star History Chart + + + ## 🛠️ Contributing For contribution guidelines, please refer to the [CONTRIBUTING.md](CONTRIBUTING.md) file. diff --git a/apps/docs/.eslintrc.json b/apps/docs/.eslintrc.json new file mode 100644 index 0000000..3722418 --- /dev/null +++ b/apps/docs/.eslintrc.json @@ -0,0 +1,3 @@ +{ + "extends": ["next/core-web-vitals", "next/typescript"] +} diff --git a/apps/docs/.gitignore b/apps/docs/.gitignore index e1823c1..55a12ae 100644 --- a/apps/docs/.gitignore +++ b/apps/docs/.gitignore @@ -1,3 +1,28 @@ -node_modules -.astro -dist \ No newline at end of file +# deps +/node_modules + +# generated content +.contentlayer +.content-collections +.source + +# test & build +/coverage +/.next/ +/out/ +/build +*.tsbuildinfo + +# misc +.DS_Store +*.pem +/.pnp +.pnp.js +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# others +.env*.local +.vercel +next-env.d.ts \ No newline at end of file diff --git a/apps/docs/.vscode/css.json b/apps/docs/.vscode/css.json deleted file mode 100644 index 96a1f57..0000000 --- a/apps/docs/.vscode/css.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "version": 1.1, - "atDirectives": [ - { - "name": "@tailwind", - "description": "Use the `@tailwind` directive to insert Tailwind's `base`, `components`, `utilities` and `screens` styles into your CSS.", - "references": [ - { - "name": "Tailwind Documentation", - "url": "https://tailwindcss.com/docs/functions-and-directives#tailwind" - } - ] - }, - { - "name": "@apply", - "description": "Use the `@apply` directive to inline any existing utility classes into your own custom CSS. This is useful when you find a common utility pattern in your HTML that you’d like to extract to a new component.", - "references": [ - { - "name": "Tailwind Documentation", - "url": "https://tailwindcss.com/docs/functions-and-directives#apply" - } - ] - }, - { - "name": "@responsive", - "description": "You can generate responsive variants of your own classes by wrapping their definitions in the `@responsive` directive:\n```css\n@responsive {\n .alert {\n background-color: #E53E3E;\n }\n}\n```\n", - "references": [ - { - "name": "Tailwind Documentation", - "url": "https://tailwindcss.com/docs/functions-and-directives#responsive" - } - ] - }, - { - "name": "@screen", - "description": "The `@screen` directive allows you to create media queries that reference your breakpoints by **name** instead of duplicating their values in your own CSS:\n```css\n@screen sm {\n /* ... */\n}\n```\n…gets transformed into this:\n```css\n@media (min-width: 640px) {\n /* ... */\n}\n```\n", - "references": [ - { - "name": "Tailwind Documentation", - "url": "https://tailwindcss.com/docs/functions-and-directives#screen" - } - ] - }, - { - "name": "@variants", - "description": "Generate `hover`, `focus`, `active` and other **variants** of your own utilities by wrapping their definitions in the `@variants` directive:\n```css\n@variants hover, focus {\n .btn-brand {\n background-color: #3182CE;\n }\n}\n```\n", - "references": [ - { - "name": "Tailwind Documentation", - "url": "https://tailwindcss.com/docs/functions-and-directives#variants" - } - ] - } - ] -} diff --git a/apps/docs/.vscode/extensions.json b/apps/docs/.vscode/extensions.json deleted file mode 100644 index 691da13..0000000 --- a/apps/docs/.vscode/extensions.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "recommendations": [ - "dbaeumer.vscode-eslint", - "bradlc.vscode-tailwindcss" - ], - - "unwantedRecommendations": [ - "esbenp.prettier-vscode" - ] -} diff --git a/apps/docs/.vscode/settings.json b/apps/docs/.vscode/settings.json deleted file mode 100644 index 16392d2..0000000 --- a/apps/docs/.vscode/settings.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "eslint.workingDirectories": [ - { "pattern": "apps/*/" }, - { "pattern": "packages/*/" } - ], - - "tailwindCSS.experimental.configFile": { - "apps/web/tailwind.config.ts": "apps/web/**" - }, - - "tailwindCSS.experimental.classRegex": [ - ["cva\\(([^)]*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]"], - ["cn\\(([^)]*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]"], - ], - - "tailwindCSS.classAttributes": [ - "class", - "className", - "tw" - ], - - "css.customData": [ - ".vscode/css.json" - ], - -"[javascript]": { - "editor.formatOnSave": false, - "editor.codeActionsOnSave": { - "source.fixAll.eslint": "explicit" - } - }, - - "[typescript]": { - "editor.formatOnSave": false, - "editor.codeActionsOnSave": { - "source.fixAll.eslint": "explicit" - } - }, - - "[typescriptreact]": { - "editor.formatOnSave": false, - "editor.codeActionsOnSave": { - "source.fixAll.eslint": "explicit" - } - }, - - "eslint.validate": [ - "javascript", - "typescript" - ], -} diff --git a/apps/docs/README.md b/apps/docs/README.md new file mode 100644 index 0000000..a923f4d --- /dev/null +++ b/apps/docs/README.md @@ -0,0 +1,26 @@ +# docs-v2 + +This is a Next.js application generated with +[Create Fumadocs](https://github.com/fuma-nama/fumadocs). + +Run development server: + +```bash +npm run dev +# or +pnpm dev +# or +yarn dev +``` + +Open http://localhost:3000 with your browser to see the result. + +## Learn More + +To learn more about Next.js and Fumadocs, take a look at the following +resources: + +- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js + features and API. +- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. +- [Fumadocs](https://fumadocs.vercel.app) - learn about Fumadocs diff --git a/apps/docs/astro.config.mjs b/apps/docs/astro.config.mjs deleted file mode 100644 index 63f97f6..0000000 --- a/apps/docs/astro.config.mjs +++ /dev/null @@ -1,58 +0,0 @@ -import { defineConfig } from 'astro/config'; -import starlight from '@astrojs/starlight'; - -export default defineConfig({ - integrations: [ - starlight({ - title: '🌴 Palmr. - Documentation', - defaultLocale: 'root', - social: { - github: 'https://github.com/kyantech/Palmr', - openCollective: 'https://github.com/sponsors/kyantech', - }, - sidebar: [ - { - label: 'Introduction', - items: [ - { label: 'Welcome to Palmr.', link: '/' }, - { label: 'Architecture of Palmr.', link: '/core/architecture' }, - { label: 'GitHub architecture', link: '/core/github-architecture' }, - { label: 'Installation (Docker Compose)', link: '/core/installation' }, - { label: 'Manual installation', link: '/core/manual-installation' }, - { label: 'API Endpoints', link: '/core/api-docs' }, - ], - }, - { - label: 'How to use Palmr.', - items: [ - { label: 'First login (Admin)', link: '/main/login' }, - { label: 'Manage users', link: '/main/manage-users' }, - { label: 'Uploading files', link: '/main/upload' }, - { label: 'Creating a share', link: '/main/generate-share' }, - { label: 'Configuring SMTP', link: '/main/configuring-smtp' }, - { label: 'Available languages', link: '/main/available-languages' }, - ], - }, - { - label: 'Developers', - items: [ - { label: 'How to contribute', link: '/developers/contribute' }, - { label: 'How to open an issue', link: '/developers/open-an-issue' }, - ], - }, - { - label: 'Sponsor this project', - items: [ - { label: 'Star this project on Github', link: '/sponsor/gh-star' }, - { label: 'Github Sponsors', link: '/sponsor/gh-sponsor' }, - ], - }, - ], - lastUpdated: true, - pagination: false, - customCss: [ - './src/styles/custom.css', - ], - }), - ], -}); diff --git a/apps/docs/components.json b/apps/docs/components.json new file mode 100644 index 0000000..49c6a2c --- /dev/null +++ b/apps/docs/components.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://ui.shadcn.com/schema.json", + "style": "new-york", + "rsc": true, + "tsx": true, + "tailwind": { + "config": "", + "css": "src/app/global.css", + "baseColor": "neutral", + "cssVariables": true, + "prefix": "" + }, + "aliases": { + "components": "@/components", + "utils": "@/lib/utils", + "ui": "@/components/ui", + "lib": "@/lib", + "hooks": "@/hooks" + }, + "iconLibrary": "lucide" +} \ No newline at end of file diff --git a/apps/docs/src/content/docs/core/api-docs.md b/apps/docs/content/docs/1.1.7-beta/api.md similarity index 91% rename from apps/docs/src/content/docs/core/api-docs.md rename to apps/docs/content/docs/1.1.7-beta/api.md index 71f694a..3a9a595 100644 --- a/apps/docs/src/content/docs/core/api-docs.md +++ b/apps/docs/content/docs/1.1.7-beta/api.md @@ -1,9 +1,7 @@ --- -title: Palmr. API Endpoints +title: API Endpoints --- -##### Overview of Palmr. API Endpoints - Palmr. provides a **highly documented and typed API** that can be accessed at: - **In a production environment:** `{your_server_domain}/docs` @@ -11,7 +9,7 @@ Palmr. provides a **highly documented and typed API** that can be accessed at: The API documentation is powered by **Scalar** ([https://scalar.com](https://scalar.com)), which offers a fully interactive interface for testing all the available requests within Palmr. Below is an example screenshot of the API documentation interface: -![Palmr API Documentation](/public/api-docs/scalar.png) +![Palmr API Documentation](/assets/v1/api-docs/scalar.png) --- @@ -31,7 +29,7 @@ We recommend using **Scalar** for querying and testing the API because the syste If you prefer not to use Scalar or are more comfortable with an alternative tool, a **Swagger-based version** of the documentation is also available. -![Palmr API Documentation](/public/api-docs/swagger.png) +![Palmr API Documentation](/assets/v1/api-docs/swagger.png) You can access it at: diff --git a/apps/docs/src/content/docs/core/architecture.md b/apps/docs/content/docs/1.1.7-beta/architecture.md similarity index 98% rename from apps/docs/src/content/docs/core/architecture.md rename to apps/docs/content/docs/1.1.7-beta/architecture.md index 3fc7fcc..b5e5f3c 100644 --- a/apps/docs/src/content/docs/core/architecture.md +++ b/apps/docs/content/docs/1.1.7-beta/architecture.md @@ -7,7 +7,7 @@ title: Architecture of Palmr. Understanding the architecture of Palmr. is crucial for both deploying and scaling the application. Below is a diagram illustrating the main components: -![Palmr Banner](/public/general/architecture.png) +![Palmr Banner](/assets/v1/general/architecture.png) ## **Technologies Used** diff --git a/apps/docs/src/content/docs/main/available-languages.md b/apps/docs/content/docs/1.1.7-beta/available-languages.md similarity index 95% rename from apps/docs/src/content/docs/main/available-languages.md rename to apps/docs/content/docs/1.1.7-beta/available-languages.md index 77dddbf..3b80b21 100644 --- a/apps/docs/src/content/docs/main/available-languages.md +++ b/apps/docs/content/docs/1.1.7-beta/available-languages.md @@ -32,7 +32,7 @@ The project uses i18next for internationalization (i18n) support. The language d #### 2. Manual Selection -![Palmr Profile Menu](/public/main/language/language-selector.png) +![Palmr Profile Menu](/assets/v1/main/language/language-selector.png) - Users can manually switch languages through the language selector in the UI - Language preference is saved in the browser's localStorage diff --git a/apps/docs/src/content/docs/main/configuring-smtp.md b/apps/docs/content/docs/1.1.7-beta/configuring-smtp.md similarity index 92% rename from apps/docs/src/content/docs/main/configuring-smtp.md rename to apps/docs/content/docs/1.1.7-beta/configuring-smtp.md index 7e39054..3a3e36a 100644 --- a/apps/docs/src/content/docs/main/configuring-smtp.md +++ b/apps/docs/content/docs/1.1.7-beta/configuring-smtp.md @@ -18,15 +18,15 @@ Now, let's go through the step-by-step process to configure the **SMTP Server**. To access **Settings**, an **ADMIN** user must click on the profile picture in the **header** and select **Settings** from the dropdown menu. -![Dropdown Menu](/public/main/smtp/dropdown-menu.png) +![Dropdown Menu](/assets/v1/main/smtp/dropdown-menu.png) Once inside the **Settings** panel, click on the **Email** card to expand the SMTP configuration options. -![Closed Settings Card](/public/main/smtp/closed-card.png) +![Closed Settings Card](/assets/v1/main/smtp/closed-card.png) After expanding the card, the following SMTP configuration fields will appear: -![Opened Settings Card](/public/main/smtp/opened-card.png) +![Opened Settings Card](/assets/v1/main/smtp/opened-card.png) --- @@ -34,7 +34,7 @@ After expanding the card, the following SMTP configuration fields will appear: The first step is to **enable SMTP** by selecting "Yes" in the **SMTP Enabled** field. -![SMTP Enabled](/public/main/smtp/smtp-enabled.png) +![SMTP Enabled](/assets/v1/main/smtp/smtp-enabled.png) Once SMTP is enabled, you can configure the other necessary fields: diff --git a/apps/docs/src/content/docs/developers/contribute.md b/apps/docs/content/docs/1.1.7-beta/contribute.md similarity index 99% rename from apps/docs/src/content/docs/developers/contribute.md rename to apps/docs/content/docs/1.1.7-beta/contribute.md index 51c09b4..14afa70 100644 --- a/apps/docs/src/content/docs/developers/contribute.md +++ b/apps/docs/content/docs/1.1.7-beta/contribute.md @@ -1,5 +1,5 @@ --- -title: How to Contribute to the Palmr. Project +title: How to Contribute --- Thank you for your interest in contributing to the **Palmr.** project! Contributions are what make the open-source community such an amazing place to learn, inspire, and create. This guide will walk you through the process of contributing to Palmr. diff --git a/apps/docs/src/content/docs/main/generate-share.md b/apps/docs/content/docs/1.1.7-beta/generate-share.md similarity index 75% rename from apps/docs/src/content/docs/main/generate-share.md rename to apps/docs/content/docs/1.1.7-beta/generate-share.md index 4f01d1a..e142061 100644 --- a/apps/docs/src/content/docs/main/generate-share.md +++ b/apps/docs/content/docs/1.1.7-beta/generate-share.md @@ -8,11 +8,11 @@ To create a share in Palmr, the process is very intuitive and self-explanatory. On the home page, there is a **"Recent Shares"** section. When no shares have been created yet, this section will appear as follows: -![Recent Shares Section](/public/main/shares/share-section.png) +![Recent Shares Section](/assets/v1/main/shares/share-section.png) Since no shares exist yet, you will see a **"Create Share"** button prominently displayed. -![Create Share Button](/public/main/shares/create-first-share.png) +![Create Share Button](/assets/v1/main/shares/create-first-share.png) > **Note:** You don’t need to upload files to create a share! Yes, it’s entirely possible to create a share without adding any files. While this might not make sense in every scenario, some users and use cases find this feature highly valuable. @@ -20,7 +20,7 @@ As mentioned above, shares in Palmr are created first with their settings, and t To create a share, simply click the **"Create Share"** button in the center of the **Recent Shares** section. Doing so will open the following **Create Share** modal: -![Create Share Modal](/public/main/shares/create-share-modal.png) +![Create Share Modal](/assets/v1/main/shares/create-share-modal.png) Fill in the required information in the modal. The fields **Expiration Date**, **Max Views**, and **Password** are optional but significantly impact how the share functions for recipients: - **Password:** If set, the recipient must enter the correct password to access the share. @@ -40,27 +40,27 @@ Once a share is created, the **Recent Shares** section updates to display a tabl - **Recipients** - **Actions** -![Shares Table](/public/main/shares/shares-table.png) +![Shares Table](/assets/v1/main/shares/shares-table.png) To create additional shares, a **"New Share"** button appears in the upper right corner of the **Recent Shares** section. -![New Share Button](/public/main/shares/new-share-btn.png) +![New Share Button](/assets/v1/main/shares/new-share-btn.png) Clicking this button will reopen the **Create Share** modal. The **Recent Shares** section displays only the **last 5 shares**. To view all created shares, click the **"View All"** button. -![Shares Filled](/public/main/shares/recent-shares-filled.png) +![Shares Filled](/assets/v1/main/shares/recent-shares-filled.png) -![View All Button](/public/main/shares/view-all-button.png) +![View All Button](/assets/v1/main/shares/view-all-button.png) Clicking this redirects you to the **Shares Management** page. -![Shares Management Page](/public/main/shares/my-shares-page.png) +![Shares Management Page](/assets/v1/main/shares/my-shares-page.png) Another way to access the **Shares Management** page is by clicking the **"My Shares"** card on the home page. -![My Shares Card](/public/main/shares/my-shares-card.png) +![My Shares Card](/assets/v1/main/shares/my-shares-card.png) --- @@ -70,19 +70,19 @@ The **Shares Management** page is similar to the **Uploads Management** page, bu ##### Each share has an **Actions** column with the following options: -![Actions Column](/public/main/shares/actions-column.png) +![Actions Column](/assets/v1/main/shares/actions-column.png) ## Edit Share Clicking the **Edit** button allows you to modify the share details. -![Edit Share Modal](/public/main/shares/edit-share-modal.png) +![Edit Share Modal](/assets/v1/main/shares/edit-share-modal.png) ## Manage Files Clicking the **Manage Files** button lets you add or remove files from the share. -![Manage Files Modal](/public/main/shares/manage-files-modal.png) +![Manage Files Modal](/assets/v1/main/shares/manage-files-modal.png) ## Manage Recipients @@ -90,36 +90,36 @@ Clicking the **Manage Recipients** button lets you add or remove recipients for > **Note:** Email notifications will only be sent if SMTP settings are properly configured in the system. -![Manage Recipients Modal](/public/main/shares/manage-recipients-modal.png) +![Manage Recipients Modal](/assets/v1/main/shares/manage-recipients-modal.png) ## View Share Details Clicking **View Details** lets you see all details of a share. -![View Details Modal](/public/main/shares/share-details-modal.png) +![View Details Modal](/assets/v1/main/shares/share-details-modal.png) ## Generate Share Link Clicking the **Generate Link** button creates a shareable link, which can be customized. -![Generate Link Modal](/public/main/shares/generate-share-link-modal.png) +![Generate Link Modal](/assets/v1/main/shares/generate-share-link-modal.png) Once generated, you can view and copy the link. -![Copy Link Modal](/public/main/shares/copy-link-modal.png) +![Copy Link Modal](/assets/v1/main/shares/copy-link-modal.png) The generated link can be edited or copied from a dropdown menu. -![Edit or Copy Link Dropdown](/public/main/shares/dropdown-with-copy.png) +![Edit or Copy Link Dropdown](/assets/v1/main/shares/dropdown-with-copy.png) When the generated link is accessed, the recipient can **view and download** the shared files. -![Shared Page Preview](/public/main/shares/share-screen.png) +![Shared Page Preview](/assets/v1/main/shares/share-screen.png) ## Delete Share Clicking the **Delete** button allows you to permanently remove a share. -![Delete Share Modal](/public/main/shares/delete-share-modal.png) +![Delete Share Modal](/assets/v1/main/shares/delete-share-modal.png) --- diff --git a/apps/docs/src/content/docs/sponsor/gh-sponsor.md b/apps/docs/content/docs/1.1.7-beta/gh-sponsor.md similarity index 96% rename from apps/docs/src/content/docs/sponsor/gh-sponsor.md rename to apps/docs/content/docs/1.1.7-beta/gh-sponsor.md index c4b92cf..103cd51 100644 --- a/apps/docs/src/content/docs/sponsor/gh-sponsor.md +++ b/apps/docs/content/docs/1.1.7-beta/gh-sponsor.md @@ -24,7 +24,7 @@ Alternatively, you can search for "Palmr" in the GitHub search bar and click on On the Palmr repository page, you'll see a "Sponsor" button at the top right corner of the page. Click this button to proceed. -![Palmr Profile Menu](/public/sponsor/sponsor-btn.png) +![Palmr Profile Menu](/assets/v1/sponsor/sponsor-btn.png) --- @@ -35,7 +35,7 @@ GitHub Sponsors allows you to sponsor the project with a **custom amount startin 2. Type in the amount you'd like to sponsor (e.g., $1, $5, $10, or any amount you choose). 3. Select the billing frequency (monthly or one-time). -![Palmr Profile Menu](/public/sponsor/sponsor-page.png) +![Palmr Profile Menu](/assets/v1/sponsor/sponsor-page.png) --- diff --git a/apps/docs/src/content/docs/sponsor/gh-star.md b/apps/docs/content/docs/1.1.7-beta/gh-star.md similarity index 96% rename from apps/docs/src/content/docs/sponsor/gh-star.md rename to apps/docs/content/docs/1.1.7-beta/gh-star.md index f5f0c10..f85d94f 100644 --- a/apps/docs/src/content/docs/sponsor/gh-star.md +++ b/apps/docs/content/docs/1.1.7-beta/gh-star.md @@ -24,7 +24,7 @@ Alternatively, you can search for "Palmr" in the GitHub search bar and click on On the Palmr. repository page, you'll see a "Star" button at the top right corner of the page. Click this button to star the repository. -![Palmr Profile Menu](/public/sponsor/star-btn.png) +![Palmr Profile Menu](/assets/v1/sponsor/star-btn.png) --- @@ -32,7 +32,7 @@ On the Palmr. repository page, you'll see a "Star" button at the top right corne After clicking the "Star" button, the button will change to "Unstar," indicating that the repository has been successfully starred. You can always unstar the repository by clicking the "Unstar" button. -![Palmr Profile Menu](/public/sponsor/starred-button.png) +![Palmr Profile Menu](/assets/v1/sponsor/starred-button.png) --- diff --git a/apps/docs/src/content/docs/core/github-architecture.md b/apps/docs/content/docs/1.1.7-beta/github-architecture.md similarity index 100% rename from apps/docs/src/content/docs/core/github-architecture.md rename to apps/docs/content/docs/1.1.7-beta/github-architecture.md diff --git a/apps/docs/src/content/docs/index.md b/apps/docs/content/docs/1.1.7-beta/index.md similarity index 96% rename from apps/docs/src/content/docs/index.md rename to apps/docs/content/docs/1.1.7-beta/index.md index be90a6d..e4c01b8 100644 --- a/apps/docs/src/content/docs/index.md +++ b/apps/docs/content/docs/1.1.7-beta/index.md @@ -1,8 +1,8 @@ --- -title: Introduction +title: Welcome to Palmr. --- -![Palmr Banner](/public/general/banner.png) +![Palmr Banner](/assets/v1/general/banner.png) ## 🌴 What is **Palmr.** ? ___ diff --git a/apps/docs/src/content/docs/core/installation.mdx b/apps/docs/content/docs/1.1.7-beta/installation.mdx similarity index 59% rename from apps/docs/src/content/docs/core/installation.mdx rename to apps/docs/content/docs/1.1.7-beta/installation.mdx index 84f0cbb..09aa248 100644 --- a/apps/docs/src/content/docs/core/installation.mdx +++ b/apps/docs/content/docs/1.1.7-beta/installation.mdx @@ -1,13 +1,26 @@ --- -title: Installation -description: Guide to install and run Palmr using Docker Compose +title: Installation (Docker Compose) --- -import { Tabs, TabItem } from '@astrojs/starlight/components'; +import { Tab, Tabs } from 'fumadocs-ui/components/tabs'; -### Startup Script for Docker Compose +### Quick Start with Default Docker Compose -To simplify the execution of the project and enable it to run on any machine, a **startup script** for Docker Compose was created. This script automates the generation of secure credentials and facilitates local setup. +There is a default `docker-compose.yml` file in the project root that can be used for quick execution. While this provides a convenient way to get started, it's important to note that using the default passwords is **not secure**, especially if the application is exposed to public networks. Malicious users could potentially exploit known default credentials to attack your deployment. + +This base Docker Compose configuration works perfectly for localhost development but may require modifications when deployed to a VPS or production environment for optimal performance and security. Please consult the complete documentation for proper production deployment configurations. + +For a quick start using the default configuration, simply run: +```bash +docker compose up -d +``` +This command will start the project using the default configuration. + +> ⚠️ **Important:** We strongly recommend testing your configuration locally first, especially if you've made any modifications to the Docker Compose files. Only after confirming everything works as expected locally should you proceed with deployment to a VPS or server environment. + +### Startup Script for Docker Compose + +To simplify the execution of the project and enable it to run on any machine, a **startup script** for Docker Compose was created. This script automates the generation of secure credentials and facilitates local setup. While this method provides better security than using default passwords, for maximum security, we strongly recommend moving all sensitive credentials to environment variables instead. To execute the project using this approach, you need to have **Docker** and **Docker Compose** installed on your machine. While this is the simplest way to execute the project, it is **not recommended for production environments**. @@ -15,28 +28,29 @@ To execute the project using this approach, you need to have **Docker** and **Do ### Ways to Execute the Startup Script -First of all, clone the official repository: `https://github.com/kyantech/Palmr.git` +First of all, download the relase v1.1.7-beta: +[Release version - 1.1.7-beta](https://github.com/kyantech/Palmr/releases/tag/v1.1.7-beta) There are two ways to execute the script: - - + + To use this method, you need to have the `make` command installed on your machine. - To generate the `docker-compose.yml` file using a Makefile, run the following command from the project root: + To generate the new `docker-compose.yml` file using a Makefile, run the following command from the project root: ```bash make gen-compose ``` - This command will generate a `docker-compose.yml` file in the root of the project. + This command will subcribe the `docker-compose.yml` file in the root of the project. - The script's primary function is to generate secure passwords for **MinIO** (object storage) and **Postgres** (database). - The generated `docker-compose.yml` file serves as a base and can be modified at any time. - It is configured to run locally via `localhost` and is **not intended for production** or VPS environments. After the file is generated, you can modify or adapt it for deployment in other environments. - - + + To generate the `docker-compose.yml` file by running the script directly, use the following commands: ```bash @@ -45,13 +59,13 @@ There are two ways to execute the script: ``` This will have the same effect as running `make gen-compose`. - + --- ### Running the Project -After generating the `docker-compose.yml` file, you can start the project by running the following command from the project root: +After generating the new `docker-compose.yml` file, you can start the project by running the following command from the project root: ```bash docker compose up -d @@ -64,9 +78,9 @@ To access Palmr. in a local environment, open your browser and visit: --- ### Deployment in Production -For production environments, we recommend using **Kubernetes**, **Docker Swarm**, or a similar container orchestrator. +For production environments with high scalability and availability requirements, we recommend using **Kubernetes**, **Docker Swarm**, or a similar container orchestrator. -For local execution or testing environments, you can use Docker Compose with the `docker-compose.yml` file. This file pulls the latest Palmr. images from Docker and makes them available on specific ports, as shown below: +For homelab, personal projects, or environments where high availability and scalability are not critical, Docker Compose can be used without issues. The `docker-compose.yml` file pulls the latest Palmr. images from Docker and makes them available on specific ports, as shown below: - **Frontend:** [http://localhost:4173](http://localhost:4173) - **Backend:** [http://localhost:3333](http://localhost:3333) @@ -79,7 +93,7 @@ For local execution or testing environments, you can use Docker Compose with the ### Port Configuration Recommendations In this version of `docker-compose.yml`, none of the ports for the frontend and backend should be modified. Consequently, none of the URLs should be changed because the frontend image contains a pre-built version configured to work on port **4173**. -Due to technical limitations related to **ReactJS**, environment variables executed at runtime cannot be changed. Therefore, to ensure that the system functions correctly as designed, keep the `docker-compose.yml` file unchanged. +> ⚠️ Due to technical limitations related to **ReactJS**, environment variables executed at runtime cannot be changed. Therefore, to ensure that the system functions correctly as designed, keep the `docker-compose.yml` file unchanged. --- diff --git a/apps/docs/src/content/docs/main/login.md b/apps/docs/content/docs/1.1.7-beta/login.md similarity index 92% rename from apps/docs/src/content/docs/main/login.md rename to apps/docs/content/docs/1.1.7-beta/login.md index 6615f97..369a638 100644 --- a/apps/docs/src/content/docs/main/login.md +++ b/apps/docs/content/docs/1.1.7-beta/login.md @@ -9,7 +9,7 @@ Once you have started all the services as described in the deployment instructio Upon accessing the frontend, you will see a screen similar to the image below: -![Palmr Landing Page](/public/general/lp.png) +![Palmr Landing Page](/assets/v1/general/lp.png) This is the **Palmr. landing page**, which provides basic information about the application. This landing page can be hidden later when you configure your app, allowing the login page to become the default home page. However, on the first execution, it is displayed by default. @@ -25,7 +25,7 @@ To simplify the process, Palmr. comes pre-configured with **seed data** upon the After clicking the **Login** button, you will be redirected to the login screen, which looks like this: -![Palmr Login Page](/public/ui/login.png) +![Palmr Login Page](/assets/v1/ui/login.png) Use the following default credentials to log in for the first time: @@ -35,7 +35,7 @@ Use the following default credentials to log in for the first time: If everything is set up correctly, you will be authenticated and redirected to Palmr.'s main dashboard, which looks like this: -![Palmr Dashboard](/public/ui/dashboard.png) +![Palmr Dashboard](/assets/v1/ui/dashboard.png) At this point, you are officially logged in and ready to start using all the features of Palmr.! @@ -51,11 +51,11 @@ Follow these steps to update the admin credentials and secure your Palmr. instan 1. Click the **user icon** located in the top right corner of the screen. 2. A dropdown menu will appear with several options: -![Palmr Profile Menu](/public/ui/menu.png) +![Palmr Profile Menu](/assets/v1/ui/menu.png) 3. Select **"Profile"** from the dropdown menu. This will redirect you to the profile settings page: -![Palmr Profile Page](/public/ui/profile.png) +![Palmr Profile Page](/assets/v1/ui/profile.png) --- @@ -78,7 +78,7 @@ You can also update the profile picture for better personalization. 1. Click the **camera icon** next to the avatar. 2. Select an image from your local device. -![Palmr Profile Picture](/public/ui/profile_picture.png) +![Palmr Profile Picture](/assets/v1/ui/profile_picture.png) > **Recommendation:** Use a square image to ensure proper display. diff --git a/apps/docs/src/content/docs/main/manage-users.md b/apps/docs/content/docs/1.1.7-beta/manage-users.md similarity index 77% rename from apps/docs/src/content/docs/main/manage-users.md rename to apps/docs/content/docs/1.1.7-beta/manage-users.md index 75d44ed..033f1b4 100644 --- a/apps/docs/src/content/docs/main/manage-users.md +++ b/apps/docs/content/docs/1.1.7-beta/manage-users.md @@ -2,9 +2,8 @@ title: Manage users --- -##### Manage users to **Palmr** is a straightforward process. Below is a detailed step-by-step guide explaining how to create and manage users within the application. +Manage users to **Palmr** is a straightforward process. Below is a detailed step-by-step guide explaining how to create and manage users within the application. ---- ### Step 1: Accessing User Management @@ -13,7 +12,7 @@ To begin, you need to navigate to the **User Management** section: 1. Click on the **user icon** located in the header of the app. 2. A dropdown menu will appear. From the options available, select **"User Management"** -![Palmr Profile Menu](/public/ui/menu.png) +![Palmr Profile Menu](/assets/v1/ui/menu.png) --- @@ -25,7 +24,7 @@ After selecting **User Management**, you will be redirected to the **User Manage - If you need to update the Admin user details, you must follow the steps outlined in the **Profile Management** section. - User details for the logged-in Admin cannot be modified from the **User Management Dashboard**. -![Palmr Profile Menu](/public/main/users/users-management.png) +![Palmr Profile Menu](/assets/v1/main/users/users-management.png) --- @@ -33,18 +32,18 @@ After selecting **User Management**, you will be redirected to the **User Manage 1. To add a new user, click on the **"Add User"** button located at the top right corner of the screen. -![Palmr Profile Menu](/public/main/users/add-users-btn.png) +![Palmr Profile Menu](/assets/v1/main/users/add-users-btn.png) 2. A modal form will appear, allowing you to enter the new user's details: -![Palmr Profile Menu](/public/main/users/add-user-modal.png) +![Palmr Profile Menu](/assets/v1/main/users/add-user-modal.png) 3. After filling in the user details, click on **"Create"** to confirm. Alternatively, you can click **"Cancel"** to abort the user creation process. 4. Once the user is created successfully, it will appear in the user list. -![Palmr Profile Menu](/public/main/users/new-user-table.png) +![Palmr Profile Menu](/assets/v1/main/users/new-user-table.png) --- @@ -52,7 +51,7 @@ After selecting **User Management**, you will be redirected to the **User Manage In the **User List**, under the **"Actions"** column, you will find a dropdown menu for each user. -![Palmr Profile Menu](/public/main/users/add-user-actions-dropdown.png) +![Palmr Profile Menu](/assets/v1/main/users/add-user-actions-dropdown.png) Available actions include: @@ -61,7 +60,7 @@ Available actions include: - Change user details including role. - Change the user password. -![Palmr Profile Menu](/public/main/users/edit-user-modal.png) +![Palmr Profile Menu](/assets/v1/main/users/edit-user-modal.png) - **Deactivate User** – Marks the user as inactive, preventing them from logging into the system. - **Activate User** – Reactivates a deactivated user, allowing them to log in again. diff --git a/apps/docs/src/content/docs/core/manual-installation.mdx b/apps/docs/content/docs/1.1.7-beta/manual-installation.mdx similarity index 100% rename from apps/docs/src/content/docs/core/manual-installation.mdx rename to apps/docs/content/docs/1.1.7-beta/manual-installation.mdx diff --git a/apps/docs/content/docs/1.1.7-beta/meta.json b/apps/docs/content/docs/1.1.7-beta/meta.json new file mode 100644 index 0000000..faf9858 --- /dev/null +++ b/apps/docs/content/docs/1.1.7-beta/meta.json @@ -0,0 +1,28 @@ +{ + "title": "v1.1.7-beta", + "description": "(Deprecated)", + "root": true, + "icon": "Building2", + "pages": [ + "---Introduction---", + "index", + "architecture", + "github-architecture", + "installation", + "manual-installation", + "api", + "---How to use Palmr.---", + "login", + "manage-users", + "upload", + "generate-share", + "configuring-smtp", + "available-languages", + "---Developers---", + "contribute", + "open-an-issue", + "---Sponsor this project---", + "gh-star", + "gh-sponsor" + ] +} diff --git a/apps/docs/src/content/docs/developers/open-an-issue.md b/apps/docs/content/docs/1.1.7-beta/open-an-issue.md similarity index 94% rename from apps/docs/src/content/docs/developers/open-an-issue.md rename to apps/docs/content/docs/1.1.7-beta/open-an-issue.md index 228c675..164eedb 100644 --- a/apps/docs/src/content/docs/developers/open-an-issue.md +++ b/apps/docs/content/docs/1.1.7-beta/open-an-issue.md @@ -24,7 +24,7 @@ Alternatively, you can search for "Palmr" in the GitHub search bar and click on On the Palmr repository page, click on the **Issues** tab near the top of the page. This will take you to the issues section of the repository. -![Palmr Profile Menu](/public/developers/issues-tab.png) +![Palmr Profile Menu](/assets/v1/developers/issues-tab.png) --- @@ -33,7 +33,7 @@ On the Palmr repository page, click on the **Issues** tab near the top of the pa Once you're in the issues section, click the **New Issue** button to start creating a new issue. -![Palmr Profile Menu](/public/developers/new-issue-btn.png) +![Palmr Profile Menu](/assets/v1/developers/new-issue-btn.png) --- @@ -47,7 +47,7 @@ You’ll now see a form where you can provide details about your issue. Here’s 3. **Labels (Optional)**: Add labels to categorize your issue (e.g., `bug`, `enhancement`, `question`). This helps the maintainers organize and prioritize issues. 4. **Attachments (Optional)**: You can attach screenshots, logs, or other files to help explain the issue. -![Palmr Profile Menu](/public/developers/new-issue-form.png) +![Palmr Profile Menu](/assets/v1/developers/new-issue-form.png) --- diff --git a/apps/docs/src/content/docs/main/upload.md b/apps/docs/content/docs/1.1.7-beta/upload.md similarity index 81% rename from apps/docs/src/content/docs/main/upload.md rename to apps/docs/content/docs/1.1.7-beta/upload.md index 0fc6b89..6721349 100644 --- a/apps/docs/src/content/docs/main/upload.md +++ b/apps/docs/content/docs/1.1.7-beta/upload.md @@ -17,36 +17,36 @@ Now let's focus on the file upload process. As mentioned, it is very simple, and On the home page, there is a **"Recent Uploads"** section. On the first initialization (when no file has been uploaded yet), it will appear like this: -![Recent Uploads Section](/public/main/upload/recent-uploads.png) +![Recent Uploads Section](/assets/v1/main/upload/recent-uploads.png) To upload a file, simply click on the **"Upload File"** button. This will open a modal where you can select the file you want to upload from your device. Some file types, such as images, audio, and video, will have a preview available. -![Upload File Button](/public/main/upload/upload-file-button.png) +![Upload File Button](/assets/v1/main/upload/upload-file-button.png) ### Example with an image: -![Preview Example](/public/main/upload/preview-example.png) +![Preview Example](/assets/v1/main/upload/preview-example.png) After selecting the file, you can either confirm the upload by clicking the **"Upload"** button or cancel the operation by clicking the **"Cancel"** button. -![Upload and Cancel Buttons](/public/main/upload/upload-cancel-buttons.png) +![Upload and Cancel Buttons](/assets/v1/main/upload/upload-cancel-buttons.png) Once one or more files have been uploaded, the **"Recent Uploads"** section will update and look like this: -![Recent Uploads with Files](/public/main/upload/recent-uploads-filled.png) +![Recent Uploads with Files](/assets/v1/main/upload/recent-uploads-filled.png) To upload a new file from this screen, click the **"Upload File"** button in the upper right corner of the section, and follow the same steps as before. -![New Upload Button](/public/main/upload/new-upload-button.png) +![New Upload Button](/assets/v1/main/upload/new-upload-button.png) This list on the home page shows only the **last 5 uploads**. To view older files or upload more, you need to go to the **"My Files"** page. You can access this by clicking on the **"View All"** button in the upper right corner of the section or by clicking on the **"My Files"** card on the home page. -![View All Button](/public/main/upload/view-all-button.png) +![View All Button](/assets/v1/main/upload/view-all-button.png) Or: -![My Files Card](/public/main/files/my-files-card.png) +![My Files Card](/assets/v1/main/files/my-files-card.png) --- @@ -54,7 +54,7 @@ Or: On the **"My Files"** page, the layout will look like this: -![My Files Page](/public/main/files/my-files-page.png) +![My Files Page](/assets/v1/main/files/my-files-page.png) Here, you have the option to **filter** your uploaded files or upload new ones by clicking the **"Upload File"** button and following the same steps explained earlier. @@ -72,13 +72,13 @@ The table fields include: ### Actions Column In the **"Actions"** column, you will find an icon that opens the following dropdown: -![Actions Dropdown](/public/main/files/actions-dropdown.png) +![Actions Dropdown](/assets/v1/main/files/actions-dropdown.png) Each option is self-explanatory, but let’s detail the **Edit** option: - **Edit** – Opens a modal where you can edit the file name, description, and other details. - ![Edit Modal](/public/main/files/edit-modal.png) + ![Edit Modal](/assets/v1/main/files/edit-modal.png) - You can also **delete** a file directly from the dropdown by selecting the **Delete** option. diff --git a/apps/docs/content/docs/2.0.0-beta/api.mdx b/apps/docs/content/docs/2.0.0-beta/api.mdx new file mode 100644 index 0000000..784d494 --- /dev/null +++ b/apps/docs/content/docs/2.0.0-beta/api.mdx @@ -0,0 +1,48 @@ +--- +title: 🔌 API Endpoints +tag: v2.0.0-beta +--- + +## 📚 Accessing the API Documentation + +Palmr. provides a **comprehensive, well-documented, and fully typed API** that has been carefully designed to ensure maximum developer productivity and ease of integration. + +### 🎯 Scalar-Based Documentation + +This API can be accessed through dedicated documentation endpoints at: + +- **In a production environment:** `{your_server_domain}/docs` or `{your_server_ip}/docs` +- **In a local environment:** http://localhost:3333/docs + +The API documentation is powered by **[Scalar](https://scalar.com/)**, which provides developers with a sophisticated and fully interactive interface for exploring, testing, and validating all available requests within the Palmr. ecosystem. This modern documentation platform enables real-time testing and visualization of API responses. Below is an example screenshot of the API documentation interface: + +![Palmr API Documentation](/assets/v2/api-docs/scalar.png) + + +We have made a deliberate decision to **not provide an online version** of the API documentation, as the endpoints and functionality may vary significantly depending on the specific version of Palmr. you have deployed in your environment. To ensure you're always working with accurate and version-specific documentation, we strongly recommend accessing the documentation only after initializing your API service. It's important to note that the API service is specifically designated as the **server** component within the official Palmr. GitHub repository. + +We strongly recommend utilizing **Scalar** as your primary tool for querying and testing the API, as the entire documentation system has been carefully optimized and designed with Scalar integration in mind. Scalar provides developers with an exceptionally intuitive and feature-rich interactive environment that streamlines the process of exploring endpoints, constructing and sending requests, and analyzing responses directly within its sophisticated interface. + +--- + +### 🔄 Swagger-Based Documentation + +Understanding that developers may have different preferences or requirements, we also maintain a **Swagger-based version** of the documentation for those who prefer this widely-adopted documentation standard or require compatibility with existing tools and workflows. + +![Palmr API Documentation](/assets/v2/api-docs/swagger.png) + +This alternative documentation format can be accessed at the following endpoints: + +- **In a production environment:** `{your_server_domain}/swagger` or `{your_server_ip}/swagger` +- **In a local environment:** http://localhost:3333/swagger + +Rest assured that both the Scalar and Swagger documentation versions maintain complete parity in terms of endpoint coverage and provide equally comprehensive documentation levels, ensuring successful testing and system integration regardless of your chosen documentation platform. + +These carefully curated documentation options have been implemented to ensure that developers have access to all the necessary resources, detailed information, and interactive tools required for seamless integration between Palmr. and both internal systems and third-party services. + +### 🔗 Useful Links + +For additional information and detailed documentation about the tools that power our API documentation, please refer to these official resources: + +- [Scalar Official Website](https://scalar.com/) +- [Swagger Official Website](https://swagger.io/) \ No newline at end of file diff --git a/apps/docs/content/docs/2.0.0-beta/architecture.mdx b/apps/docs/content/docs/2.0.0-beta/architecture.mdx new file mode 100644 index 0000000..54cdd4a --- /dev/null +++ b/apps/docs/content/docs/2.0.0-beta/architecture.mdx @@ -0,0 +1,62 @@ +--- +title: 🏗 Architecture of Palmr. +--- + +## 🔍 Overview + +Understanding the architecture of Palmr. is crucial for both deploying and scaling the application. Below is a diagram illustrating the main components: + +![Palmr Banner](/assets/v2/general/architecture.png) + +## 🛠 Technologies Used + +Each component in the Palmr. architecture plays a vital role in ensuring reliability, performance, and scalability. The stack is built with simplicity, performance, and flexibility in mind, everything is self-hosted, developer-friendly, and designed to scale without adding unnecessary complexity. + + +### 💾 PostgreSQL +Palmr. uses **PostgreSQL** as the primary database solution. It's a powerful, open-source relational database that’s trusted by developers around the world. PostgreSQL is fully ACID-compliant, which means it handles transactions safely and reliably. It’s perfect for storing structured data like user accounts, file metadata, transfer logs, and anything else that requires consistency. With advanced features like full-text search, custom data types (like JSONB), and strong indexing capabilities, PostgreSQL gives us the tools to scale efficiently without giving up query performance or flexibility. + +- Provides reliable and secure data storage, ensuring consistency and high performance for all database operations. +- Powerful indexing, query optimization, and support for complex data types. +- Ideal for handling large amounts of metadata and transactional data in a predictable and scalable way. + + +### 🎨 Next.js 15 + React + TypeScript +The frontend of Palmr. is built using **Next.js 15**, along with **React** and **TypeScript**, forming a modern stack that’s easy to maintain and super fast for end users. Next.js 15 brings server components, server actions, and a new app router system that makes rendering dynamic content incredibly efficient. This allows us to load only what’s needed, when it’s needed which makes the app feel snappy even under load. React provides a clean, component-based structure that makes it easy to break the UI into reusable pieces, and TypeScript helps prevent bugs before they even happen by enforcing static typing and better code navigation. Whether it's SSR, static pages, or dynamic user interactions, this trio handles it all seamlessly. + +- **React** enables the creation of a dynamic and responsive user interface with a component-based architecture. +- **TypeScript** adds static typing, enhancing code quality and reducing runtime errors. +- **Next.js 15** handles routing, server-side rendering, and server components for performance at scale. + + +### 📦 MinIO +Palmr. uses **MinIO** for object storage. MinIO is a lightweight, high-performance, S3-compatible storage solution that makes file handling simple and scalable. Every file uploaded to Palmr. Whether it's a personal file transfer or a shared asset is stored in MinIO. It’s built to handle huge amounts of data and can be deployed locally, on-premise, or in the cloud. Because it speaks the same API as Amazon S3, integrating with it is straightforward and familiar to most developers. And since it’s self-hosted, we have full control over performance, redundancy, and security. + +- Supports high-throughput file storage and retrieval. +- Ensures data integrity and redundancy. +- Compatible with AWS S3 APIs, making integration seamless. + + +### ⚡ Fastify +The backend of Palmr. is powered by **Fastify**, a super-fast Node.js web framework optimized for performance and low overhead. It’s designed to handle lots of concurrent requests with minimal resource usage, which is key for scalable backend services. Fastify also has a built-in schema validation system that ensures all incoming data is properly validated before reaching business logic, which helps prevent bugs and security issues. It follows a plugin-based architecture, making it easy to keep route handlers, services, and middlewares cleanly separated and easy to extend as the project grows. + +- Provides fast request handling with a lightweight core. +- Built-in schema-based validation for secure and reliable API handling. +- Supports plugin-based architecture for easy extensibility. + + +### 🔄 How It Works +1. **Frontend** — React + TypeScript + Next.js 15 handle the user interface and user interactions. +2. **Backend** — Fastify processes requests and communicates with the database and storage layers. +3. **Database** — PostgreSQL stores metadata and transactional data. +4. **Object Storage** — MinIO stores the actual files and ensures scalable, high-performance storage. + + +### 📚 Useful Links +- [PostgreSQL Documentation](https://www.postgresql.org/docs/) +- [Next.js Documentation](https://nextjs.org/docs) +- [React Documentation](https://react.dev/) +- [TypeScript Handbook](https://www.typescriptlang.org/docs/) +- [MinIO Documentation](https://min.io/docs/minio/container/index.html) +- [Fastify Documentation](https://fastify.dev/docs/latest/) + diff --git a/apps/docs/content/docs/2.0.0-beta/available-languages.mdx b/apps/docs/content/docs/2.0.0-beta/available-languages.mdx new file mode 100644 index 0000000..ba07a03 --- /dev/null +++ b/apps/docs/content/docs/2.0.0-beta/available-languages.mdx @@ -0,0 +1,52 @@ +--- +title: 🌐 Available languages +--- + +The project leverages next-intl, a powerful and flexible internationalization (i18n) library, to provide comprehensive language support across the entire application. This robust solution enables seamless translation management, date/time formatting, number formatting, and pluralization rules across different locales. The integration of next-intl ensures consistent internationalization throughout the application's components, pages, and features, while maintaining optimal performance through efficient bundle splitting and lazy loading of language resources. With its TypeScript support and React Server Components compatibility, next-intl serves as the foundation for delivering a truly global and accessible user experience. + +## 🗣️ Available Languages in Palmr. + +--- + +| Language | Code | Description | Translation | +|----------|------|-------------|-------------| +| 🇺🇸 English | en-US | Primary development language and default fallback option | 100% | +| 🇧🇷 Portuguese | pt-BR | Standard Brazilian Portuguese support | 100% | +| 🇫🇷 French | fr-FR | Standard French language support | 100% | +| 🇪🇸 Spanish | es-ES | Standard Spanish language support | 100% | +| 🇩🇪 German | de-DE | Standard German language support | 100% | +| 🇷🇺 Russian | ru-RU | Standard Russian language support | 100% | +| 🇮🇳 Hindi | hi-IN | Standard Hindi language support | 100% | +| 🇸🇦 Arabic | ar-SA | Standard Arabic language support with RTL | 100% | +| 🇯🇵 Japanese | ja-JP | Standard Japanese language support | 100% | +| 🇰🇷 Korean | ko-KR | Standard Korean language support | 100% | +| 🇹🇷 Turkish | tr-TR | Standard Turkish language support | 100% | +| 🇨🇳 Chinese | zh-CN | Standard Simplified Chinese support | 100% | + +### 🔄 Language Selection + +The application provides two convenient methods for language selection, ensuring a seamless user experience: + +### 🤖 1. Automatic Detection + +- The application features sophisticated automatic detection of the user's preferred browser language settings +- Intelligently utilizes the browser's preconfigured language preferences to set the initial application language + +### 👆 2. Manual Selection + +![](/assets/v1/main/language/language-selector.png) + +- Users have complete control to manually select their preferred language through an intuitive language selector interface in the UI +- Selected language preferences are persistently stored in the browser's localStorage for a consistent experience across sessions + +### ⭐ Default Language + +English (en-US) serves as the system's fallback language, ensuring consistent functionality even when language detection or selection encounters issues. This means that if a user's preferred language is not available or if there are any problems with language selection, the application will automatically default to English. This fallback mechanism is crucial for maintaining a seamless user experience and preventing any potential language-related disruptions. Additionally, all new features and updates are first implemented in English before being translated into other supported languages, ensuring that the English version always remains the most up-to-date and comprehensive. + +### 🔍 Language Detection + +The application employs advanced detection mechanisms to automatically identify and apply the user's browser language settings as the initial language configuration. For maximum flexibility, users can easily override this selection at any time using the convenient language switcher, accessible via the globe icon prominently displayed in the navigation bar. + +### ↔️ RTL Support + +The application incorporates comprehensive right-to-left (RTL) text handling capabilities, with particular attention paid to Arabic (ar-SA) language requirements, ensuring proper text alignment, layout direction, and user interface elements. \ No newline at end of file diff --git a/apps/docs/content/docs/2.0.0-beta/configuring-smtp.mdx b/apps/docs/content/docs/2.0.0-beta/configuring-smtp.mdx new file mode 100644 index 0000000..d08f9ae --- /dev/null +++ b/apps/docs/content/docs/2.0.0-beta/configuring-smtp.mdx @@ -0,0 +1,67 @@ +--- +title: ✉️ Configuring SMTP +--- + +For Palmr to function with all its best features, we need to configure our email server. To make this easier, there is a built-in configuration panel inside **Settings** in Palmr. However, only users with an **ADMIN** profile can access and configure these settings. + +## ❓ Why Configure SMTP? + +The main functionalities that depend on SMTP configuration are: +- 🔑 **Password Reset** – Users who forget their password and cannot access the **Settings** panel need this feature. +- 📧 **Email Notifications** – Recipients will receive emails when new shares are sent to them. + +Now, let's go through the step-by-step process to configure the **SMTP Server**. + +--- + +### 🔧 Accessing SMTP Settings + +To access **Settings**, an **ADMIN** user must click on the profile picture in the **header** and select **Settings** from the dropdown menu. + +![Dropdown Menu](/assets/v1/main/smtp/dropdown-menu.png) + +Once inside the **Settings** panel, click on the **Email** card to expand the SMTP configuration options. + +![Closed Settings Card](/assets/v1/main/smtp/closed-card.png) + +After expanding the card, the following SMTP configuration fields will appear: + +![Opened Settings Card](/assets/v1/main/smtp/opened-card.png) + +--- + +### ⚙️ Configuring SMTP Server + +The first step is to **enable SMTP** by selecting "Yes" in the **SMTP Enabled** field. + +![SMTP Enabled](/assets/v1/main/smtp/smtp-enabled.png) + +Once SMTP is enabled, you can configure the other necessary fields: + +- **Sender Name** – This will appear as the sender’s name in emails. (Example: "Palmr") +- **Sender Email** – The email address from which notifications will be sent. (Example: "noreply@palmr.app") +- **SMTP Server** – The SMTP server address. You can use any email service provider. For Gmail, use `smtp.gmail.com` (this is the recommended option and set as default). +- **SMTP Port** – The server port. For Gmail, the standard port is **587**. +- **SMTP Username** – The username for the SMTP server. For Gmail, enter your email address. +- **SMTP Password** – The SMTP password. (Generate an App Password for Gmail) + +> **Important:** If using **Gmail**, you need to generate an **App Password** instead of using your standard email password. +> For other email services, consult the official documentation of the service provider you are using. We recommend using Gmail for simplicity and limits the number of emails sent. + +--- + +### 🔐 Generating a Gmail App Password + +To generate an App Password for Gmail: +1. Go to [Google My Account](https://myaccount.google.com/). +2. Select **Security**. +3. Scroll down to **App Passwords**. +4. Generate a new password specifically for Palmr. + +For a complete guide, refer to: **[How to set up SMTP credentials with Gmail](https://medium.com/rails-to-rescue/how-to-set-up-smtp-credentials-with-gmail-for-your-app-send-email-cf236d11087d)**. + +--- + +### ✅ Finalizing SMTP Configuration + +After entering the correct information, save the settings. Palmr is now ready to send emails for password resets and share notifications! diff --git a/apps/docs/content/docs/2.0.0-beta/contribute.mdx b/apps/docs/content/docs/2.0.0-beta/contribute.mdx new file mode 100644 index 0000000..cc56cf2 --- /dev/null +++ b/apps/docs/content/docs/2.0.0-beta/contribute.mdx @@ -0,0 +1,217 @@ +--- +title: 🤝 How to Contribute +--- + +## 👋 Introduction + +Thank you for your interest in contributing to the **Palmr.** project! Contributions are what make the open-source community such an amazing place to learn, inspire, and create. Whether you're fixing bugs, adding new features, improving documentation, or sharing ideas, every contribution helps make Palmr better for everyone. We welcome contributors of all experience levels - from beginners to seasoned developers. This comprehensive guide will walk you through the process of contributing to Palmr, from setting up your development environment to submitting your first pull request. We're excited to have you join our community of contributors! + +--- + +### 🔑 GitHub Login + +Before you can contribute, you need to be logged into your GitHub account. If you don't have an account yet, you can sign up for free at **[GitHub](https://github.com/)**. Having a GitHub account is essential as it allows you to fork repositories, submit pull requests, and interact with other contributors. Make sure to use a professional email address when creating your account, and consider enabling two-factor authentication for enhanced security. Once your account is set up, you can customize your profile and start exploring the vast open-source community on GitHub. + +--- + +### 🔍 Access the Repository +Once you're logged in, go to the Palmr repository by clicking on this link: **[https://github.com/kyantech/Palmr](https://github.com/kyantech/Palmr)**. The repository contains all the source code, documentation, and resources for the Palmr project. Take a moment to explore the repository structure, including the README file, which provides an overview of the project. + +Alternatively, you can search for "Palmr" in the GitHub search bar and click on the repository owned by **kyantech**. When searching, make sure you're looking at the official repository by checking the owner and repository name. The repository should have a description that matches the Palmr project and show recent activity from the maintainers. You can also check the number of stars, forks, and watchers to verify you're accessing the correct repository. + +--- + +### 🍴 Fork the Repository + +To contribute to the project, you'll need to create your own copy of the repository. This is called a **fork**. Here's how to do it: + +1. Click the **Fork** button at the top right of the repository page. +2. Select where you want to fork the repository (your personal account or an organization). +3. Wait a few moments while GitHub creates your fork. +4. This will create a copy of the repository under your GitHub account. +5. You'll be automatically redirected to your forked repository once it's ready. + +The fork will maintain a connection to the original repository, allowing you to: +- Keep your fork synchronized with the original repository +- Submit pull requests from your fork to the original repository +- Work independently on your own copy without affecting the original + +--- + +### 📥 Clone the Fork + +Next, you’ll need to clone your forked repository to your local machine. Here’s how: +1. On your forked repository page, click the **Code** button. +2. Copy the repository URL (HTTPS or SSH). +3. Open your terminal or command prompt and run the following command to clone the repository: + + ```bash + git clone + ``` + +4. Navigate into the cloned directory: + + ```bash + cd Palmr + ``` + +--- + +### 🔄 Set up Base Branch + +Before making changes, ensure your local repository is set up to track the `next` branch from the original Palmr repository. Here’s how: +1. Add the original Palmr repository as a remote: + + ```bash + git remote add upstream https://github.com/kyantech/Palmr.git + ``` + +2. Fetch the latest changes from the `next` branch: + + ```bash + git fetch upstream next + ``` + +3. Create a new branch for your contribution based on `upstream/next`: + + ```bash + git checkout -b your-branch-name upstream/next + ``` + +--- + +### ✏️ Make Local Changes +Now you're ready to make your contributions! This could include: +- Fixing a bug +- Adding a new feature +- Improving documentation +- Writing tests +- Enhancing performance +- Adding translations +- Improving accessibility +- Refactoring code +- Adding examples +- Reporting issues + +Make your changes in your local repository using your preferred code editor. Here are some tips for making changes: + +1. **Follow the Style Guide**: Make sure your code follows the project's coding standards and style guidelines +2. **Test Your Changes**: Run tests locally to ensure your changes don't break existing functionality +3. **Keep Changes Focused**: Make small, focused changes that address a single issue or feature +4. **Document Your Changes**: Add or update documentation as needed to explain your changes +5. **Review Your Work**: Double-check your changes before committing to ensure quality + +Remember to regularly save your work and test your changes incrementally to catch any issues early in the development process. + +--- + +### 📝 Use Conventional Commits + +Once you’ve made your changes, commit them to your branch using **Conventional Commits**. Conventional Commits help maintain a clean and consistent commit history. Here’s how to format your commit messages: + +**Commit Message Format:** +`(): ` + +**Examples:** +- `feat: add user authentication` +- `fix(api): resolve null pointer exception` +- `docs: update README file` +- `chore: update dependencies` + +**Steps to Commit:** +1. Stage your changes: + + ```bash + git add . + ``` + +2. Commit your changes with a properly formatted message: + + ```bash + git commit -m "feat: add new feature for user profiles" + ``` + +--- + +### 📤 Push Changes + +After committing your changes, you'll need to push them to your forked repository on GitHub. This step synchronizes your local changes with your remote repository. Here's how to do it: + +1. First, ensure your branch is up-to-date with any remote changes: + ```bash + git pull origin your-branch-name + ``` + +2. Then push your commits to your forked repository: + ```bash + git push origin your-branch-name + ``` + +If this is the first time pushing this branch, you might need to set the upstream branch: + ```bash + git push -u origin your-branch-name + ``` + +If you encounter any errors while pushing: +- Make sure you have the correct permissions on your fork +- Verify your remote URL is correct using `git remote -v` +- Check if you need to authenticate with GitHub + +--- + +### 🔀 Create Pull Request + +Now that your changes are on GitHub, you can open a **Pull Request (PR)** to propose your changes to the `next` branch of the Palmr repository. Here’s how: +1. Go to your forked repository on GitHub. +2. Click the **Pull Request** button. +3. On the PR creation page: + - Set the **base repository** to `kyantech/Palmr`. + - Set the **base branch** to `next`. + - Set the **head repository** to your forked repository. + - Set the **compare branch** to your branch (`your-branch-name`). +4. Fill out the PR form with a clear title and description of your changes. +5. Click **Create Pull Request**. + +--- + +### ⏳ Await Review + +Once your PR is submitted, the maintainers will review your changes. They may provide feedback or request additional changes. During this process: + +- **Monitor Your PR**: Keep an eye on GitHub notifications for any comments or requests +- **Be Responsive**: Try to address feedback promptly and professionally +- **Make Updates**: If changes are requested, update your branch and push the new commits +- **Ask Questions**: Don't hesitate to ask for clarification if needed +- **Be Patient**: The review process may take some time depending on maintainer availability + +Remember that code review is a collaborative process aimed at ensuring code quality. Stay engaged and maintain open communication with the maintainers throughout the review process. + +--- + +## 💡 Contribution Tips + +To ensure your contribution is accepted, follow these tips: +- **Use Conventional Commits**: Write clear and consistent commit messages using the Conventional Commits format. +- **Keep Your PRs Small**: Focus on one issue or feature per PR to make it easier to review. +- **Be Patient**: Maintainers are often volunteers and may take some time to review your PR. +- **Write Tests**: Include tests for any new features or bug fixes you implement. +- **Follow Code Style**: Adhere to the project's coding standards and style guidelines. +- **Update Documentation**: Keep documentation in sync with code changes. +- **Engage in Discussion**: Participate in PR discussions and be open to feedback. +- **Review Others' PRs**: Help the community by reviewing other contributors' pull requests. +- **Stay Updated**: Keep your fork synchronized with the main repository. + +--- + +## ⭐ Why Contribute? + +Contributing to open-source projects like Palmr has many benefits: +1. **Improves the Project**: Your contributions help make the project better for everyone. +2. **Builds Your Skills**: You’ll gain experience working with Git, GitHub, and collaborative coding. +3. **Supports the Community**: Open-source thrives on community contributions. Your work helps sustain the project. + +--- + +## 🎉 Final Words + +That's it! You've successfully contributed to the **🌴 Palmr.** project on GitHub. Thank you for your time and effort in making Palmr better for everyone. We appreciate your contribution! diff --git a/apps/docs/content/docs/2.0.0-beta/first-login.mdx b/apps/docs/content/docs/2.0.0-beta/first-login.mdx new file mode 100644 index 0000000..c93f104 --- /dev/null +++ b/apps/docs/content/docs/2.0.0-beta/first-login.mdx @@ -0,0 +1,108 @@ +--- +title: 👋 First Login (Admin) +--- +After successfully initiating all required services according to the detailed deployment instructions provided, you will gain access to the frontend interface through the following designated endpoints: + +- **Production environment:** `{your_web_domain}` or `{your_server_ip}` - This is your primary access point for the live application deployment +- **Local environment:** [http://localhost:4173](http://localhost:4173/) - This endpoint is specifically for development and testing purposes + +Upon successfully navigating to the frontend interface through either of these endpoints, you will be presented with a comprehensive welcome screen, as illustrated in the image below: + +![Landing Page](/assets/v1/general/lp.png) + +What you are viewing is the **Palmr. landing page** ✨, which serves as an introductory interface providing essential information about the application's capabilities and features. While this landing page is displayed by default during your initial setup, you have the flexibility to modify this configuration later. Should you prefer, you can configure the system to bypass this landing page and present the login interface as your primary entry point. However, for the purposes of initial system familiarization, the landing page is deliberately set as the default welcome screen. + +--- + +## 🔑 First Login + +Prominently displayed at the top of the landing page, you will notice a clearly marked button that enables you to authenticate and access Palmr.: + +> But you may wonder: +> + +To facilitate a smooth onboarding experience, Palmr. has been thoughtfully designed with pre-configured **seed data** that is automatically implemented during the initial system initialization. This preliminary data setup includes a comprehensive **admin user** account that is granted complete access privileges, enabling full control over all system settings and user management functionalities within the application environment. + +Upon selecting the **Login** button, the system will seamlessly redirect you to the authentication interface, which presents itself as shown in the following image: + +![Login Page](/assets/v1/ui/login.png) + +For your initial access to the system, please utilize these pre-configured authentication credentials: + +### 👤 Admin Credentials + +| User | Password | +| --- | --- | +| `admin@example.com` | `admin123` | + +Following successful validation of your credentials, the system will authenticate your session and automatically direct you to Palmr.'s primary dashboard interface, which appears as demonstrated in this image: + +![Dashboard](/assets/v1/ui/dashboard.png) + +Having completed these steps successfully, you have now established an authenticated session and are fully prepared to explore and utilize the comprehensive feature set that Palmr. has to offer! 🎉 + +--- + +## 🛡️ Recommendations After First Access + +Given that Palmr.'s initial configuration includes a solitary default admin user within the seed data, it is **strongly recommended** as a security best practice to modify the default administrative credentials immediately following your first successful login. This crucial step is fundamental to establishing and maintaining the security integrity of your Palmr. instance. + +Please follow this detailed sequence of steps to update your administrative credentials and enhance the security of your Palmr. installation: + +### 🔧 Access the Profile Settings + +1. Locate and click the **user icon** positioned in the upper right corner of your screen interface. +2. Upon clicking, you will be presented with an expandable dropdown menu containing several configuration options: + +![Menu](/assets/v1/ui/menu.png) + +1. From the available options in the dropdown menu, select **"Profile"**. This selection will navigate you to the comprehensive profile settings interface: + +![Profile](/assets/v1/ui/profile.png) + +--- + +### 📝 Update the Admin Profile + +Within the profile settings interface, you have full access to modify all information associated with the administrative account. + +- To enhance security through password modification, input and confirm your newly chosen secure password. +- Take this opportunity to review and adjust any additional profile details according to your specific requirements and preferences. + +**Tip:** ✨ To establish robust security measures, ensure your new password incorporates the following elements: + +- A minimum length of 12 characters to provide adequate complexity +- A diverse combination of uppercase and lowercase alphabetical characters +- An assortment of numerical digits and special character symbols + +--- + +### 📸 Update the Profile Picture + +To enhance the personalization of your administrative profile, you have the option to customize your profile picture. + +1. Identify and select the **camera icon** positioned adjacent to your current avatar display. +2. Browse and select an appropriate image file from your local storage device. + +![Profile Picture](/assets/v1/ui/profile_picture.png) + +> 💡 Recommendation: For optimal visual presentation, utilize an image with equal width and height dimensions (square format). +> + +--- + +## ⚠️ Troubleshooting + +Should you encounter any technical difficulties during the initial authentication process or while updating your profile information, please verify the following system components: + +- Confirm the operational status of all essential services, including the frontend interface, backend systems, MinIO storage, and database connections. +- Verify the accurate configuration of all necessary environment variables within your system. +- Ensure the successful and complete application of all database seed operations. + +--- + +## 🔒 Security Best Practices + +- Following the successful configuration of your administrative account, establish additional user accounts with appropriately restricted access permissions based on specific roles and responsibilities. +- Implement HTTPS protocol to ensure secure data transmission between client devices and the server infrastructure. +- Maintain system security by regularly implementing updates to your Palmr. installation to incorporate the latest security patches and system improvements. \ No newline at end of file diff --git a/apps/docs/content/docs/2.0.0-beta/generate-share.mdx b/apps/docs/content/docs/2.0.0-beta/generate-share.mdx new file mode 100644 index 0000000..5f5ef2b --- /dev/null +++ b/apps/docs/content/docs/2.0.0-beta/generate-share.mdx @@ -0,0 +1,152 @@ +--- +title: 🔗 Managing shares +--- + +## 📤 Creating a share + +Creating a share in Palmr is designed to be a straightforward and user-friendly experience that anyone can master quickly. While the platform offers several methods for share creation, we recommend beginning with the most accessible approach: utilizing the **Home Page**, particularly through the well-organized **Recent Shares** section. + +___ + +### Home Page + +When you visit the home page, you'll immediately notice the **"Recent Shares"** section, which serves as your central hub for file sharing. For new users who haven't created any shares yet, this section presents a clean, welcoming interface as follows: + +![](/assets/v1/main/shares/share-section.png) + +For first-time users, the interface features a prominently positioned **"Create Share"** button that stands out against the clean background, making it impossible to miss. + +![](/assets/v1/main/shares/create-first-share.png) + +> Note: One of Palmr's unique features is its flexibility - you don't need to upload files to create a share! This might seem counterintuitive at first, but it's a deliberately designed feature that many users find invaluable for their specific workflows and use cases. This approach allows you to set up the sharing framework first and add content later. +> + +This design philosophy reflects Palmr's user-centric approach: you can establish your share's parameters and settings first, then populate it with files at your convenience. Furthermore, all aspects of your share remain fully editable at any time, providing maximum flexibility. + +To initiate the share creation process, locate and click the **"Create Share"** button positioned centrally within the **Recent Shares** section. This action will trigger the appearance of a comprehensive **Create Share** modal window: + +![](/assets/v1/main/shares/create-share-modal.png) + +Within the modal, you'll find various fields to customize your share. While some fields are optional, they each serve important functions in controlling how your share behaves. Pay particular attention to these three powerful security options - **Expiration Date**, **Max Views**, and **Password** - as they significantly enhance your control over how recipients interact with your shared content: + +- **Password:** Adding this extra layer of security ensures that only recipients with the correct password can gain access to your shared content, providing an additional verification step. +- **Max Views:** This feature allows you to set a specific limit on the number of times your share can be accessed. Once this threshold is reached, the share becomes inaccessible unless you, as the creator, choose to adjust or remove the viewing limit. +- **Expiration Date:** By setting this parameter, you can determine precisely how long your share remains accessible. After the specified date passes, the share automatically deactivates, though you retain the ability to extend this deadline if needed. + +While the **name** field isn't mandatory, we strongly encourage users to assign meaningful names to their shares for easier management and organization of multiple shares over time. + +After successfully creating a share, the **Recent Shares** section transforms into an informative table display, presenting comprehensive details through the following columns: + +- **Name** +- **Created At** +- **Expires At** +- **Status** +- **Security** +- **Files** +- **Recipients** +- **Actions** + +![](/assets/v1/main/shares/shares-table.png) + +For your convenience, once you've created your first share, a **"New Share"** button appears in the upper right corner of the **Recent Shares** section, making it easy to create additional shares. + +![](/assets/v1/main/shares/new-share-btn.png) + +This conveniently positioned button provides quick access to the **Create Share** modal whenever you need to create another share. + +To maintain a clean and manageable interface, the **Recent Shares** section displays your **last 5 shares** by default. When you need to access your complete sharing history, simply click the **"View All"** button to see your entire collection of shares. + +![](/assets/v1/main/shares/recent-shares-filled.png) + +![](/assets/v1/main/shares/view-all-button.png) + +Upon clicking this button, you'll be seamlessly redirected to the comprehensive **Shares Management** page. + +![](/assets/v1/main/shares/my-shares-page.png) + +For quick access to your complete share collection, you can also reach the **Shares Management** page by clicking the conveniently placed **"My Shares"** card on the home page. + +![](/assets/v1/main/shares/my-shares-card.png) + +--- + +### 📊 Shares Management Page + +The **Shares Management** page functions similarly to the **Uploads Management** page but offers expanded capabilities. Here, you'll find a complete overview where you can **add, remove, edit, and view all created shares** without being restricted to the five-share limit of the Recent Shares section. + +Each share has an **Actions** column with the following options: + +![](/assets/v1/main/shares/actions-column.png) + +___ + +## ✏️ Edit Share + +The **Edit** button provides access to a comprehensive interface where you can modify and update all share details as needed. + +![](/assets/v1/main/shares/edit-share-modal.png) + +## 📁 Manage Files + +___ + +Through the **Manage Files** button, you gain complete control over the content of your share, with the ability to both add new files and remove existing ones. + +![](/assets/v1/main/shares/manage-files-modal.png) + +___ + +## 👥 Manage Recipients + +The **Manage Recipients** button opens an interface where you can maintain your recipient list, adding or removing access as needed. + +> Note: For email notifications to function properly, please ensure that your system's SMTP settings are correctly configured and active. +> + +![](/assets/v1/main/shares/manage-recipients-modal.png) + +___ + +## 👀 View Share Details + +The **View Details** option provides a comprehensive overview of all aspects and settings associated with your share. + +![](/assets/v1/main/shares/share-details-modal.png) + +___ + +## 🔗 Generate Share Link + +The **Generate Link** feature allows you to create a customizable sharing link for easy distribution of your content. + +![](/assets/v1/main/shares/generate-share-link-modal.png) + +After generation, the system presents you with the link for immediate viewing and copying. + +![](/assets/v1/main/shares/copy-link-modal.png) + +A convenient dropdown menu provides options to either edit the generated link's settings or copy it to your clipboard. + +![](/assets/v1/main/shares/dropdown-with-copy.png) + +When recipients access your generated link, they'll be able to both **view and download** the shared files according to the permissions you've set. + +![](/assets/v1/main/shares/share-screen.png) + +___ + +## Delete Share + +Clicking the + +**Delete** + +button allows you to permanently remove any share that's no longer needed. + +![](/assets/v1/main/shares/delete-share-modal.png) + +--- + +### 📝 Summary + +Palmr's share creation system exemplifies intuitive design and flexible functionality. The platform offers comprehensive features including file-free share creation, customizable share settings, recipient management, and secure link generation. The dedicated **Shares Management** page serves as your command center, providing complete oversight and control of your entire sharing ecosystem. \ No newline at end of file diff --git a/apps/docs/content/docs/2.0.0-beta/gh-sponsor.mdx b/apps/docs/content/docs/2.0.0-beta/gh-sponsor.mdx new file mode 100644 index 0000000..19e4621 --- /dev/null +++ b/apps/docs/content/docs/2.0.0-beta/gh-sponsor.mdx @@ -0,0 +1,110 @@ +--- +title: 💝 Github Sponsors +--- + +## 👋 Introduction + +Sponsoring a project on GitHub is a powerful way to support its development and ensure its long-term sustainability. This tutorial will guide you through the process of sponsoring the **Palmr.** project on GitHub using GitHub Sponsors. + +By becoming a sponsor, you'll not only help maintain and improve the project, but you'll also: + +- Support continuous development and bug fixes +- Enable new feature implementations +- Help cover hosting and infrastructure costs +- Show appreciation for the developers' hard work +- Join a community of supporters who value open source + +--- + +### 🔑 GitHub Login + +Before you can sponsor a project, you need to be logged into your GitHub account. If you don't have an account yet, you can sign up for free at [GitHub](https://github.com/). Having an account also allows you to: + +- Follow project updates +- Report issues +- Contribute to discussions +- Access sponsor-only content (if available) + +--- + +### 🔍 Access the Repository + +Once you're logged in, go to the Palmr. repository by clicking on this link: [https://github.com/kyantech/Palmr](https://github.com/kyantech/Palmr). + +Alternatively, you can search for "Palmr" in the GitHub search bar and click on the repository owned by **Kyantech**. + +You can also: +- Star the repository to show your support +- Watch it for updates +- Fork it if you want to contribute + +--- + +### 💖 Click the Sponsor Button + +On the Palmr repository page, you'll see a **Sponsor** button at the top right corner of the page. Click this button to proceed. The button is typically highlighted in a distinct color to make it easily visible. + +![Palmr Sponsor Button](/assets/v1/sponsor/sponsor-btn.png) + +Pro tip: You can also access the sponsorship page directly through your GitHub dashboard under "Sponsoring" if you've sponsored us before. + +--- + +### 💰 Choose a Custom Sponsorship + +GitHub Sponsors allows you to sponsor the project with a **custom amount starting at $1**: + +1. On the sponsorship page, look for the option to **enter a custom amount**. +2. Type in the amount you'd like to sponsor (e.g., $1, $5, $10, or any amount you choose). +3. Select the billing frequency (**monthly** or **one-time**). +4. Consider setting up automatic annual sponsorship for a simplified experience. +5. Look for any special tier benefits that might be available at different sponsorship levels. + +![Sponsor Page Example](/assets/v1/sponsor/sponsor-page.png) + +--- + +### ✅ Complete Your Sponsorship + +After entering your custom amount and selecting the billing frequency, you'll be prompted to enter your payment details. Follow the instructions to complete the sponsorship process. + +Once done, you'll officially be a **Palmr sponsor**! 🙌 + +--- + +### ⭐ Why Sponsoring Matters + +- 🧱 Supports Sustainability +Your sponsorship helps keep the project alive and maintained long-term. + +- 🚀 Encourages Innovation +Financial support gives developers the freedom to try new ideas and push boundaries. + +- 🫶 Shows Deep Appreciation +Sponsoring is a meaningful, tangible way to thank developers for their work. + +- 🏆 Earns You Recognition +Many projects publicly thank their sponsors — you might appear in the README or on the site! + +- 🌱 Helps Open Source Thrive +Open-source projects rely on community support. Sponsoring helps the ecosystem grow. + +--- + +## 🎁 What Happens After Sponsoring + +Once you become a sponsor: +1. You'll receive a confirmation email from GitHub +2. Your name will appear in our sponsors list +3. You'll get access to sponsor-only updates and content +4. You'll be invited to our private Discord channel +5. You'll receive early access to new features + +--- + +## 🌟 Final Words + +That's it! You've successfully sponsored the **Palmr.** project on GitHub. +Your support will help ensure this open-source project continues to evolve and thrive. +**We appreciate you and welcome you to our community!** 🎉 + diff --git a/apps/docs/content/docs/2.0.0-beta/gh-star.mdx b/apps/docs/content/docs/2.0.0-beta/gh-star.mdx new file mode 100644 index 0000000..a276df4 --- /dev/null +++ b/apps/docs/content/docs/2.0.0-beta/gh-star.mdx @@ -0,0 +1,127 @@ +--- +title: ⭐ Star on Github +--- + +## 👋 Introduction + +Starring a project on GitHub is a great way to show appreciation for a repository and to bookmark it for easy access later. This tutorial will guide you through the process of starring the **Palmr** project on GitHub. By starring our repository, you help increase its visibility and support the ongoing development of the project. + +--- + +### 🔑 GitHub Login + +Before you can star a project, you need to be logged into your GitHub account. If you don't have an account yet, you can sign up for free at [GitHub](https://github.com/). Here's how to get started: + +1. Visit [GitHub's signup page](https://github.com/signup) +2. Enter your email address +3. Create a strong password +4. Choose a username +5. Complete the verification process +6. Select your preferences and complete the setup + +Once your account is created, make sure to verify your email address to access all GitHub features. + +--- + +### 🔍 Access the Repository + +There are several ways to find and access the Palmr repository: + +1. **Direct Link**: Go to the Palmr repository by clicking on this link: [https://github.com/kyantech/Palmr](https://github.com/kyantech/Palmr) + +2. **Search Method**: + - Go to GitHub's main page + - Click the search bar at the top + - Type "Palmr" + - Look for the repository owned by **Kyantech** + - Click on the repository name to access it + +3. **Through Profile**: + - Visit Kyantech's GitHub profile + - Navigate to the "Repositories" tab + - Find and click on "Palmr" + +--- + +### 🌟 Find the Star Button + +Once you're on the Palmr repository page, you'll find the "Star" button in the top-right section of the page. Here's what to look for: + +1. Look at the top navigation bar of the repository +2. Find the row of action buttons (Watch, Fork, Star) +3. The Star button will be prominently displayed with a star icon ⭐ +4. You may see the current star count next to the button + +![Palmr Profile Menu](/assets/v1/sponsor/star-btn.png) + +--- + +### ✅ Confirm the Star + +After clicking the "Star" button, several things will happen: + +1. The button will change from "Star" to "Unstar" +2. The star count will increase by one +3. The button will fill with color to indicate it's active +4. The repository will be added to your starred repositories list + +You can access your starred repositories anytime by: +- Clicking your profile picture +- Selecting "Your stars" from the dropdown menu +- Or visiting: https://github.com/[your-username]?tab=stars + +To remove your star, simply click the "Unstar" button at any time. + +![Palmr Profile Menu](/assets/v1/sponsor/starred-button.png) + +--- + +### 💫 Why Starring Matters + +Starring a repository on GitHub is more than just a bookmarking tool—it’s a way to support the project and its developers. Here’s why starring is so important: + +- 🙌 Shows Appreciation +Starring a repository is a simple way to show your appreciation for the hard work and effort that goes into maintaining and developing a project. + +- 📈 Increases Visibility +The more stars a repository has, the more visible it becomes on GitHub. + +- 💪 Encourages Developers +Seeing stars motivates developers to continue improving the project. + +- 🔍 Helps with Discovery +GitHub prioritizes repositories with more stars in trending and recommendations. + +- 📚 Tracks Your Interests +Starred repositories are saved to your list for easy access later. + +- 🌍 Supports Open Source +Your stars help sustain the open-source community and the Palmr project. + +--- + +## 💝 Small Action / Big Impact + +Starring a repository takes just a second, but it can have a huge impact on the project's growth and development. Here's what your star means to us: + +- Helps drive project momentum +- Encourages more community participation +- Provides valuable feedback on project value +- Helps us set and achieve development goals +- Supports sustainable open-source development + +Your star is more than just a number - it's a vote of confidence in our vision and helps shape the future of Palmr. + +--- + +## 🎉 Final Words + +That's it! You've successfully starred the **Palmr** project on GitHub. Thank you for supporting Palmr and becoming part of our growing community! Your support helps us continue improving and expanding the project for everyone. + +Feel free to explore our other ways to contribute, like: +- Sharing Palmr with others +- Reporting issues +- Contributing code +- Joining discussions + +Every interaction helps make Palmr. better! diff --git a/apps/docs/content/docs/2.0.0-beta/github-architecture.mdx b/apps/docs/content/docs/2.0.0-beta/github-architecture.mdx new file mode 100644 index 0000000..f5dd7a3 --- /dev/null +++ b/apps/docs/content/docs/2.0.0-beta/github-architecture.mdx @@ -0,0 +1,145 @@ +--- +title: Github Architecture +--- + +import { File, Folder, Files } from "fumadocs-ui/components/files"; + +## Project Structure + + + + + + + + + + + + + + + + + +## Core Components + +### 🖥️ Frontend Application (apps/web) + + **Technology Stack:** + +- Next.js 15 (App Router) +- React 18 +- TypeScript +- TailwindCSS +- shadcn/ui components +- next-intl for internationalization + +Palmr.'s frontend is built with **Next.js 15**, using the App Router and Server Components for performance, scalability, and flexibility. The structure is modular and feature-based, keeping things easy to evolve as the product grows. UI logic runs on **React 18**, and **TypeScript** adds type safety that prevents a lot of silent bugs. Styles are handled with **TailwindCSS**, letting us build clean, responsive interfaces quickly. For components, we rely on **shadcn/ui**, a headless component library built with Radix UI and Tailwind, it’s fast, accessible, and fully customizable. + +Internationalization is handled by **next-intl**, which integrates perfectly with Next.js routing. It supports locale-aware routes, per-page translation loading, and plural rules, all without any extra client-side bloat. It’s flexible, lightweight, and great for apps with multilingual audiences. + +The frontend is organized with: + +- A **components-based architecture** for modular UI +- **Custom hooks** to isolate logic and side effects +- A **route protection system** using session cookies and middleware +- A **file management interface** integrated with the backend +- A **reusable modal system** used for file actions, confirmations, and more +- **Dynamic, locale-aware routing** using next-intl + +--- + +### ⚙️ Backend Service (apps/server) + + **Technology Stack:** + +- Fastify +- PostgreSQL +- MinIO (S3-compatible) +- Prisma ORM + +The backend is built on **Fastify**, a blazing-fast web framework for Node.js. It’s lightweight, modular, and optimized for high performance. Every route is validated using JSON schema, which helps keep the API consistent and secure. Auth flows are built using JWTs stored in HTTP-only cookies, and everything from file uploads to token-based sharing goes through this layer. + +Data is stored in **PostgreSQL**, which handles user info, file metadata, session tokens, and more. For actual file storage, we use **MinIO**, a fast, S3-compatible object store that’s self-hosted and super scalable. It’s perfect for keeping user files isolated and safe. We use **Prisma** as our ORM to simplify database access, it gives us type-safe queries and easy-to-read code. + +Key features include: + +- **Authentication/authorization** with JWT + cookie sessions +- **File management logic** including uploads, deletes, and renames +- **Storage operations** to handle bucket creation, usage tracking, and cleanup +- A **share system** that generates tokenized public file links +- Schema-based request validation for all endpoints +- Prisma models that keep the database logic predictable and type-safe + +--- + +### 📚 Documentation (apps/docs) + + **Technology Stack:** + +- Fumadocs +- MDX (Markdown + JSX) +- React-based components + +The docs are built using **Fumadocs**, a modern documentation system built on top of Next.js. It uses **MDX**, so you can mix Markdown with interactive React components, perfect for developer tools and open-source projects. Pages are fast, versionable, and easy to customize. The goal is to keep the documentation as close to the codebase as possible, using shared components where needed and reusing UI patterns directly from the app. + +It supports sidebar navigation, keyboard shortcuts, dark mode, and even interactive demos or UI previews. The file tree you see above, for example, is powered by a real React component from the docs. + +- Built with **Fumadocs**, powered by Next.js +- Supports **MDX** and full React component embedding +- Ideal for technical docs and live code samples +- Styled using the same Tailwind setup from the main app + +--- + +### 🏗️ Infrastructure + +Palmr. is fully containerized using **Docker**, which means every service: frontend, backend, database, storage, runs in its own isolated environment. With `docker-compose`, the whole stack spins up locally with a single command. It’s also easy to deploy to services like Fly.io, Render, or your own VPS. + +Volumes are used to persist data locally, and containers are networked together so that all services can talk to each other securely. + +- **Docker-first architecture** with all services containerized +- Configurable through `.env` and compose overrides +- Local volumes and named networks +- Easy to deploy and scale on any container-compatible infra + +--- + +## Key Features + +### 📂 File Management + +Files are at the heart of Palmr. Users can upload files via the frontend, and they’re streamed directly to MinIO. The backend handles metadata (name, size, type, ownership), and also handles deletion, renaming, and public sharing. Every file operation is tracked, and all actions can be scoped per user. + +- Upload/download with instant feedback +- File previews, type validation, and size limits +- Token-based sharing system +- Disk usage tracking by user + +### 👤 User System + +Authentication is done through secure JWTs, stored in HTTP-only cookies for safety. Signup and login flows are simple and fast, and user info is kept in sync across the frontend and backend. + +- Cookie-based session management +- Role support and future admin access +- Profile updates and password reset flows +- Logged-in user state handled via custom hooks + +### 💾 Storage System + +MinIO is used for all file storage. It’s fast, lightweight, and fully S3-compatible which means it can scale easily and integrates with tons of other tools. The backend tracks usage, handles cleanup of orphaned files, and ensures that every file on disk has a matching database record. + +- S3-compatible object storage via MinIO +- Upload validation and automatic cleanup +- Usage tracking and quotas (per user or global) +- Secure access to stored files with signed URLs + +### 🌐 Internationalization + +Palmr. supports multiple languages using **next-intl**, which is deeply integrated into the routing system. It loads only the necessary translations per route, supports nested namespaces, and makes it easy to keep things organized even at scale. + +- Per-locale localstorage (`en-US`, `pt-BR`, etc.) +- Translation loading by namespace/page +- Full pluralization and formatting support +- Easy translation management via JSON files diff --git a/apps/docs/content/docs/2.0.0-beta/index.mdx b/apps/docs/content/docs/2.0.0-beta/index.mdx new file mode 100644 index 0000000..04f2f2a --- /dev/null +++ b/apps/docs/content/docs/2.0.0-beta/index.mdx @@ -0,0 +1,52 @@ +--- +title: 🌴 Welcome to Palmr. +--- + +![Palmr Banner](/assets/v2/general/banner.png) + +**Palmr.** is a powerful and **flexible open-source alternative** to popular file transfer services like **WeTransfer**, **SendGB**, **Send Anywhere** and **Files.fm**. The key advantage of Palmr. is that you can **host it on your own infrastructure**, such as a **dedicated server** or **VPS**, giving you full control over your files and data security without relying on third-party services or worrying about artificial limits or high fees. + +## **Why Choose Palmr.?** + +### 🚫 **No Artificial Limits** + +Unlike traditional file transfer services that impose arbitrary restrictions, Palmr. takes a fundamentally different approach by removing all artificial constraints on file sizes and quantities. The only practical limitation you'll encounter is the **available storage** space on your server or VPS infrastructure. This means that as long as you have adequate storage capacity in your hosting environment, you have complete freedom to transfer files of any size and in any quantity. There are no premium tiers to unlock additional features, no intrusive advertisements to navigate around, and absolutely no hidden charges or unexpected fees that might surprise you later. This unrestricted approach ensures that your file transfer capabilities are determined solely by your infrastructure choices rather than arbitrary service limitations. + +### 🌟 **Open Source and Free** + +Palmr. is completely **open source** and free to use, which means there are no licensing fees, subscription costs, or hidden charges associated with implementing and maintaining the software. This commitment to open source principles ensures complete transparency and freedom in how you utilize the platform. You can: + +- Deploy it on any infrastructure of your choice (VPS, dedicated server, Docker, cloud platforms, or other hosting environments), giving you complete flexibility in your hosting decisions. +- Review and audit the entire codebase to ensure security and integrity, allowing you to verify that the software meets your organization's security standards and compliance requirements. +- Contribute improvements or custom features to enhance the platform's functionality, participating in the collaborative development process that makes open source software so powerful. +- Adapt it for different use cases as needed, whether you're using it for personal file sharing, business operations, or specialized applications that require custom modifications. + +### 🔒 **Security and Privacy Under Your Control** + +When you host Palmr. on your infrastructure, you maintain **full control over your data** through end-to-end management of the storage and transfer process. By keeping files within your own hosting environment, you eliminate security vulnerabilities that could arise from third-party handling. Your files never get stored or processed by external services, ensuring complete **privacy** and **confidentiality** of transferred information. This allows you to implement security protocols and compliance measures that match your specific requirements. + +By eliminating third-party involvement, you gain peace of mind knowing that the files are never handled by external providers. This guarantees that you retain full control over data handling and processing, reinforcing the confidentiality of sensitive information throughout its lifecycle. + +With Palmr., your security and privacy are entirely in your hands, making it a powerful and reliable solution for organizations that require full control over their data, whether for internal use or for compliance with regulations. + +### 🎨 **Highly Customizable** + +Palmr. offers extensive customization options that allow you to tailor every aspect of the platform to perfectly align with your brand identity and create an optimal user experience that matches your specific requirements: + +- Add your own **logo** to maintain consistent branding across your file-sharing platform and establish a professional, unified presence. +- Set a **custom app name** that reflects your organization's identity and helps users instantly recognize your branded file-sharing solution. +- Configure an **SMTP server** for email notifications, enabling seamless communication with users about file transfers, updates, and system alerts. +- Customize text throughout the interface to create a unique user experience that resonates with your audience and maintains your brand voice. + +### 👥 **Complete User and Admin Management** + +Palmr. provides a comprehensive and sophisticated user and admin management system that puts you in complete control of your file-sharing environment: + +- Create and manage multiple **administrators** with different permission levels to ensure proper oversight and delegation of responsibilities. +- Add unlimited **users** to accommodate teams of any size, from small workgroups to large enterprises. +- Control who can view, upload, and manage files with granular permission settings that allow you to implement precise access controls. +- Easily monitor storage usage through detailed analytics and reporting tools that help you optimize resource allocation. + +### ⚡ **Fast, Lightweight, and Scalable** + +Palmr. demonstrates exceptional technical capabilities through its streamlined and expandable architecture, engineered to deliver optimal operational efficiency. The system effectively processes substantial file transfers and manages high-volume user activity while consistently maintaining superior transfer rates. The platform's contemporary infrastructure automatically adjusts to accommodate increased utilization, facilitating uninterrupted functionality as operational requirements expand. Through advanced resource allocation and refined programming, the system delivers a highly responsive user experience that accommodates organizational growth while maintaining consistent performance standards and operational stability. \ No newline at end of file diff --git a/apps/docs/content/docs/2.0.0-beta/installation.mdx b/apps/docs/content/docs/2.0.0-beta/installation.mdx new file mode 100644 index 0000000..85e6d56 --- /dev/null +++ b/apps/docs/content/docs/2.0.0-beta/installation.mdx @@ -0,0 +1,260 @@ +--- +title: 🐳 Installation (Docker Compose) +--- + + +Installation via Docker Compose is the simplest way to run the project across different environments. For it to run correctly, we need two main tools installed in our environment: + +- Docker ([https://docs.docker.com](https://docs.docker.com/)) +- Docker Compose ([https://docs.docker.com/compose](https://docs.docker.com/compose/)) + +> *It's worth emphasizing that Palmr. was fully developed in a MacOS environment and extensively tested on Linux servers. Therefore, we can guarantee the best system performance in these environments. Windows and other environments have not been tested yet, and potential bugs may occur during execution. However, remember that we are still in a beta version of Palmr., and errors or bugs can occur in any operating system. If you identify any issues, we appreciate your help in notifying us through our GitHub [issues page](https://github.com/kyantech/Palmr/issues).* + +--- + +## ⚡ Quick Start + +Having installed [Docker](https://docs.docker.com/) and [Docker Compose](https://docs.docker.com/compose/) in our environment, we can proceed with the simple installation using these tools. + +In the root folder of our project, we can find our `docker-compose.yaml` file, which is the only file needed to run the project via Docker and Docker Compose. This is because the pre-built images are already in our [DockerHub](https://hub.docker.com/repositories/kyantech) and are only referenced in the `docker-compose.yaml` + +Any changes needed for execution can be made directly in our `docker-compose.yaml` or via environment variables, which we will show later in this tutorial. + +Next, let's look at the content of our `docker-compose.yaml`. + +--- + +## 🐳 Docker Compose Content +Below is the complete content of our `docker-compose.yaml` that can be copied directly from here or from our official repository ([Docker Compose](https://github.com/kyantech/Palmr/blob/main/docker-compose.yaml)). + +```yaml +services: + palmr-api: + image: kyantech/palmr-api:v2.0.0-beta # Make sure to use the correct version (latest) of the image + container_name: palmr-api + depends_on: + postgres: + condition: "service_healthy" + minio: + condition: "service_healthy" + environment: + - PORT=${API_INTERNAL_PORT:-3333} # Port for the backend service + - DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD:-postgresRootPassword}@postgres:5432/palmr_db?schema=public # Database URL with configurable password through POSTGRES_PASSWORD env var + - MINIO_ENDPOINT=minio # This can change if your MinIO is at a different address + - MINIO_PORT=${MINIO_INTERNAL_API_PORT:-6421} # Default MinIO port (Change if yours is not the default) + - MINIO_USE_SSL=false # MinIO uses SSL by default, but you can change it to true if needed + - MINIO_ROOT_USER=${MINIO_ROOT_USER:-minio_root_user} # MinIO credentials can be configured through MINIO_ROOT_USER env vars + - MINIO_ROOT_PASSWORD=${MINIO_ROOT_PASSWORD:-minioRootPassword} # MinIO credentials can be configured through MINIO_ROOT_PASSWORD env vars + - MINIO_REGION=sa-east-1 # MinIO region - This is needed for MinIO to work properly + - MINIO_BUCKET_NAME=files # MinIO bucket name - This is needed for MinIO to work properly, dont change it if you don't know what you are doing + - FRONTEND_URL=${APP_URL:-http://${SERVER_IP:-localhost}:${APP_EXTERNAL_PORT:-5487}} # Frontend URL - Make sure to use the correct frontend URL, depends on where the frontend is running, its prepared for localhost, but you can change it to your frontend URL if needed + - SERVER_IP=${SERVER_IP:-localhost} # Server IP - Make sure to use the correct server IP if you running on a cloud provider or a virtual machine. This prepared for localhost, but you can change it to your server IP if needed + ports: + - "${API_EXTERNAL_PORT:-3333}:${API_INTERNAL_PORT:-3333}" # Backend port mapping + restart: unless-stopped + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:${API_INTERNAL_PORT:-3333}/health"] + interval: 10s + timeout: 5s + retries: 5 + start_period: 30s + + palmr-app: + image: kyantech/palmr-app:v2.0.0-beta # Make sure to use the correct version (latest) of the image + container_name: palmr-web + depends_on: + palmr-api: + condition: "service_healthy" + ports: + - "${APP_EXTERNAL_PORT:-5487}:5487" # Frontend port mapping + environment: + - NODE_ENV=production + - NEXT_TELEMETRY_DISABLED=1 + - API_BASE_URL=http://palmr-api:${API_INTERNAL_PORT:-3333} # Here we use docker's internal network to reference the backend service (can be changed if needed) + restart: unless-stopped + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:5487"] + interval: 30s + timeout: 10s + retries: 3 + + minio: + image: minio/minio:RELEASE.2025-03-12T18-04-18Z # Use only version RELEASE.2025-03-12T18-04-18Z to avoid compatibility issues with the backend + container_name: minio + environment: + # MinIO credentials - same as above, configurable through environment variables + - MINIO_ROOT_USER=${MINIO_ROOT_USER:-minio_root_user} + - MINIO_ROOT_PASSWORD=${MINIO_ROOT_PASSWORD:-minioRootPassword} + - MINIO_SITE_REGION=sa-east-1 + command: server /data --address ":${MINIO_INTERNAL_API_PORT:-6421}" --console-address ":${MINIO_INTERNAL_CONSOLE_PORT:-6422}" + volumes: + - minio_data:/data + ports: + - "${MINIO_EXTERNAL_API_PORT:-6421}:${MINIO_INTERNAL_API_PORT:-6421}" + - "${MINIO_EXTERNAL_CONSOLE_PORT:-6422}:${MINIO_INTERNAL_CONSOLE_PORT:-6422}" + restart: unless-stopped + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:${MINIO_INTERNAL_API_PORT:-6421}/minio/health/ready"] + interval: 10s + timeout: 5s + retries: 5 + + minio-init: + image: minio/mc:RELEASE.2025-03-12T17-29-24Z # Use only version RELEASE.2025-03-12T17-29-24Z to avoid compatibility issues with the backend and MinIO + container_name: minio-init + depends_on: + minio: + condition: "service_healthy" + restart: "no" + # The entrypoint script will create a bucket called "files" and set it to be publicly readable using the MinIO client (mc). + entrypoint: > + sh -c " + sleep 5 && + mc alias set myminio http://minio:${MINIO_INTERNAL_API_PORT:-6421} ${MINIO_ROOT_USER:-minio_root_user} ${MINIO_ROOT_PASSWORD:-minioRootPassword} && + mc mb myminio/files --ignore-existing && + mc anonymous set download myminio/files + " + + postgres: + image: bitnami/postgresql:17.2.0 # You can use any postgres version you prefer, but remember that some versions might not be compatible + container_name: palmr-postgres + environment: + # PostgreSQL credentials configurable through environment variables + # POSTGRES_USER, POSTGRES_PASSWORD, and POSTGRES_DB can be set to override defaults + - POSTGRESQL_USERNAME=${POSTGRES_USER:-postgres} + - POSTGRESQL_PASSWORD=${POSTGRES_PASSWORD:-postgresRootPassword} + - POSTGRESQL_DATABASE=${POSTGRES_DB:-palmr_db} + volumes: + - postgres_data:/bitnami/postgresql + ports: + - "5432:5432" + restart: unless-stopped + healthcheck: + test: ["CMD", "pg_isready", "-U", "palmr"] + interval: 10s + timeout: 5s + retries: 5 + +volumes: + minio_data: + postgres_data: + +``` + +Notice that the `docker-compose.yaml` has several comments that help you configure your own compose to meet your environment's needs. Let's give an overview of some changes we can make. + +--- + +### ⚙️ Services Overview + +Palmr. consists of five main services, each with specific responsibilities. Below, we present a detailed view of each component: + +| **Service** | **Image** | **Exposed Ports** | **Main Features** | +| --- | --- | --- | --- | +| palmr-api (Backend) | [kyantech/palmr-api:latest](https://hub.docker.com/repository/docker/kyantech/palmr-api/tags/latest/sha256-84245d3d0012aa65c588caba56322363729c4b68c3722a08dcda912904de9d1d) | **3333** | • Main API service
• Depends on services: postgres and minio
• Has healthcheck to ensure availability | +| palmr-app (Frontend) | [kyantech/palmr-app:latest](https://hub.docker.com/repository/docker/kyantech/palmr-app/tags/latest/sha256-33f568673ae8cc8529532146b6afc1acafa203387ced6c7bb3451a7ab4198a2f) | **5487** | • Web application interface
• Depends on palmr-api service
• Configured for production environment | +| minio (Storage) | [minio/minio:RELEASE.2025-03-12T18-04-18Z](https://hub.docker.com/layers/minio/minio/RELEASE.2025-03-12T18-04-18Z/images/sha256-85f3e4cd1ca92a2711553ab79f222bcd8b75aa2c77a1a0b0ccf80d38e8ab2fe5) | **6421**(API)
**6422**(Console) | • File storage service
• Persistent volume for data | +| minio-init (Config) | [minio/mc:RELEASE.2025-03-12T17-29-24Z](https://hub.docker.com/layers/minio/mc/RELEASE.2025-03-12T17-29-24Z/images/sha256-68d8c80f43908b02daa285e55547131870a1d36b3ffe272c26d7d8f4d52d1e5c) | N/A | • Initially configures the "files" bucket
• Runs only once during initialization | +| postgres (Database) | [bitnami/postgresql:17.2.0](https://hub.docker.com/layers/bitnami/postgresql/17.2.0/images/sha256-29c614afad4f514b12b5c0f4d006f38c98fa4b18c3582732ff93b3fe9a79d875) | **5432** | • PostgreSQL database
• Persistent volume for data | + +--- + +### 🛠️ Available Environment Variables + +The table below shows all environment variables that can be set + +| **Variable** | **Default Value** | **Description** | +| --- | --- | --- | +| API_INTERNAL_PORT | 3333 | Internal API port in container | +| API_EXTERNAL_PORT | 3333 | Exposed port on host for API | +| POSTGRES_PASSWORD | postgresRootPassword | PostgreSQL database password | +| APP_EXTERNAL_PORT | 5487 | Exposed port on host for frontend | +| APP_URL | http://localhost:5487 | Complete frontend URL | +| SERVER_IP | localhost | IP of the server where the application is running | +| MINIO_ROOT_USER | minio_root_user | MinIO admin user | +| MINIO_ROOT_PASSWORD | minioRootPassword | MinIO admin password | +| MINIO_INTERNAL_API_PORT | 6421 | Internal MinIO API port | +| MINIO_INTERNAL_CONSOLE_PORT | 6422 | Internal MinIO console port | +| MINIO_EXTERNAL_API_PORT | 6421 | Exposed port on host for MinIO API | +| MINIO_EXTERNAL_CONSOLE_PORT | 6422 | Exposed port on host for MinIO console | +| POSTGRESQL_USERNAME | postgres | PostgreSQL user | +| POSTGRESQL_DATABASE | palmr_db | Database name | + +> *All these variables can be configured through a .env file in the project root or defined directly in the environment where docker-compose will be executed. The best way to do this is up to you. But be careful to replace correctly if doing directly in the compose instead of providing an environment var.* +> + + +#### 🗂️ Persistent Volumes + +- minio_data: Stores MinIO files +- postgres_data: Stores PostgreSQL data + +--- + +### 💻 Local Execution + +In a localhost environment, there's no mystery. If you don't want to change any service exposure ports, you can simply run: + +This will execute all necessary services and give you access to the following URLs (if you haven't changed any ports): + +- **Frontend:** [http://localhost:5487](http://localhost:5487) +- **Backend:** [http://localhost:3333](http://localhost:3333/) +- **MinIO API:** [http://localhost:6421](http://localhost:6421) +- **MinIO Console:** [http://localhost:6422](http://localhost:6422) +- **Postgres Database:** [http://localhost:5423](http://localhost:5423/) (Connection only) + +> *If you have changed any port, simply access the URL with the port you configured.* +> + +--- + +### 🌐 Production (VPS or other) + +For production environments, whether it's your VPS, Homelab Server, or other, the execution is very similar to the localhost environment, except for some particularities that may occur in some cases. + +We mainly need to pay attention to the following points: + +- Correctly set the `SERVER_IP` env var with our server's IP, otherwise some redirects and queries will fail during App execution. +- Set the `APP_URL` - regardless of whether the frontend is on the same server and with the same IP, it's extremely important to set this environment variable, otherwise sharing links will be generated incorrectly. +- For all environment variables that are `PASSWORD`, it's highly recommended to generate secure passwords and replace them as env vars. +- Lastly, make sure no docker service will conflict with any existing ones in your environment. If there is a conflict, simply change the execution ports via environment var or in the docker compose. + +To generate a .env file with just the `server_ip` configuration, you can run this command: + +```bash +curl -fsSL https://gist.githubusercontent.com/danielalves96/5a68913d70e5e31b68b7331dc17dfa9c/raw | bash +``` +> execute this command in your server terminal, at same path of docker-compose.yaml. + +Basically, by paying attention to these points, you can quickly execute the project with the same command we used for localhost: + +```bash +docker compose up -d +``` + +At this stage, if you encounter any errors, it's worth reviewing your `docker-compose.yaml` and trying again, paying close attention to the points mentioned above. + +> *First test without using reverse proxies like Caddy, Traefik, etc... if you plan to use them. Access the services via `server_ip:port` after confirming they work, then make the necessary routing configurations as desired.* +> + +If you haven't changed the execution ports, you'll have access on your server at: + +- **Frontend:** `[server_ip]:5487` +- **Backend:** `[server_ip]:3333` +- **MinIO API:** `[server_ip]:6421` +- **MinIO Console:** `[server_ip]:6422` +- **Postgres Database:** `[server_ip]:5423` (Connection only) + +> *If you've changed any port, simply access the URL with the port you configured.* +> + +It's worth noting that this is just a quick start and we're not going into details about any of the developed services, but it's recommended for execution in any environment. However, if your focus is on using Palmr. with high availability in mind, it's recommended to use a container orchestrator prepared for this, such as Kubernetes or similar, but we don't cover this type of configuration in our documentation. + +--- + +## 📚 Additional Resources + +- [Docker Documentation](https://docs.docker.com/) +- [Docker Compose Documentation](https://docs.docker.com/compose/) +- [MinIO Documentation](https://min.io/docs/minio/container/index.html) +- [PostgreSQL Documentation](https://www.postgresql.org/docs/) diff --git a/apps/docs/content/docs/2.0.0-beta/manage-users.mdx b/apps/docs/content/docs/2.0.0-beta/manage-users.mdx new file mode 100644 index 0000000..9f8496b --- /dev/null +++ b/apps/docs/content/docs/2.0.0-beta/manage-users.mdx @@ -0,0 +1,81 @@ +--- +title: 👥 Users Management +--- + +Managing users in **Palmr.** is a straightforward and intuitive process that ensures proper access control and organization within your system. This comprehensive step-by-step guide will walk you through the essential processes of creating, modifying, and managing user accounts within the application. + +## 🔐 Accessing User Management + +To initiate the user management process, you'll need to navigate to the dedicated **User Management** section. This centralized hub provides all the tools necessary for effective user administration: + +1. Locate and click on the **user icon** prominently displayed in the application's header area, where all primary navigation controls are situated. +2. Upon clicking, a comprehensive dropdown menu will appear, presenting various options. From these choices, locate and select **"User Management"** to proceed + +![Menu](/assets/v1/ui/menu.png) + +--- + +### 📊 User Management Dashboard + +Upon selecting **User Management**, the system will automatically direct you to the comprehensive **User Management Dashboard**, your central control panel for all user-related operations. + +- During your initial access to the system, you'll notice that the user list contains only the **default Admin** user account, which serves as the primary administrative account. +- Should you find it necessary to modify the Admin user's information or credentials, please note that these changes must be implemented through the dedicated **Profile Management** section, which provides specialized tools for administrator profile maintenance. +- For security purposes and to maintain system integrity, it's important to understand that the currently logged-in Admin user's details cannot be altered directly from within the **User Management Dashboard**. + +![Users Management Page](/assets/v1/main/users/users-management.png) + +--- + +### 👤 Adding a New User + +1. To initiate the process of adding a new user to the system, locate and click the **"Add User"** button, which is conveniently positioned in the top right corner of your screen for easy access. + +![Add Users Button](/assets/v1/main/users/add-users-btn.png) + +1. Upon clicking, an interactive modal form will be displayed, presenting you with all the necessary fields to input the new user's comprehensive details and access permissions: + +![Add Users Modal](/assets/v1/main/users/add-user-modal.png) + +1. After carefully entering all the required user information and reviewing for accuracy, click the **"Create"** button to finalize the process. ✨ If you need to start over or decide not to proceed, simply click the **"Cancel"** button to terminate the user creation process without saving any changes. +2. Following successful user creation, the new account will be immediately visible in the user list, confirming the completion of the process. 🎉 + +![New Users Table](/assets/v1/main/users/new-user-table.png) + +--- + +### ⚙️ Managing User Actions + +Within the **User List** interface, you'll find a comprehensive **"Actions"** column containing a dropdown menu for each user account, providing access to all available management functions. + +![Add User Actions Dropdown](/assets/v1/main/users/add-user-actions-dropdown.png) + +The following administrative actions are available for your convenience: + +- 📝 **Edit User** – Provides access to a detailed modal form for comprehensive user information updates: +- Modify various user details including their assigned role and permissions within the system. +- Implement security measures such as password changes and access control modifications. + +![Edit User Modal](/assets/v1/main/users/edit-user-modal.png) + +- 🔒 **Deactivate User** – Temporarily suspends user access by marking the account as inactive, effectively preventing any system login attempts while maintaining their account information. +- 🔓 **Activate User** – Restores full system access for previously deactivated users, enabling them to resume normal account activities and authentication. +- ❌ **Delete User** – Executes a permanent removal of the user account from the system, including all associated data and permissions. + +--- + +## ⚠️ Troubleshooting + +In the event of any challenges or issues during the user management process, please refer to the following troubleshooting guidelines: + +### 🚫 User Creation Fails + +- Carefully verify that all required fields (including name, email address, and role assignments) have been completed with accurate information. +- Perform a thorough check to ensure the email address isn't already associated with an existing account in the system. +- Confirm that your system maintains a stable and active connection to the backend services necessary for user management. + +### 🔑 User Cannot Log In + +- First, verify that the user's account status is set to **Active** in the system. +- Double-check that the user is attempting to authenticate with their correct email address and current password combination. +- If authentication issues persist, initiate a password reset procedure to establish new credentials. diff --git a/apps/docs/content/docs/2.0.0-beta/manual-installation.mdx b/apps/docs/content/docs/2.0.0-beta/manual-installation.mdx new file mode 100644 index 0000000..f8d81d8 --- /dev/null +++ b/apps/docs/content/docs/2.0.0-beta/manual-installation.mdx @@ -0,0 +1,212 @@ +--- +title: 📦 Manual Installation +--- + +Manual installation requires more detailed attention and hands-on configuration compared to the streamlined process offered by Docker Compose. While this approach demands additional effort and technical understanding, following our comprehensive step-by-step guide will ensure a clean and successful project execution with full control over each component. + +An important consideration in this manual setup process is that while we'll be handling the frontend and backend deployments directly, we still require Docker or an equivalent third-party service to manage our Postgres database and MinIO object storage infrastructure. For the purposes of this tutorial, we've chosen to utilize Docker with Docker Compose to establish and configure both MinIO and Postgres, as this provides a reliable and well-tested environment. + +To facilitate this setup, we've included a pre-configured Docker Compose file within the `apps/server` directory that handles the initialization and configuration of both MinIO and Postgres - two essential components for the application's core functionality. While this is our recommended approach, you maintain the flexibility to implement alternative solutions that better suit your specific needs or infrastructure requirements. Our decision to leverage Docker Compose for these particular services stems from its ability to significantly streamline the configuration process, especially when dealing with complex third-party services like Postgres and MinIO. + +Should you be interested in exploring alternative deployment methods for hosting MinIO and Postgres without utilizing Docker and Docker Compose, comprehensive information is available through their respective official channels and documentation: + +- MinIO GitHub: [Visit MinIO GitHub](https://github.com/minio/minio) +- Postgres Github: [Visit Postgres GitHub](https://github.com/postgres/postgres) +- MinIO documentation: [View MinIO docs](https://min.io/docs/minio/linux/index.html) +- Postgres documentation: [View Postgres docs](https://www.postgresql.org/docs/) + +With these foundational concepts established, we can now proceed with our detailed, step-by-step installation guide. + +--- + +## ✅ Prerequisites + +Before proceeding with the installation, it's essential to ensure that your development environment is properly configured with all the necessary tools and dependencies. Please verify that you have the following software components installed and properly configured on your system: + +- Docker *(Required only if you plan to use Docker + Docker Compose)* +- Docker Compose *(Required only if you plan to use Docker + Docker Compose)* +- Node.js *(Essential for running JavaScript/TypeScript applications)* +- pnpm *(Our preferred package manager)* +- Git *(For version control and repository management)* + +⚠️ A critical note regarding package management: This repository has been specifically developed and thoroughly tested using the pnpm package manager. While technically possible to use alternative package managers such as `npm`, `yarn`, or `bun`, we strongly advise against this approach. + + +--- + +## Running the Application + +### 📥 Clone the Repository + +To begin the installation process, you'll need to obtain a local copy of the codebase. Start by cloning the official repository using the following Git command: + +```bash +git clone https://github.com/kyantech/Palmr.git +``` + +Upon successful cloning, you'll find yourself with a new directory containing the project structure. Within this directory, there's a crucial folder named 'apps' that houses three essential components: docs, server, and web. For the purposes of this installation guide, we'll focus primarily on the server and web directories, which contain our robust backend infrastructure (built with Fastify) and our responsive frontend application (developed using React + Vite), respectively. + +--- + +### ⚙️ Set Up Backend Services + +The next phase involves setting up our backend services. First, navigate to the backend directory where you'll find the Docker Compose configuration file for our essential services - MinIO and Postgres: + +```bash +cd ./apps/server +``` + +Once you're in the correct directory, initiate the services by executing the following command: + +```bash +docker compose up -d +``` + +This command initializes both Postgres and MinIO services in detached mode, allowing them to run seamlessly in the background. While the configuration file at `apps/server/docker-compose.yaml` can be customized to suit specific needs, we strongly recommend maintaining the default configuration for your initial setup. This approach ensures a smooth installation process, and you can always refine the settings once you have a working implementation. + +Now that our essential services are operational through Docker Compose, we can proceed with the core backend setup. During this phase, we'll be preparing the application for production deployment rather than development mode. This process requires careful attention to both the backend and frontend components. + +Since our current working directory is already set to the server folder, let's begin with the backend configuration. + +#### 🔑 Set Up Environment Variables + +A crucial preliminary step is configuring the environment variables that Palmr requires for proper operation. We've provided a template file named `.env.example` in the repository to streamline this process. + +Execute this straightforward command to create your environment configuration: + +```bash +cp .env.example .env +``` + +This operation creates a new `.env` file in the root directory, populated with all the necessary environmental configurations. + +#### 📦 Install Dependencies + +The next crucial step involves initializing our database connection through Prisma, our chosen Object-Relational Mapping (ORM) tool. However, before we can utilize Prisma effectively, we need to ensure all backend dependencies are properly installed. With your Node.js environment and pnpm package manager ready, execute: + +```bash +pnpm install +``` + +#### ⚡ Generate Prisma Client + +After successfully installing all dependencies, proceed with generating the Prisma client by running: + +```bash +pnpm dlx prisma generate +``` + +This essential command generates the Prisma client specifically tailored for our project, establishing the necessary interface for seamless database interactions and operations. + +#### 🔄 Deploy Prisma Migrations + +With the client generation complete, deploy the database schema using: + +```bash +pnpm dlx prisma migrate deploy +``` + +This command ensures all your database migrations are properly implemented, establishing the required database structure. + +#### 🌱 Seed the Database + +Following the successful migration deployment, we'll populate the database with initial data using our seeding script. Execute: + +```bash +pnpm db:seed +``` + +This process will populate your database with the necessary initial data, preparing it for application use. + +#### 🏗️ Build and Run the Backend + +With all preparatory steps completed, we can now build the backend application: + +```bash +pnpm run build +``` + +Once the build process successfully concludes, start the backend service: + +```bash +pnpm start +``` + +To verify that your backend is functioning correctly, you can access the comprehensive API documentation at: + +```bash +http://localhost:3333/docs +``` + +This documentation interface provides detailed information about all available API endpoints and their usage. + +--- + +### 🎨 Set Up Frontend + +The frontend configuration process follows a similar pattern to the backend setup, though it's somewhat simplified as it doesn't require Docker container management - we'll only need to configure and run the service itself. + +#### 📂 Navigate to the Frontend Directory + +If your current location is the server directory, use: + +```bash +cd ../web +``` + +Alternatively, if you're starting from the repository root, navigate with: + +```bash +cd apps/web +``` + +#### ⚙️ Set Up Environment Variables + +After reaching the web directory, begin by creating your frontend environment configuration: + +```bash +cp .env.example .env +``` + +This step mirrors our backend environment setup, ensuring all necessary variables are properly configured. + +#### 📦 Install Dependencies + +Proceed with installing all required frontend dependencies: + +```bash +pnpm install +``` + +#### 💻 Build and Run the Frontend + +The final stage of our frontend setup is straightforward. First, create a production build: + +```bash +pnpm run build +``` + +After the build completes successfully, launch the frontend service: + +```bash +pnpm serve +``` + +Once the service initialization is complete, you can access the full application through your web browser at: + +```bash +http://localhost:3000 +``` + +--- + +## 🎉 Conclusion + +Congratulations! You've successfully completed the comprehensive setup process for deploying a production-ready instance of Palmr. This detailed guide has walked you through each crucial step, from initial repository cloning to final application deployment. + +## 🔗 Useful Links + +- [Docker Documentation](https://docs.docker.com/) +- [Node.js Documentation](https://nodejs.org/en/docs/) +- [pnpm Documentation](https://pnpm.io/) +- [Prisma Documentation](https://www.prisma.io/docs/) \ No newline at end of file diff --git a/apps/docs/content/docs/2.0.0-beta/meta.json b/apps/docs/content/docs/2.0.0-beta/meta.json new file mode 100644 index 0000000..2841360 --- /dev/null +++ b/apps/docs/content/docs/2.0.0-beta/meta.json @@ -0,0 +1,29 @@ +{ + "title": "v2.0.0-beta", + "description": "v2.0.0-beta Documentation", + "root": true, + "icon": "Building2", + "pages": [ + "---Introduction---", + "index", + "architecture", + "github-architecture", + "installation", + "manual-installation", + "api", + "---How to use Palmr.---", + "first-login", + "manage-users", + "uploading-files", + "generate-share", + "configuring-smtp", + "available-languages", + "---Developers---", + "contribute", + "open-an-issue", + "---Sponsor this project---", + "gh-star", + "gh-sponsor", + "..." + ] +} diff --git a/apps/docs/content/docs/2.0.0-beta/open-an-issue.mdx b/apps/docs/content/docs/2.0.0-beta/open-an-issue.mdx new file mode 100644 index 0000000..3ca184b --- /dev/null +++ b/apps/docs/content/docs/2.0.0-beta/open-an-issue.mdx @@ -0,0 +1,137 @@ +--- +title: 🎫 How to open an issue +--- + +## 👋 Introduction + +Opening an issue on GitHub is a great way to report bugs, request features, or ask questions about a project. This tutorial will guide you through the process of opening an issue for the **Palmr.** project on GitHub. + +Issues are an essential communication tool in open source development that help track bugs, feature requests, and general questions. They create a transparent record of project discussions and improvements. Whether you've found a bug that needs fixing, have an idea for a new feature, or just need clarification about how something works, creating an issue is the first step to getting your voice heard. + +--- + +### 🔑 GitHub Login + +Before you can open an issue, you need to be logged into your GitHub account. If you don't have an account yet, you can sign up for free at [GitHub](https://github.com/). Having a GitHub account allows you to: + +- Create and manage issues +- Comment on existing issues +- Receive notifications about updates +- Collaborate with other developers + +Once you have an account, make sure you're logged in before proceeding to the next steps. + +--- + +### 🔍 Access the Repository + +There are several ways to access the Palmr repository: + +1. **Direct Link**: + Go to the Palmr repository by clicking this link: [https://github.com/kyantech/Palmr](https://github.com/kyantech/Palmr) + +2. **GitHub Search**: + - Click the search bar at the top of GitHub + - Type "Palmr" or "kyantech/Palmr" + - Look for the repository owned by **Kyantech** + - Click on the repository name to access it + +3. **Through Organization**: + - Visit [Kyantech's GitHub profile](https://github.com/kyantech) + - Navigate to the "Repositories" tab + - Find and click on "Palmr" in the repository list + +--- + +### 📋 Open the Issues Tab + +To access the issues section: + +1. Look at the navigation bar near the top of the repository page +2. Find the **Issues** tab - it's usually between "Code" and "Pull requests" +3. Click on the **Issues** tab to open the issues section +4. You'll see a list of all existing issues, both open and closed + +The issues tab shows important information like: +- Number of open issues +- Issue labels and categories +- Issue status (open/closed) +- Recent activity +- Assigned contributors + +![Palmr Profile Menu](/assets/v1/developers/issues-tab.png) + +--- + +### ➕ Create New Issue + +To start creating a new issue: + +1. Look for the green **New Issue** button on the right side of the issues page +2. Click the button to open the issue creation form +3. If there are multiple issue templates available, choose the most appropriate one for your needs +4. Take time to read through the template requirements carefully +5. Make sure you have all necessary information ready before starting + +Pro Tips: +- Before creating a new issue, search existing issues to avoid duplicates +- Review any contribution guidelines or issue templates +- Consider adding relevant labels when creating your issue +- Include system information if reporting a bug +- Reference related issues or pull requests if applicable +- Use markdown formatting to make your issue more readable + +![Palmr Profile Menu](/assets/v1/developers/new-issue-btn.png) + +--- + +### 📝 Fill Out the Form + +You’ll now see a form where you can provide details about your issue. Here’s how to fill it out: + +1. **Title**: Write a clear and concise title that summarizes the issue. +2. **Description**: Provide a detailed description of the issue. Include steps to reproduce the problem (if it’s a bug), expected behavior, and actual behavior. If you’re requesting a feature, explain why it would be useful. +3. **Labels (Optional)**: Add labels to categorize your issue (e.g., `bug`, `enhancement`, `question`). This helps the maintainers organize and prioritize issues. +4. **Attachments (Optional)**: You can attach screenshots, logs, or other files to help explain the issue. + +![Palmr Profile Menu](/assets/v1/developers/new-issue-form.png) + +--- + +### ✅ Submit the Issue + +Once you've filled out the form, click the **Create** button at the bottom of the page. Your issue will now be visible to the project maintainers and other contributors. You can track the status of your issue and receive notifications when there are updates or responses. Feel free to participate in any follow-up discussions in the comments section of your issue. + +--- + +### 💡 Tips for Issues + +To ensure your issue is addressed quickly and effectively, follow these tips: +- **Be Clear and Specific**: Provide as much detail as possible. +- **Use a Descriptive Title**: A good title helps maintainers understand the issue at a glance. +- **Include Steps to Reproduce**: If it’s a bug, explain how to reproduce it. +- **Be Polite and Respectful**: Remember that maintainers and contributors are volunteering their time. + +--- + +### ⭐ Why Issues Matter + +Opening issues is a key part of contributing to open-source projects. Here’s why it matters: +1. **Improves the Project**: Your feedback helps identify bugs and suggest new features. +2. **Helps Maintainers**: Clear and detailed issues make it easier for maintainers to address problems. +3. **Encourages Collaboration**: Issues can spark discussions and attract contributors to help solve problems. + +--- + +### 🎉 Final Words + +Congratulations on creating your first issue for the **Palmr** project! Your contribution is valuable and helps make the project better for everyone. Remember: + +- Stay engaged with your issue's progress +- Help others when you can +- Share your knowledge and experiences +- Consider contributing code if possible +- Star the repository to show support +- Spread the word about Palmr + +Thank you for being part of our open-source community. Your participation helps make Palmr better for everyone! diff --git a/apps/docs/content/docs/2.0.0-beta/uploading-files.mdx b/apps/docs/content/docs/2.0.0-beta/uploading-files.mdx new file mode 100644 index 0000000..d6c89fa --- /dev/null +++ b/apps/docs/content/docs/2.0.0-beta/uploading-files.mdx @@ -0,0 +1,91 @@ +--- +title: 📤 Uploading Files +--- + +To upload a file in Palmr, the process has been designed to be straightforward and user-friendly. The platform offers two convenient locations where users can upload their files, ensuring flexibility and ease of access. Each location has been optimized to provide a seamless upload experience. + +Before we delve into the specifics of file uploading, it's essential to understand that file sharing stands at the heart of Palmr's functionality. This core feature enables users to collaborate and distribute content efficiently. To initiate this collaborative process, you'll need to first upload one or more files to your account. Once your files are uploaded, you can proceed to create a sharing session, which serves as a container that can encompass either a single file or multiple files, depending on your specific needs. + +Now let's explore the file upload process in detail. As previously mentioned, the procedure has been streamlined for maximum efficiency, and you can initiate file uploads from two distinct locations: **the Home Page** or **the My Files Page**. We will thoroughly examine both options in the following sections, though it's worth noting that the underlying upload mechanism remains consistent regardless of which location you choose. + +--- + +## 🏠 Home Page + +On the home page, you'll find a dedicated "Recent Uploads" section. When you're using Palmr for the first time and haven't uploaded any files yet, this section will appear in its initial state: + +![Recent Uploads Section](/assets/v1/main/upload/recent-uploads.png) + +To begin the upload process, locate and click the "Upload File" button. This action will trigger a modal window where you can browse and select the desired file from your device. For enhanced user experience, certain file formats including images, audio files, and video content will automatically generate a preview within the modal. + +![Upload File Button](/assets/v1/main/upload/upload-file-button.png) + + +**Example with an image:** + +![Preview Example](/assets/v1/main/upload/preview-example.png) + +Upon selecting your file, you'll be presented with two options: confirm the upload by clicking the "Upload" button, or if you need to make changes, you can abort the process by selecting the "Cancel" button. + +![Upload and Cancel Buttons](/assets/v1/main/upload/upload-cancel-buttons.png) + +After successfully uploading one or more files, the "Recent Uploads" section will automatically refresh to display your newly added content: + +![Recent Uploads with Files](/assets/v1/main/upload/recent-uploads-filled.png) + +Should you wish to upload additional files from this view, simply click the "Upload File" button positioned in the upper right corner of the section, then follow the same straightforward procedure outlined above. + +![New Upload Button](/assets/v1/main/upload/new-upload-button.png) + +It's important to note that the home page list displays only your last 5 uploads for quick access. For a comprehensive view of your uploaded files or to upload additional content, you'll need to navigate to the "My Files" page. This can be accomplished in two ways: either click the "View All" button located in the upper right corner of the section, or select the "My Files" card directly from the home page. + +![View All Button](/assets/v1/main/upload/view-all-button.png) + +Or: + +![My Files Card](/assets/v1/main/files/my-files-card.png) + +--- + +## 📂 My Files Page + +Upon accessing the **"My Files"** page, you'll be presented with this comprehensive layout: + +This interface provides enhanced functionality, allowing you to **filter** through your uploaded files for better organization. You can also continue uploading new files by clicking the **"Upload File"** button and following the previously described upload procedure. + +For clarity, it's worth mentioning that the tables found in both the **"Recent Files"** section and the **"My Files"** page share the same structure and organization — the primary distinction lies in the quantity of files displayed. While the **"Recent Files"** section provides quick access to your five most recent uploads, the **"My Files"** table presents a comprehensive view of your entire upload history. + +The table provides detailed information through the following fields: + +- **Name** +- **Description** +- **Size** +- **Created At** +- **Updated At** +- **Actions** + +--- + +### ⚙️ Actions Column + +Within the **"Actions"** column, you'll discover an interactive icon that reveals the following dropdown menu: + +![Actions Dropdown](/assets/v1/main/files/actions-dropdown.png) + +While most options are self-explanatory, let's examine the Edit functionality in detail: + +- Edit – Opens a modal where you can modify various file attributes including the file name, description, and other relevant details. + + ![Edit Modal](/assets/v1/main/files/edit-modal.png) + +- The platform also provides the ability to **delete** files directly through the dropdown menu by selecting the **Delete** option. + +For enhanced user experience, the preview functionality is available for common media formats including images, audio files, PDFs, and videos. For all other file types, you can easily access the content through the **Download** option in the dropdown menu. + +--- + +## 📝 Notes and Recommendations + +- To ensure optimal performance and user experience, we strongly recommend uploading files that have been properly optimized. +- For troubleshooting purposes, all upload errors and related issues are systematically logged and can be accessed through the administrative panel. +- System administrators have full control over file access permissions and can manage them as needed. diff --git a/apps/docs/content/docs/meta.json b/apps/docs/content/docs/meta.json new file mode 100644 index 0000000..ed656a4 --- /dev/null +++ b/apps/docs/content/docs/meta.json @@ -0,0 +1,3 @@ +{ + "pages": ["2.0.0-beta", "1.1.7-beta"] +} \ No newline at end of file diff --git a/apps/docs/next.config.mjs b/apps/docs/next.config.mjs new file mode 100644 index 0000000..99eddcc --- /dev/null +++ b/apps/docs/next.config.mjs @@ -0,0 +1,29 @@ +import { createMDX } from 'fumadocs-mdx/next'; + +const withMDX = createMDX(); + +/** @type {import('next').NextConfig} */ +const config = { + reactStrictMode: true, + eslint: { + ignoreDuringBuilds: true, + }, + typescript: { + ignoreBuildErrors: true, + }, + images: { + qualities: [100], + remotePatterns: [ + { + protocol: 'https', + hostname: '**' + }, + { + protocol: 'http', + hostname: '**' + } + ] + } +}; + +export default withMDX(config); diff --git a/apps/docs/package.json b/apps/docs/package.json index dc4e6db..8e13db2 100644 --- a/apps/docs/package.json +++ b/apps/docs/package.json @@ -1,17 +1,37 @@ { - "name": "palmr-docs", - "type": "module", - "version": "0.0.1", + "name": "docs-v2", + "version": "0.0.0", + "private": true, "scripts": { - "dev": "astro dev", - "start": "astro preview", - "build": "astro build && cp -r public dist/", - "preview": "astro preview", - "astro": "astro" + "build": "next build", + "dev": "next dev --turbo", + "start": "next start", + "postinstall": "fumadocs-mdx" }, "dependencies": { - "@astrojs/starlight": "^0.32.2", - "astro": "^5.1.5", - "sharp": "^0.32.5" + "class-variance-authority": "^0.7.1", + "clsx": "^2.1.1", + "fumadocs-core": "15.2.7", + "fumadocs-mdx": "11.6.0", + "fumadocs-ui": "15.2.7", + "lucide-react": "^0.488.0", + "motion": "^12.9.1", + "next": "15.3.0", + "react": "^19.1.0", + "react-dom": "^19.1.0", + "tailwind-merge": "^3.2.0" + }, + "devDependencies": { + "@tailwindcss/postcss": "^4.1.3", + "@types/mdx": "^2.0.13", + "@types/node": "22.14.0", + "@types/react": "^19.1.0", + "@types/react-dom": "^19.1.2", + "eslint": "^8", + "eslint-config-next": "15.3.0", + "postcss": "^8.5.3", + "tailwindcss": "^4.1.3", + "tw-animate-css": "^1.2.8", + "typescript": "^5.8.3" } } \ No newline at end of file diff --git a/apps/docs/pnpm-lock.yaml b/apps/docs/pnpm-lock.yaml index 91d96ca..8817796 100644 --- a/apps/docs/pnpm-lock.yaml +++ b/apps/docs/pnpm-lock.yaml @@ -8,511 +8,957 @@ importers: .: dependencies: - '@astrojs/starlight': - specifier: ^0.32.2 - version: 0.32.2(astro@5.5.2(rollup@4.35.0)(typescript@5.8.2)) - astro: - specifier: ^5.1.5 - version: 5.5.2(rollup@4.35.0)(typescript@5.8.2) - sharp: - specifier: ^0.32.5 - version: 0.32.6 + class-variance-authority: + specifier: ^0.7.1 + version: 0.7.1 + clsx: + specifier: ^2.1.1 + version: 2.1.1 + fumadocs-core: + specifier: 15.2.7 + version: 15.2.7(@types/react@19.1.2)(next@15.3.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + fumadocs-mdx: + specifier: 11.6.0 + version: 11.6.0(acorn@8.14.1)(fumadocs-core@15.2.7(@types/react@19.1.2)(next@15.3.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(next@15.3.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0)) + fumadocs-ui: + specifier: 15.2.7 + version: 15.2.7(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(next@15.3.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(tailwindcss@4.1.4) + lucide-react: + specifier: ^0.488.0 + version: 0.488.0(react@19.1.0) + motion: + specifier: ^12.9.1 + version: 12.9.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + next: + specifier: 15.3.0 + version: 15.3.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + react: + specifier: ^19.1.0 + version: 19.1.0 + react-dom: + specifier: ^19.1.0 + version: 19.1.0(react@19.1.0) + tailwind-merge: + specifier: ^3.2.0 + version: 3.2.0 + devDependencies: + '@tailwindcss/postcss': + specifier: ^4.1.3 + version: 4.1.4 + '@types/mdx': + specifier: ^2.0.13 + version: 2.0.13 + '@types/node': + specifier: 22.14.0 + version: 22.14.0 + '@types/react': + specifier: ^19.1.0 + version: 19.1.2 + '@types/react-dom': + specifier: ^19.1.2 + version: 19.1.2(@types/react@19.1.2) + eslint: + specifier: ^8 + version: 8.57.1 + eslint-config-next: + specifier: 15.3.0 + version: 15.3.0(eslint@8.57.1)(typescript@5.8.3) + postcss: + specifier: ^8.5.3 + version: 8.5.3 + tailwindcss: + specifier: ^4.1.3 + version: 4.1.4 + tw-animate-css: + specifier: ^1.2.8 + version: 1.2.8 + typescript: + specifier: ^5.8.3 + version: 5.8.3 packages: - '@astrojs/compiler@2.11.0': - resolution: {integrity: sha512-zZOO7i+JhojO8qmlyR/URui6LyfHJY6m+L9nwyX5GiKD78YoRaZ5tzz6X0fkl+5bD3uwlDHayf6Oe8Fu36RKNg==} + '@alloc/quick-lru@5.2.0': + resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} + engines: {node: '>=10'} - '@astrojs/internal-helpers@0.6.1': - resolution: {integrity: sha512-l5Pqf6uZu31aG+3Lv8nl/3s4DbUzdlxTWDof4pEpto6GUJNhhCbelVi9dEyurOVyqaelwmS9oSyOWOENSfgo9A==} + '@emnapi/core@1.4.3': + resolution: {integrity: sha512-4m62DuCE07lw01soJwPiBGC0nAww0Q+RY70VZ+n49yDIO13yyinhbWCeNnaob0lakDtWQzSdtNWzJeOJt2ma+g==} - '@astrojs/markdown-remark@6.3.0': - resolution: {integrity: sha512-imInEojAbpeV9D/SRaSQBz3yUzvtg3UQC1euX70QHVf8X0kWAIAArmzBbgXl8LlyxSFe52f/++PXQ4t14V9b+A==} + '@emnapi/runtime@1.4.3': + resolution: {integrity: sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ==} - '@astrojs/mdx@4.2.0': - resolution: {integrity: sha512-MHiogYeb7XdzbqUktoMsrziph1vK10WfLgwDJVejGOieEsJ1eOUtNtQCl2vv85tnr/+IGBqZ0bOf6ydQGgJMYA==} - engines: {node: ^18.17.1 || ^20.3.0 || >=22.0.0} - peerDependencies: - astro: ^5.0.0 + '@emnapi/wasi-threads@1.0.2': + resolution: {integrity: sha512-5n3nTJblwRi8LlXkJ9eBzu+kZR8Yxcc7ubakyQTFzPMtIhFpUBRbsnc2Dv88IZDIbCDlBiWrknhB4Lsz7mg6BA==} - '@astrojs/prism@3.2.0': - resolution: {integrity: sha512-GilTHKGCW6HMq7y3BUv9Ac7GMe/MO9gi9GW62GzKtth0SwukCu/qp2wLiGpEujhY+VVhaG9v7kv/5vFzvf4NYw==} - engines: {node: ^18.17.1 || ^20.3.0 || >=22.0.0} - - '@astrojs/sitemap@3.2.1': - resolution: {integrity: sha512-uxMfO8f7pALq0ADL6Lk68UV6dNYjJ2xGUzyjjVj60JLBs5a6smtlkBYv3tQ0DzoqwS7c9n4FUx5lgv0yPo/fgA==} - - '@astrojs/starlight@0.32.2': - resolution: {integrity: sha512-FLz8Y8R+GsD0jD/G64bYijwwVsAq99Ugk2bJYRmH2k1reYMh83GRma2IaKGgSI2fLNEu7tdyG4cpkwrwP3W02A==} - peerDependencies: - astro: ^5.1.5 - - '@astrojs/telemetry@3.2.0': - resolution: {integrity: sha512-wxhSKRfKugLwLlr4OFfcqovk+LIFtKwLyGPqMsv+9/ibqqnW3Gv7tBhtKEb0gAyUAC4G9BTVQeQahqnQAhd6IQ==} - engines: {node: ^18.17.1 || ^20.3.0 || >=22.0.0} - - '@babel/helper-string-parser@7.25.9': - resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==} - engines: {node: '>=6.9.0'} - - '@babel/helper-validator-identifier@7.25.9': - resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==} - engines: {node: '>=6.9.0'} - - '@babel/parser@7.26.10': - resolution: {integrity: sha512-6aQR2zGE/QFi8JpDLjUZEPYOs7+mhKXm86VaKFiLP35JQwQb6bwUE+XbvkH0EptsYhbNBSUGaUBLKqxH1xSgsA==} - engines: {node: '>=6.0.0'} - hasBin: true - - '@babel/runtime@7.26.10': - resolution: {integrity: sha512-2WJMeRQPHKSPemqk/awGrAiuFfzBmOIPXKizAsVhWH9YJqLZ0H+HS4c8loHGgW6utJ3E/ejXQUsiGaQy2NZ9Fw==} - engines: {node: '>=6.9.0'} - - '@babel/types@7.26.10': - resolution: {integrity: sha512-emqcG3vHrpxUKTrxcblR36dcrcoRDvKmnL/dCL6ZsHaShW80qxCAcNhzQZrpeM765VzEos+xOi4s+r4IXzTwdQ==} - engines: {node: '>=6.9.0'} - - '@ctrl/tinycolor@4.1.0': - resolution: {integrity: sha512-WyOx8cJQ+FQus4Mm4uPIZA64gbk3Wxh0so5Lcii0aJifqwoVOlfFtorjLE0Hen4OYyHZMXDWqMmaQemBhgxFRQ==} - engines: {node: '>=14'} - - '@emnapi/runtime@1.3.1': - resolution: {integrity: sha512-kEBmG8KyqtxJZv+ygbEim+KCGtIq1fC22Ms3S4ziXmYKm8uyoLX0MHONVKwp+9opg390VaKRNt4a7A9NwmpNhw==} - - '@esbuild/aix-ppc64@0.25.1': - resolution: {integrity: sha512-kfYGy8IdzTGy+z0vFGvExZtxkFlA4zAxgKEahG9KE1ScBjpQnFsNOX8KTU5ojNru5ed5CVoJYXFtoxaq5nFbjQ==} + '@esbuild/aix-ppc64@0.25.2': + resolution: {integrity: sha512-wCIboOL2yXZym2cgm6mlA742s9QeJ8DjGVaL39dLN4rRwrOgOyYSnOaFPhKZGLb2ngj4EyfAFjsNJwPXZvseag==} engines: {node: '>=18'} cpu: [ppc64] os: [aix] - '@esbuild/android-arm64@0.25.1': - resolution: {integrity: sha512-50tM0zCJW5kGqgG7fQ7IHvQOcAn9TKiVRuQ/lN0xR+T2lzEFvAi1ZcS8DiksFcEpf1t/GYOeOfCAgDHFpkiSmA==} + '@esbuild/android-arm64@0.25.2': + resolution: {integrity: sha512-5ZAX5xOmTligeBaeNEPnPaeEuah53Id2tX4c2CVP3JaROTH+j4fnfHCkr1PjXMd78hMst+TlkfKcW/DlTq0i4w==} engines: {node: '>=18'} cpu: [arm64] os: [android] - '@esbuild/android-arm@0.25.1': - resolution: {integrity: sha512-dp+MshLYux6j/JjdqVLnMglQlFu+MuVeNrmT5nk6q07wNhCdSnB7QZj+7G8VMUGh1q+vj2Bq8kRsuyA00I/k+Q==} + '@esbuild/android-arm@0.25.2': + resolution: {integrity: sha512-NQhH7jFstVY5x8CKbcfa166GoV0EFkaPkCKBQkdPJFvo5u+nGXLEH/ooniLb3QI8Fk58YAx7nsPLozUWfCBOJA==} engines: {node: '>=18'} cpu: [arm] os: [android] - '@esbuild/android-x64@0.25.1': - resolution: {integrity: sha512-GCj6WfUtNldqUzYkN/ITtlhwQqGWu9S45vUXs7EIYf+7rCiiqH9bCloatO9VhxsL0Pji+PF4Lz2XXCES+Q8hDw==} + '@esbuild/android-x64@0.25.2': + resolution: {integrity: sha512-Ffcx+nnma8Sge4jzddPHCZVRvIfQ0kMsUsCMcJRHkGJ1cDmhe4SsrYIjLUKn1xpHZybmOqCWwB0zQvsjdEHtkg==} engines: {node: '>=18'} cpu: [x64] os: [android] - '@esbuild/darwin-arm64@0.25.1': - resolution: {integrity: sha512-5hEZKPf+nQjYoSr/elb62U19/l1mZDdqidGfmFutVUjjUZrOazAtwK+Kr+3y0C/oeJfLlxo9fXb1w7L+P7E4FQ==} + '@esbuild/darwin-arm64@0.25.2': + resolution: {integrity: sha512-MpM6LUVTXAzOvN4KbjzU/q5smzryuoNjlriAIx+06RpecwCkL9JpenNzpKd2YMzLJFOdPqBpuub6eVRP5IgiSA==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] - '@esbuild/darwin-x64@0.25.1': - resolution: {integrity: sha512-hxVnwL2Dqs3fM1IWq8Iezh0cX7ZGdVhbTfnOy5uURtao5OIVCEyj9xIzemDi7sRvKsuSdtCAhMKarxqtlyVyfA==} + '@esbuild/darwin-x64@0.25.2': + resolution: {integrity: sha512-5eRPrTX7wFyuWe8FqEFPG2cU0+butQQVNcT4sVipqjLYQjjh8a8+vUTfgBKM88ObB85ahsnTwF7PSIt6PG+QkA==} engines: {node: '>=18'} cpu: [x64] os: [darwin] - '@esbuild/freebsd-arm64@0.25.1': - resolution: {integrity: sha512-1MrCZs0fZa2g8E+FUo2ipw6jw5qqQiH+tERoS5fAfKnRx6NXH31tXBKI3VpmLijLH6yriMZsxJtaXUyFt/8Y4A==} + '@esbuild/freebsd-arm64@0.25.2': + resolution: {integrity: sha512-mLwm4vXKiQ2UTSX4+ImyiPdiHjiZhIaE9QvC7sw0tZ6HoNMjYAqQpGyui5VRIi5sGd+uWq940gdCbY3VLvsO1w==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-x64@0.25.1': - resolution: {integrity: sha512-0IZWLiTyz7nm0xuIs0q1Y3QWJC52R8aSXxe40VUxm6BB1RNmkODtW6LHvWRrGiICulcX7ZvyH6h5fqdLu4gkww==} + '@esbuild/freebsd-x64@0.25.2': + resolution: {integrity: sha512-6qyyn6TjayJSwGpm8J9QYYGQcRgc90nmfdUb0O7pp1s4lTY+9D0H9O02v5JqGApUyiHOtkz6+1hZNvNtEhbwRQ==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] - '@esbuild/linux-arm64@0.25.1': - resolution: {integrity: sha512-jaN3dHi0/DDPelk0nLcXRm1q7DNJpjXy7yWaWvbfkPvI+7XNSc/lDOnCLN7gzsyzgu6qSAmgSvP9oXAhP973uQ==} + '@esbuild/linux-arm64@0.25.2': + resolution: {integrity: sha512-gq/sjLsOyMT19I8obBISvhoYiZIAaGF8JpeXu1u8yPv8BE5HlWYobmlsfijFIZ9hIVGYkbdFhEqC0NvM4kNO0g==} engines: {node: '>=18'} cpu: [arm64] os: [linux] - '@esbuild/linux-arm@0.25.1': - resolution: {integrity: sha512-NdKOhS4u7JhDKw9G3cY6sWqFcnLITn6SqivVArbzIaf3cemShqfLGHYMx8Xlm/lBit3/5d7kXvriTUGa5YViuQ==} + '@esbuild/linux-arm@0.25.2': + resolution: {integrity: sha512-UHBRgJcmjJv5oeQF8EpTRZs/1knq6loLxTsjc3nxO9eXAPDLcWW55flrMVc97qFPbmZP31ta1AZVUKQzKTzb0g==} engines: {node: '>=18'} cpu: [arm] os: [linux] - '@esbuild/linux-ia32@0.25.1': - resolution: {integrity: sha512-OJykPaF4v8JidKNGz8c/q1lBO44sQNUQtq1KktJXdBLn1hPod5rE/Hko5ugKKZd+D2+o1a9MFGUEIUwO2YfgkQ==} + '@esbuild/linux-ia32@0.25.2': + resolution: {integrity: sha512-bBYCv9obgW2cBP+2ZWfjYTU+f5cxRoGGQ5SeDbYdFCAZpYWrfjjfYwvUpP8MlKbP0nwZ5gyOU/0aUzZ5HWPuvQ==} engines: {node: '>=18'} cpu: [ia32] os: [linux] - '@esbuild/linux-loong64@0.25.1': - resolution: {integrity: sha512-nGfornQj4dzcq5Vp835oM/o21UMlXzn79KobKlcs3Wz9smwiifknLy4xDCLUU0BWp7b/houtdrgUz7nOGnfIYg==} + '@esbuild/linux-loong64@0.25.2': + resolution: {integrity: sha512-SHNGiKtvnU2dBlM5D8CXRFdd+6etgZ9dXfaPCeJtz+37PIUlixvlIhI23L5khKXs3DIzAn9V8v+qb1TRKrgT5w==} engines: {node: '>=18'} cpu: [loong64] os: [linux] - '@esbuild/linux-mips64el@0.25.1': - resolution: {integrity: sha512-1osBbPEFYwIE5IVB/0g2X6i1qInZa1aIoj1TdL4AaAb55xIIgbg8Doq6a5BzYWgr+tEcDzYH67XVnTmUzL+nXg==} + '@esbuild/linux-mips64el@0.25.2': + resolution: {integrity: sha512-hDDRlzE6rPeoj+5fsADqdUZl1OzqDYow4TB4Y/3PlKBD0ph1e6uPHzIQcv2Z65u2K0kpeByIyAjCmjn1hJgG0Q==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] - '@esbuild/linux-ppc64@0.25.1': - resolution: {integrity: sha512-/6VBJOwUf3TdTvJZ82qF3tbLuWsscd7/1w+D9LH0W/SqUgM5/JJD0lrJ1fVIfZsqB6RFmLCe0Xz3fmZc3WtyVg==} + '@esbuild/linux-ppc64@0.25.2': + resolution: {integrity: sha512-tsHu2RRSWzipmUi9UBDEzc0nLc4HtpZEI5Ba+Omms5456x5WaNuiG3u7xh5AO6sipnJ9r4cRWQB2tUjPyIkc6g==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] - '@esbuild/linux-riscv64@0.25.1': - resolution: {integrity: sha512-nSut/Mx5gnilhcq2yIMLMe3Wl4FK5wx/o0QuuCLMtmJn+WeWYoEGDN1ipcN72g1WHsnIbxGXd4i/MF0gTcuAjQ==} + '@esbuild/linux-riscv64@0.25.2': + resolution: {integrity: sha512-k4LtpgV7NJQOml/10uPU0s4SAXGnowi5qBSjaLWMojNCUICNu7TshqHLAEbkBdAszL5TabfvQ48kK84hyFzjnw==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] - '@esbuild/linux-s390x@0.25.1': - resolution: {integrity: sha512-cEECeLlJNfT8kZHqLarDBQso9a27o2Zd2AQ8USAEoGtejOrCYHNtKP8XQhMDJMtthdF4GBmjR2au3x1udADQQQ==} + '@esbuild/linux-s390x@0.25.2': + resolution: {integrity: sha512-GRa4IshOdvKY7M/rDpRR3gkiTNp34M0eLTaC1a08gNrh4u488aPhuZOCpkF6+2wl3zAN7L7XIpOFBhnaE3/Q8Q==} engines: {node: '>=18'} cpu: [s390x] os: [linux] - '@esbuild/linux-x64@0.25.1': - resolution: {integrity: sha512-xbfUhu/gnvSEg+EGovRc+kjBAkrvtk38RlerAzQxvMzlB4fXpCFCeUAYzJvrnhFtdeyVCDANSjJvOvGYoeKzFA==} + '@esbuild/linux-x64@0.25.2': + resolution: {integrity: sha512-QInHERlqpTTZ4FRB0fROQWXcYRD64lAoiegezDunLpalZMjcUcld3YzZmVJ2H/Cp0wJRZ8Xtjtj0cEHhYc/uUg==} engines: {node: '>=18'} cpu: [x64] os: [linux] - '@esbuild/netbsd-arm64@0.25.1': - resolution: {integrity: sha512-O96poM2XGhLtpTh+s4+nP7YCCAfb4tJNRVZHfIE7dgmax+yMP2WgMd2OecBuaATHKTHsLWHQeuaxMRnCsH8+5g==} + '@esbuild/netbsd-arm64@0.25.2': + resolution: {integrity: sha512-talAIBoY5M8vHc6EeI2WW9d/CkiO9MQJ0IOWX8hrLhxGbro/vBXJvaQXefW2cP0z0nQVTdQ/eNyGFV1GSKrxfw==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] - '@esbuild/netbsd-x64@0.25.1': - resolution: {integrity: sha512-X53z6uXip6KFXBQ+Krbx25XHV/NCbzryM6ehOAeAil7X7oa4XIq+394PWGnwaSQ2WRA0KI6PUO6hTO5zeF5ijA==} + '@esbuild/netbsd-x64@0.25.2': + resolution: {integrity: sha512-voZT9Z+tpOxrvfKFyfDYPc4DO4rk06qamv1a/fkuzHpiVBMOhpjK+vBmWM8J1eiB3OLSMFYNaOaBNLXGChf5tg==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] - '@esbuild/openbsd-arm64@0.25.1': - resolution: {integrity: sha512-Na9T3szbXezdzM/Kfs3GcRQNjHzM6GzFBeU1/6IV/npKP5ORtp9zbQjvkDJ47s6BCgaAZnnnu/cY1x342+MvZg==} + '@esbuild/openbsd-arm64@0.25.2': + resolution: {integrity: sha512-dcXYOC6NXOqcykeDlwId9kB6OkPUxOEqU+rkrYVqJbK2hagWOMrsTGsMr8+rW02M+d5Op5NNlgMmjzecaRf7Tg==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] - '@esbuild/openbsd-x64@0.25.1': - resolution: {integrity: sha512-T3H78X2h1tszfRSf+txbt5aOp/e7TAz3ptVKu9Oyir3IAOFPGV6O9c2naym5TOriy1l0nNf6a4X5UXRZSGX/dw==} + '@esbuild/openbsd-x64@0.25.2': + resolution: {integrity: sha512-t/TkWwahkH0Tsgoq1Ju7QfgGhArkGLkF1uYz8nQS/PPFlXbP5YgRpqQR3ARRiC2iXoLTWFxc6DJMSK10dVXluw==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] - '@esbuild/sunos-x64@0.25.1': - resolution: {integrity: sha512-2H3RUvcmULO7dIE5EWJH8eubZAI4xw54H1ilJnRNZdeo8dTADEZ21w6J22XBkXqGJbe0+wnNJtw3UXRoLJnFEg==} + '@esbuild/sunos-x64@0.25.2': + resolution: {integrity: sha512-cfZH1co2+imVdWCjd+D1gf9NjkchVhhdpgb1q5y6Hcv9TP6Zi9ZG/beI3ig8TvwT9lH9dlxLq5MQBBgwuj4xvA==} engines: {node: '>=18'} cpu: [x64] os: [sunos] - '@esbuild/win32-arm64@0.25.1': - resolution: {integrity: sha512-GE7XvrdOzrb+yVKB9KsRMq+7a2U/K5Cf/8grVFRAGJmfADr/e/ODQ134RK2/eeHqYV5eQRFxb1hY7Nr15fv1NQ==} + '@esbuild/win32-arm64@0.25.2': + resolution: {integrity: sha512-7Loyjh+D/Nx/sOTzV8vfbB3GJuHdOQyrOryFdZvPHLf42Tk9ivBU5Aedi7iyX+x6rbn2Mh68T4qq1SDqJBQO5Q==} engines: {node: '>=18'} cpu: [arm64] os: [win32] - '@esbuild/win32-ia32@0.25.1': - resolution: {integrity: sha512-uOxSJCIcavSiT6UnBhBzE8wy3n0hOkJsBOzy7HDAuTDE++1DJMRRVCPGisULScHL+a/ZwdXPpXD3IyFKjA7K8A==} + '@esbuild/win32-ia32@0.25.2': + resolution: {integrity: sha512-WRJgsz9un0nqZJ4MfhabxaD9Ft8KioqU3JMinOTvobbX6MOSUigSBlogP8QB3uxpJDsFS6yN+3FDBdqE5lg9kg==} engines: {node: '>=18'} cpu: [ia32] os: [win32] - '@esbuild/win32-x64@0.25.1': - resolution: {integrity: sha512-Y1EQdcfwMSeQN/ujR5VayLOJ1BHaK+ssyk0AEzPjC+t1lITgsnccPqFjb6V+LsTp/9Iov4ysfjxLaGJ9RPtkVg==} + '@esbuild/win32-x64@0.25.2': + resolution: {integrity: sha512-kM3HKb16VIXZyIeVrM1ygYmZBKybX8N4p754bw390wGO3Tf2j4L2/WYL+4suWujpgf6GBYs3jv7TyUivdd05JA==} engines: {node: '>=18'} cpu: [x64] os: [win32] - '@expressive-code/core@0.40.2': - resolution: {integrity: sha512-gXY3v7jbgz6nWKvRpoDxK4AHUPkZRuJsM79vHX/5uhV9/qX6Qnctp/U/dMHog/LCVXcuOps+5nRmf1uxQVPb3w==} + '@eslint-community/eslint-utils@4.6.1': + resolution: {integrity: sha512-KTsJMmobmbrFLe3LDh0PC2FXpcSYJt/MLjlkh/9LEnmKYLSYmT/0EW9JWANjeoemiuZrmogti0tW5Ch+qNUYDw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - '@expressive-code/plugin-frames@0.40.2': - resolution: {integrity: sha512-aLw5IlDlZWb10Jo/TTDCVsmJhKfZ7FJI83Zo9VDrV0OBlmHAg7klZqw68VDz7FlftIBVAmMby53/MNXPnMjTSQ==} + '@eslint-community/regexpp@4.12.1': + resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - '@expressive-code/plugin-shiki@0.40.2': - resolution: {integrity: sha512-t2HMR5BO6GdDW1c1ISBTk66xO503e/Z8ecZdNcr6E4NpUfvY+MRje+LtrcvbBqMwWBBO8RpVKcam/Uy+1GxwKQ==} + '@eslint/eslintrc@2.1.4': + resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - '@expressive-code/plugin-text-markers@0.40.2': - resolution: {integrity: sha512-/XoLjD67K9nfM4TgDlXAExzMJp6ewFKxNpfUw4F7q5Ecy+IU3/9zQQG/O70Zy+RxYTwKGw2MA9kd7yelsxnSmw==} + '@eslint/js@8.57.1': + resolution: {integrity: sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - '@img/sharp-darwin-arm64@0.33.5': - resolution: {integrity: sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==} + '@floating-ui/core@1.6.9': + resolution: {integrity: sha512-uMXCuQ3BItDUbAMhIXw7UPXRfAlOAvZzdK9BWpE60MCn+Svt3aLn9jsPTi/WNGlRUu2uI0v5S7JiIUsbsvh3fw==} + + '@floating-ui/dom@1.6.13': + resolution: {integrity: sha512-umqzocjDgNRGTuO7Q8CU32dkHkECqI8ZdMZ5Swb6QAM0t5rnlrN3lGo1hdpscRd3WS8T6DKYK4ephgIH9iRh3w==} + + '@floating-ui/react-dom@2.1.2': + resolution: {integrity: sha512-06okr5cgPzMNBy+Ycse2A6udMi4bqwW/zgBF/rwjcNqWkyr82Mcg8b0vjX8OJpZFy/FKjJmw6wV7t44kK6kW7A==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + + '@floating-ui/utils@0.2.9': + resolution: {integrity: sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==} + + '@formatjs/intl-localematcher@0.6.1': + resolution: {integrity: sha512-ePEgLgVCqi2BBFnTMWPfIghu6FkbZnnBVhO2sSxvLfrdFw7wCHAHiDoM2h4NRgjbaY7+B7HgOLZGkK187pZTZg==} + + '@humanwhocodes/config-array@0.13.0': + resolution: {integrity: sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==} + engines: {node: '>=10.10.0'} + deprecated: Use @eslint/config-array instead + + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + + '@humanwhocodes/object-schema@2.0.3': + resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} + deprecated: Use @eslint/object-schema instead + + '@img/sharp-darwin-arm64@0.34.1': + resolution: {integrity: sha512-pn44xgBtgpEbZsu+lWf2KNb6OAf70X68k+yk69Ic2Xz11zHR/w24/U49XT7AeRwJ0Px+mhALhU5LPci1Aymk7A==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [darwin] - '@img/sharp-darwin-x64@0.33.5': - resolution: {integrity: sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==} + '@img/sharp-darwin-x64@0.34.1': + resolution: {integrity: sha512-VfuYgG2r8BpYiOUN+BfYeFo69nP/MIwAtSJ7/Zpxc5QF3KS22z8Pvg3FkrSFJBPNQ7mmcUcYQFBmEQp7eu1F8Q==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [darwin] - '@img/sharp-libvips-darwin-arm64@1.0.4': - resolution: {integrity: sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==} + '@img/sharp-libvips-darwin-arm64@1.1.0': + resolution: {integrity: sha512-HZ/JUmPwrJSoM4DIQPv/BfNh9yrOA8tlBbqbLz4JZ5uew2+o22Ik+tHQJcih7QJuSa0zo5coHTfD5J8inqj9DA==} cpu: [arm64] os: [darwin] - '@img/sharp-libvips-darwin-x64@1.0.4': - resolution: {integrity: sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==} + '@img/sharp-libvips-darwin-x64@1.1.0': + resolution: {integrity: sha512-Xzc2ToEmHN+hfvsl9wja0RlnXEgpKNmftriQp6XzY/RaSfwD9th+MSh0WQKzUreLKKINb3afirxW7A0fz2YWuQ==} cpu: [x64] os: [darwin] - '@img/sharp-libvips-linux-arm64@1.0.4': - resolution: {integrity: sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==} + '@img/sharp-libvips-linux-arm64@1.1.0': + resolution: {integrity: sha512-IVfGJa7gjChDET1dK9SekxFFdflarnUB8PwW8aGwEoF3oAsSDuNUTYS+SKDOyOJxQyDC1aPFMuRYLoDInyV9Ew==} cpu: [arm64] os: [linux] - '@img/sharp-libvips-linux-arm@1.0.5': - resolution: {integrity: sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==} + '@img/sharp-libvips-linux-arm@1.1.0': + resolution: {integrity: sha512-s8BAd0lwUIvYCJyRdFqvsj+BJIpDBSxs6ivrOPm/R7piTs5UIwY5OjXrP2bqXC9/moGsyRa37eYWYCOGVXxVrA==} cpu: [arm] os: [linux] - '@img/sharp-libvips-linux-s390x@1.0.4': - resolution: {integrity: sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==} + '@img/sharp-libvips-linux-ppc64@1.1.0': + resolution: {integrity: sha512-tiXxFZFbhnkWE2LA8oQj7KYR+bWBkiV2nilRldT7bqoEZ4HiDOcePr9wVDAZPi/Id5fT1oY9iGnDq20cwUz8lQ==} + cpu: [ppc64] + os: [linux] + + '@img/sharp-libvips-linux-s390x@1.1.0': + resolution: {integrity: sha512-xukSwvhguw7COyzvmjydRb3x/09+21HykyapcZchiCUkTThEQEOMtBj9UhkaBRLuBrgLFzQ2wbxdeCCJW/jgJA==} cpu: [s390x] os: [linux] - '@img/sharp-libvips-linux-x64@1.0.4': - resolution: {integrity: sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==} + '@img/sharp-libvips-linux-x64@1.1.0': + resolution: {integrity: sha512-yRj2+reB8iMg9W5sULM3S74jVS7zqSzHG3Ol/twnAAkAhnGQnpjj6e4ayUz7V+FpKypwgs82xbRdYtchTTUB+Q==} cpu: [x64] os: [linux] - '@img/sharp-libvips-linuxmusl-arm64@1.0.4': - resolution: {integrity: sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==} + '@img/sharp-libvips-linuxmusl-arm64@1.1.0': + resolution: {integrity: sha512-jYZdG+whg0MDK+q2COKbYidaqW/WTz0cc1E+tMAusiDygrM4ypmSCjOJPmFTvHHJ8j/6cAGyeDWZOsK06tP33w==} cpu: [arm64] os: [linux] - '@img/sharp-libvips-linuxmusl-x64@1.0.4': - resolution: {integrity: sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==} + '@img/sharp-libvips-linuxmusl-x64@1.1.0': + resolution: {integrity: sha512-wK7SBdwrAiycjXdkPnGCPLjYb9lD4l6Ze2gSdAGVZrEL05AOUJESWU2lhlC+Ffn5/G+VKuSm6zzbQSzFX/P65A==} cpu: [x64] os: [linux] - '@img/sharp-linux-arm64@0.33.5': - resolution: {integrity: sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==} + '@img/sharp-linux-arm64@0.34.1': + resolution: {integrity: sha512-kX2c+vbvaXC6vly1RDf/IWNXxrlxLNpBVWkdpRq5Ka7OOKj6nr66etKy2IENf6FtOgklkg9ZdGpEu9kwdlcwOQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [linux] - '@img/sharp-linux-arm@0.33.5': - resolution: {integrity: sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==} + '@img/sharp-linux-arm@0.34.1': + resolution: {integrity: sha512-anKiszvACti2sGy9CirTlNyk7BjjZPiML1jt2ZkTdcvpLU1YH6CXwRAZCA2UmRXnhiIftXQ7+Oh62Ji25W72jA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm] os: [linux] - '@img/sharp-linux-s390x@0.33.5': - resolution: {integrity: sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==} + '@img/sharp-linux-s390x@0.34.1': + resolution: {integrity: sha512-7s0KX2tI9mZI2buRipKIw2X1ufdTeaRgwmRabt5bi9chYfhur+/C1OXg3TKg/eag1W+6CCWLVmSauV1owmRPxA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [s390x] os: [linux] - '@img/sharp-linux-x64@0.33.5': - resolution: {integrity: sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==} + '@img/sharp-linux-x64@0.34.1': + resolution: {integrity: sha512-wExv7SH9nmoBW3Wr2gvQopX1k8q2g5V5Iag8Zk6AVENsjwd+3adjwxtp3Dcu2QhOXr8W9NusBU6XcQUohBZ5MA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [linux] - '@img/sharp-linuxmusl-arm64@0.33.5': - resolution: {integrity: sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==} + '@img/sharp-linuxmusl-arm64@0.34.1': + resolution: {integrity: sha512-DfvyxzHxw4WGdPiTF0SOHnm11Xv4aQexvqhRDAoD00MzHekAj9a/jADXeXYCDFH/DzYruwHbXU7uz+H+nWmSOQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [arm64] os: [linux] - '@img/sharp-linuxmusl-x64@0.33.5': - resolution: {integrity: sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==} + '@img/sharp-linuxmusl-x64@0.34.1': + resolution: {integrity: sha512-pax/kTR407vNb9qaSIiWVnQplPcGU8LRIJpDT5o8PdAx5aAA7AS3X9PS8Isw1/WfqgQorPotjrZL3Pqh6C5EBg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [linux] - '@img/sharp-wasm32@0.33.5': - resolution: {integrity: sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==} + '@img/sharp-wasm32@0.34.1': + resolution: {integrity: sha512-YDybQnYrLQfEpzGOQe7OKcyLUCML4YOXl428gOOzBgN6Gw0rv8dpsJ7PqTHxBnXnwXr8S1mYFSLSa727tpz0xg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [wasm32] - '@img/sharp-win32-ia32@0.33.5': - resolution: {integrity: sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==} + '@img/sharp-win32-ia32@0.34.1': + resolution: {integrity: sha512-WKf/NAZITnonBf3U1LfdjoMgNO5JYRSlhovhRhMxXVdvWYveM4kM3L8m35onYIdh75cOMCo1BexgVQcCDzyoWw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [ia32] os: [win32] - '@img/sharp-win32-x64@0.33.5': - resolution: {integrity: sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==} + '@img/sharp-win32-x64@0.34.1': + resolution: {integrity: sha512-hw1iIAHpNE8q3uMIRCgGOeDoz9KtFNarFLQclLxr/LK1VBkj8nby18RjFvr6aP7USRYAjTZW6yisnBWMX571Tw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [x64] os: [win32] - '@jridgewell/sourcemap-codec@1.5.0': - resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} - '@mdx-js/mdx@3.1.0': resolution: {integrity: sha512-/QxEhPAvGwbQmy1Px8F899L5Uc2KZ6JtXwlCgJmjSTBedwOZkByYcBG4GceIGPXRDsmfxhHazuS+hlOShRLeDw==} - '@oslojs/encoding@1.1.0': - resolution: {integrity: sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==} + '@napi-rs/wasm-runtime@0.2.9': + resolution: {integrity: sha512-OKRBiajrrxB9ATokgEQoG87Z25c67pCpYcCwmXYX8PBftC9pBfN18gnm/fh1wurSLEKIAt+QRFLFCQISrb66Jg==} - '@pagefind/darwin-arm64@1.3.0': - resolution: {integrity: sha512-365BEGl6ChOsauRjyVpBjXybflXAOvoMROw3TucAROHIcdBvXk9/2AmEvGFU0r75+vdQI4LJdJdpH4Y6Yqaj4A==} + '@next/env@15.3.0': + resolution: {integrity: sha512-6mDmHX24nWlHOlbwUiAOmMyY7KELimmi+ed8qWcJYjqXeC+G6JzPZ3QosOAfjNwgMIzwhXBiRiCgdh8axTTdTA==} + + '@next/eslint-plugin-next@15.3.0': + resolution: {integrity: sha512-511UUcpWw5GWTyKfzW58U2F/bYJyjLE9e3SlnGK/zSXq7RqLlqFO8B9bitJjumLpj317fycC96KZ2RZsjGNfBw==} + + '@next/swc-darwin-arm64@15.3.0': + resolution: {integrity: sha512-PDQcByT0ZfF2q7QR9d+PNj3wlNN4K6Q8JoHMwFyk252gWo4gKt7BF8Y2+KBgDjTFBETXZ/TkBEUY7NIIY7A/Kw==} + engines: {node: '>= 10'} cpu: [arm64] os: [darwin] - '@pagefind/darwin-x64@1.3.0': - resolution: {integrity: sha512-zlGHA23uuXmS8z3XxEGmbHpWDxXfPZ47QS06tGUq0HDcZjXjXHeLG+cboOy828QIV5FXsm9MjfkP5e4ZNbOkow==} + '@next/swc-darwin-x64@15.3.0': + resolution: {integrity: sha512-m+eO21yg80En8HJ5c49AOQpFDq+nP51nu88ZOMCorvw3g//8g1JSUsEiPSiFpJo1KCTQ+jm9H0hwXK49H/RmXg==} + engines: {node: '>= 10'} cpu: [x64] os: [darwin] - '@pagefind/default-ui@1.3.0': - resolution: {integrity: sha512-CGKT9ccd3+oRK6STXGgfH+m0DbOKayX6QGlq38TfE1ZfUcPc5+ulTuzDbZUnMo+bubsEOIypm4Pl2iEyzZ1cNg==} - - '@pagefind/linux-arm64@1.3.0': - resolution: {integrity: sha512-8lsxNAiBRUk72JvetSBXs4WRpYrQrVJXjlRRnOL6UCdBN9Nlsz0t7hWstRk36+JqHpGWOKYiuHLzGYqYAqoOnQ==} + '@next/swc-linux-arm64-gnu@15.3.0': + resolution: {integrity: sha512-H0Kk04ZNzb6Aq/G6e0un4B3HekPnyy6D+eUBYPJv9Abx8KDYgNMWzKt4Qhj57HXV3sTTjsfc1Trc1SxuhQB+Tg==} + engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@pagefind/linux-x64@1.3.0': - resolution: {integrity: sha512-hAvqdPJv7A20Ucb6FQGE6jhjqy+vZ6pf+s2tFMNtMBG+fzcdc91uTw7aP/1Vo5plD0dAOHwdxfkyw0ugal4kcQ==} + '@next/swc-linux-arm64-musl@15.3.0': + resolution: {integrity: sha512-k8GVkdMrh/+J9uIv/GpnHakzgDQhrprJ/FbGQvwWmstaeFG06nnAoZCJV+wO/bb603iKV1BXt4gHG+s2buJqZA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@next/swc-linux-x64-gnu@15.3.0': + resolution: {integrity: sha512-ZMQ9yzDEts/vkpFLRAqfYO1wSpIJGlQNK9gZ09PgyjBJUmg8F/bb8fw2EXKgEaHbCc4gmqMpDfh+T07qUphp9A==} + engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@pagefind/windows-x64@1.3.0': - resolution: {integrity: sha512-BR1bIRWOMqkf8IoU576YDhij1Wd/Zf2kX/kCI0b2qzCKC8wcc2GQJaaRMCpzvCCrmliO4vtJ6RITp/AnoYUUmQ==} + '@next/swc-linux-x64-musl@15.3.0': + resolution: {integrity: sha512-RFwq5VKYTw9TMr4T3e5HRP6T4RiAzfDJ6XsxH8j/ZeYq2aLsBqCkFzwMI0FmnSsLaUbOb46Uov0VvN3UciHX5A==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@next/swc-win32-arm64-msvc@15.3.0': + resolution: {integrity: sha512-a7kUbqa/k09xPjfCl0RSVAvEjAkYBYxUzSVAzk2ptXiNEL+4bDBo9wNC43G/osLA/EOGzG4CuNRFnQyIHfkRgQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + + '@next/swc-win32-x64-msvc@15.3.0': + resolution: {integrity: sha512-vHUQS4YVGJPmpjn7r5lEZuMhK5UQBNBRSB+iGDvJjaNk649pTIcRluDWNb9siunyLLiu/LDPHfvxBtNamyuLTw==} + engines: {node: '>= 10'} cpu: [x64] os: [win32] - '@rollup/pluginutils@5.1.4': - resolution: {integrity: sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==} - engines: {node: '>=14.0.0'} + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@nolyfill/is-core-module@1.0.39': + resolution: {integrity: sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==} + engines: {node: '>=12.4.0'} + + '@orama/orama@3.1.6': + resolution: {integrity: sha512-qtSrqCqRU93SjEBedz987tvWao1YQSELjBhGkHYGVP7Dg0lBWP6d+uZEIt5gxTAYio/YWWlhivmRABvRfPLmnQ==} + engines: {node: '>= 16.0.0'} + + '@radix-ui/number@1.1.1': + resolution: {integrity: sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==} + + '@radix-ui/primitive@1.1.2': + resolution: {integrity: sha512-XnbHrrprsNqZKQhStrSwgRUQzoCI1glLzdw79xiZPoofhGICeZRSQ3dIxAKH1gb3OHfNf4d6f+vAv3kil2eggA==} + + '@radix-ui/react-accordion@1.2.4': + resolution: {integrity: sha512-SGCxlSBaMvEzDROzyZjsVNzu9XY5E28B3k8jOENyrz6csOv/pG1eHyYfLJai1n9tRjwG61coXDhfpgtxKxUv5g==} peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc peerDependenciesMeta: - rollup: + '@types/react': + optional: true + '@types/react-dom': optional: true - '@rollup/rollup-android-arm-eabi@4.35.0': - resolution: {integrity: sha512-uYQ2WfPaqz5QtVgMxfN6NpLD+no0MYHDBywl7itPYd3K5TjjSghNKmX8ic9S8NU8w81NVhJv/XojcHptRly7qQ==} - cpu: [arm] - os: [android] + '@radix-ui/react-arrow@1.1.3': + resolution: {integrity: sha512-2dvVU4jva0qkNZH6HHWuSz5FN5GeU5tymvCgutF8WaXz9WnD1NgUhy73cqzkjkN4Zkn8lfTPv5JIfrC221W+Nw==} + 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 - '@rollup/rollup-android-arm64@4.35.0': - resolution: {integrity: sha512-FtKddj9XZudurLhdJnBl9fl6BwCJ3ky8riCXjEw3/UIbjmIY58ppWwPEvU3fNu+W7FUsAsB1CdH+7EQE6CXAPA==} - cpu: [arm64] - os: [android] + '@radix-ui/react-collapsible@1.1.4': + resolution: {integrity: sha512-u7LCw1EYInQtBNLGjm9nZ89S/4GcvX1UR5XbekEgnQae2Hkpq39ycJ1OhdeN1/JDfVNG91kWaWoest127TaEKQ==} + 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 - '@rollup/rollup-darwin-arm64@4.35.0': - resolution: {integrity: sha512-Uk+GjOJR6CY844/q6r5DR/6lkPFOw0hjfOIzVx22THJXMxktXG6CbejseJFznU8vHcEBLpiXKY3/6xc+cBm65Q==} - cpu: [arm64] - os: [darwin] + '@radix-ui/react-collection@1.1.3': + resolution: {integrity: sha512-mM2pxoQw5HJ49rkzwOs7Y6J4oYH22wS8BfK2/bBxROlI4xuR0c4jEenQP63LlTlDkO6Buj2Vt+QYAYcOgqtrXA==} + 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 - '@rollup/rollup-darwin-x64@4.35.0': - resolution: {integrity: sha512-3IrHjfAS6Vkp+5bISNQnPogRAW5GAV1n+bNCrDwXmfMHbPl5EhTmWtfmwlJxFRUCBZ+tZ/OxDyU08aF6NI/N5Q==} - cpu: [x64] - os: [darwin] + '@radix-ui/react-compose-refs@1.1.2': + resolution: {integrity: sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true - '@rollup/rollup-freebsd-arm64@4.35.0': - resolution: {integrity: sha512-sxjoD/6F9cDLSELuLNnY0fOrM9WA0KrM0vWm57XhrIMf5FGiN8D0l7fn+bpUeBSU7dCgPV2oX4zHAsAXyHFGcQ==} - cpu: [arm64] - os: [freebsd] + '@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 - '@rollup/rollup-freebsd-x64@4.35.0': - resolution: {integrity: sha512-2mpHCeRuD1u/2kruUiHSsnjWtHjqVbzhBkNVQ1aVD63CcexKVcQGwJ2g5VphOd84GvxfSvnnlEyBtQCE5hxVVw==} - cpu: [x64] - os: [freebsd] + '@radix-ui/react-dialog@1.1.7': + resolution: {integrity: sha512-EIdma8C0C/I6kL6sO02avaCRqi3fmWJpxH6mqbVScorW6nNktzKJT/le7VPho3o/7wCsyRg3z0+Q+Obr0Gy/VQ==} + 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 - '@rollup/rollup-linux-arm-gnueabihf@4.35.0': - resolution: {integrity: sha512-mrA0v3QMy6ZSvEuLs0dMxcO2LnaCONs1Z73GUDBHWbY8tFFocM6yl7YyMu7rz4zS81NDSqhrUuolyZXGi8TEqg==} - cpu: [arm] - os: [linux] + '@radix-ui/react-direction@1.1.1': + resolution: {integrity: sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true - '@rollup/rollup-linux-arm-musleabihf@4.35.0': - resolution: {integrity: sha512-DnYhhzcvTAKNexIql8pFajr0PiDGrIsBYPRvCKlA5ixSS3uwo/CWNZxB09jhIapEIg945KOzcYEAGGSmTSpk7A==} - cpu: [arm] - os: [linux] + '@radix-ui/react-dismissable-layer@1.1.6': + resolution: {integrity: sha512-7gpgMT2gyKym9Jz2ZhlRXSg2y6cNQIK8d/cqBZ0RBCaps8pFryCWXiUKI+uHGFrhMrbGUP7U6PWgiXzIxoyF3Q==} + 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 - '@rollup/rollup-linux-arm64-gnu@4.35.0': - resolution: {integrity: sha512-uagpnH2M2g2b5iLsCTZ35CL1FgyuzzJQ8L9VtlJ+FckBXroTwNOaD0z0/UF+k5K3aNQjbm8LIVpxykUOQt1m/A==} - cpu: [arm64] - os: [linux] + '@radix-ui/react-focus-guards@1.1.2': + resolution: {integrity: sha512-fyjAACV62oPV925xFCrH8DR5xWhg9KYtJT4s3u54jxp+L/hbpTY2kIeEFFbFe+a/HCE94zGQMZLIpVTPVZDhaA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true - '@rollup/rollup-linux-arm64-musl@4.35.0': - resolution: {integrity: sha512-XQxVOCd6VJeHQA/7YcqyV0/88N6ysSVzRjJ9I9UA/xXpEsjvAgDTgH3wQYz5bmr7SPtVK2TsP2fQ2N9L4ukoUg==} - cpu: [arm64] - os: [linux] + '@radix-ui/react-focus-scope@1.1.3': + resolution: {integrity: sha512-4XaDlq0bPt7oJwR+0k0clCiCO/7lO7NKZTAaJBYxDNQT/vj4ig0/UvctrRscZaFREpRvUTkpKR96ov1e6jptQg==} + 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 - '@rollup/rollup-linux-loongarch64-gnu@4.35.0': - resolution: {integrity: sha512-5pMT5PzfgwcXEwOaSrqVsz/LvjDZt+vQ8RT/70yhPU06PTuq8WaHhfT1LW+cdD7mW6i/J5/XIkX/1tCAkh1W6g==} - cpu: [loong64] - os: [linux] + '@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 - '@rollup/rollup-linux-powerpc64le-gnu@4.35.0': - resolution: {integrity: sha512-c+zkcvbhbXF98f4CtEIP1EBA/lCic5xB0lToneZYvMeKu5Kamq3O8gqrxiYYLzlZH6E3Aq+TSW86E4ay8iD8EA==} - cpu: [ppc64] - os: [linux] + '@radix-ui/react-navigation-menu@1.2.6': + resolution: {integrity: sha512-HJqyzqG74Lj7KV58rk73i/B1nnopVyCfUmKgeGWWrZZiCuMNcY0KKugTrmqMbIeMliUnkBUDKCy9J6Mzl6xeWw==} + 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 - '@rollup/rollup-linux-riscv64-gnu@4.35.0': - resolution: {integrity: sha512-s91fuAHdOwH/Tad2tzTtPX7UZyytHIRR6V4+2IGlV0Cej5rkG0R61SX4l4y9sh0JBibMiploZx3oHKPnQBKe4g==} - cpu: [riscv64] - os: [linux] + '@radix-ui/react-popover@1.1.7': + resolution: {integrity: sha512-I38OYWDmJF2kbO74LX8UsFydSHWOJuQ7LxPnTefjxxvdvPLempvAnmsyX9UsBlywcbSGpRH7oMLfkUf+ij4nrw==} + 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 - '@rollup/rollup-linux-s390x-gnu@4.35.0': - resolution: {integrity: sha512-hQRkPQPLYJZYGP+Hj4fR9dDBMIM7zrzJDWFEMPdTnTy95Ljnv0/4w/ixFw3pTBMEuuEuoqtBINYND4M7ujcuQw==} - cpu: [s390x] - os: [linux] + '@radix-ui/react-popper@1.2.3': + resolution: {integrity: sha512-iNb9LYUMkne9zIahukgQmHlSBp9XWGeQQ7FvUGNk45ywzOb6kQa+Ca38OphXlWDiKvyneo9S+KSJsLfLt8812A==} + 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 - '@rollup/rollup-linux-x64-gnu@4.35.0': - resolution: {integrity: sha512-Pim1T8rXOri+0HmV4CdKSGrqcBWX0d1HoPnQ0uw0bdp1aP5SdQVNBy8LjYncvnLgu3fnnCt17xjWGd4cqh8/hA==} - cpu: [x64] - os: [linux] + '@radix-ui/react-portal@1.1.5': + resolution: {integrity: sha512-ps/67ZqsFm+Mb6lSPJpfhRLrVL2i2fntgCmGMqqth4eaGUf+knAuuRtWVJrNjUhExgmdRqftSgzpf0DF0n6yXA==} + 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 - '@rollup/rollup-linux-x64-musl@4.35.0': - resolution: {integrity: sha512-QysqXzYiDvQWfUiTm8XmJNO2zm9yC9P/2Gkrwg2dH9cxotQzunBHYr6jk4SujCTqnfGxduOmQcI7c2ryuW8XVg==} - cpu: [x64] - os: [linux] + '@radix-ui/react-presence@1.1.3': + resolution: {integrity: sha512-IrVLIhskYhH3nLvtcBLQFZr61tBG7wx7O3kEmdzcYwRGAEBmBicGGL7ATzNgruYJ3xBTbuzEEq9OXJM3PAX3tA==} + 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 - '@rollup/rollup-win32-arm64-msvc@4.35.0': - resolution: {integrity: sha512-OUOlGqPkVJCdJETKOCEf1mw848ZyJ5w50/rZ/3IBQVdLfR5jk/6Sr5m3iO2tdPgwo0x7VcncYuOvMhBWZq8ayg==} - cpu: [arm64] - os: [win32] + '@radix-ui/react-primitive@2.0.3': + resolution: {integrity: sha512-Pf/t/GkndH7CQ8wE2hbkXA+WyZ83fhQQn5DDmwDiDo6AwN/fhaH8oqZ0jRjMrO2iaMhDi6P1HRx6AZwyMinY1g==} + 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 - '@rollup/rollup-win32-ia32-msvc@4.35.0': - resolution: {integrity: sha512-2/lsgejMrtwQe44glq7AFFHLfJBPafpsTa6JvP2NGef/ifOa4KBoglVf7AKN7EV9o32evBPRqfg96fEHzWo5kw==} - cpu: [ia32] - os: [win32] + '@radix-ui/react-roving-focus@1.1.3': + resolution: {integrity: sha512-ufbpLUjZiOg4iYgb2hQrWXEPYX6jOLBbR27bDyAff5GYMRrCzcze8lukjuXVUQvJ6HZe8+oL+hhswDcjmcgVyg==} + 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 - '@rollup/rollup-win32-x64-msvc@4.35.0': - resolution: {integrity: sha512-PIQeY5XDkrOysbQblSW7v3l1MDZzkTEzAfTPkj5VAu3FW8fS4ynyLg2sINp0fp3SjZ8xkRYpLqoKcYqAkhU1dw==} - cpu: [x64] - os: [win32] + '@radix-ui/react-scroll-area@1.2.4': + resolution: {integrity: sha512-G9rdWTQjOR4sk76HwSdROhPU0jZWpfozn9skU1v4N0/g9k7TmswrJn8W8WMU+aYktnLLpk5LX6fofj2bGe5NFQ==} + 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 - '@shikijs/core@1.29.2': - resolution: {integrity: sha512-vju0lY9r27jJfOY4Z7+Rt/nIOjzJpZ3y+nYpqtUZInVoXQ/TJZcfGnNOGnKjFdVZb8qexiCuSlZRKcGfhhTTZQ==} + '@radix-ui/react-slot@1.2.0': + resolution: {integrity: sha512-ujc+V6r0HNDviYqIK3rW4ffgYiZ8g5DEHrGJVk4x7kTlLXRDILnKX9vAUYeIsLOoDpDJ0ujpqMkjH4w2ofuo6w==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true - '@shikijs/engine-javascript@1.29.2': - resolution: {integrity: sha512-iNEZv4IrLYPv64Q6k7EPpOCE/nuvGiKl7zxdq0WFuRPF5PAE9PRo2JGq/d8crLusM59BRemJ4eOqrFrC4wiQ+A==} + '@radix-ui/react-tabs@1.1.4': + resolution: {integrity: sha512-fuHMHWSf5SRhXke+DbHXj2wVMo+ghVH30vhX3XVacdXqDl+J4XWafMIGOOER861QpBx1jxgwKXL2dQnfrsd8MQ==} + 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 - '@shikijs/engine-oniguruma@1.29.2': - resolution: {integrity: sha512-7iiOx3SG8+g1MnlzZVDYiaeHe7Ez2Kf2HrJzdmGwkRisT7r4rak0e655AcM/tF9JG/kg5fMNYlLLKglbN7gBqA==} + '@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 - '@shikijs/langs@1.29.2': - resolution: {integrity: sha512-FIBA7N3LZ+223U7cJDUYd5shmciFQlYkFXlkKVaHsCPgfVLiO+e12FmQE6Tf9vuyEsFe3dIl8qGWKXgEHL9wmQ==} + '@radix-ui/react-use-controllable-state@1.1.1': + resolution: {integrity: sha512-YnEXIy8/ga01Y1PN0VfaNH//MhA91JlEGVBDxDzROqwrAtG5Yr2QGEPz8A/rJA3C7ZAHryOYGaUv8fLSW2H/mg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true - '@shikijs/themes@1.29.2': - resolution: {integrity: sha512-i9TNZlsq4uoyqSbluIcZkmPL9Bfi3djVxRnofUHwvx/h6SRW3cwgBC5SML7vsDcWyukY0eCzVN980rqP6qNl9g==} + '@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 - '@shikijs/types@1.29.2': - resolution: {integrity: sha512-VJjK0eIijTZf0QSTODEXCqinjBn0joAHQ+aPSBzrv4O2d/QSbsMw+ZeSRx03kV34Hy7NzUvV/7NqfYGRLrASmw==} + '@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-previous@1.1.1': + resolution: {integrity: sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==} + 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.1.3': + resolution: {integrity: sha512-oXSF3ZQRd5fvomd9hmUCb2EHSZbPp3ZSHAHJJU/DlF9XoFkJBBW8RHU/E8WEH+RbSfJd/QFA0sl8ClJXknBwHQ==} + 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==} + + '@rtsao/scc@1.1.0': + resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} + + '@rushstack/eslint-patch@1.11.0': + resolution: {integrity: sha512-zxnHvoMQVqewTJr/W4pKjF0bMGiKJv1WX7bSrkl46Hg0QjESbzBROWK0Wg4RphzSOS5Jiy7eFimmM3UgMrMZbQ==} + + '@shikijs/core@3.2.2': + resolution: {integrity: sha512-yvlSKVMLjddAGBa2Yu+vUZxuu3sClOWW1AG+UtJkvejYuGM5BVL35s6Ijiwb75O9QdEx6IkMxinHZSi8ZyrBaA==} + + '@shikijs/engine-javascript@3.2.2': + resolution: {integrity: sha512-tlDKfhWpF4jKLUyVAnmL+ggIC+0VyteNsUpBzh1iwWLZu4i+PelIRr0TNur6pRRo5UZIv3ss/PLMuwahg9S2hg==} + + '@shikijs/engine-oniguruma@3.2.2': + resolution: {integrity: sha512-vyXRnWVCSvokwbaUD/8uPn6Gqsf5Hv7XwcW4AgiU4Z2qwy19sdr6VGzMdheKKN58tJOOe5MIKiNb901bgcUXYQ==} + + '@shikijs/langs@3.2.2': + resolution: {integrity: sha512-NY0Urg2dV9ETt3JIOWoMPuoDNwte3geLZ4M1nrPHbkDS8dWMpKcEwlqiEIGqtwZNmt5gKyWpR26ln2Bg2ecPgw==} + + '@shikijs/rehype@3.2.2': + resolution: {integrity: sha512-Z/1crAoWBpQoUx/KSjiUM2eT91cjAhxMiInQ8gbgtWm2l2qQEIAWdSk6RJAINq+kl0+KO59QvcKWZHpKhCfXvw==} + + '@shikijs/themes@3.2.2': + resolution: {integrity: sha512-Zuq4lgAxVKkb0FFdhHSdDkALuRpsj1so1JdihjKNQfgM78EHxV2JhO10qPsMrm01FkE3mDRTdF68wfmsqjt6HA==} + + '@shikijs/transformers@3.2.2': + resolution: {integrity: sha512-DQvrPdygc6NNdbfeOZoO1+KiRnnjUQuuPLwsAbUuSKq4QFLD0Ik15FbHojmot5NbgCQRbVr8ufRg8U6X5rGWuQ==} + + '@shikijs/types@3.2.2': + resolution: {integrity: sha512-a5TiHk7EH5Lso8sHcLHbVNNhWKP0Wi3yVnXnu73g86n3WoDgEra7n3KszyeCGuyoagspQ2fzvy4cpSc8pKhb0A==} '@shikijs/vscode-textmate@10.0.2': resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==} - '@types/acorn@4.0.6': - resolution: {integrity: sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ==} + '@standard-schema/spec@1.0.0': + resolution: {integrity: sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==} - '@types/cookie@0.6.0': - resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==} + '@swc/counter@0.1.3': + resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} + + '@swc/helpers@0.5.15': + resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} + + '@tailwindcss/node@4.1.4': + resolution: {integrity: sha512-MT5118zaiO6x6hNA04OWInuAiP1YISXql8Z+/Y8iisV5nuhM8VXlyhRuqc2PEviPszcXI66W44bCIk500Oolhw==} + + '@tailwindcss/oxide-android-arm64@4.1.4': + resolution: {integrity: sha512-xMMAe/SaCN/vHfQYui3fqaBDEXMu22BVwQ33veLc8ep+DNy7CWN52L+TTG9y1K397w9nkzv+Mw+mZWISiqhmlA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [android] + + '@tailwindcss/oxide-darwin-arm64@4.1.4': + resolution: {integrity: sha512-JGRj0SYFuDuAGilWFBlshcexev2hOKfNkoX+0QTksKYq2zgF9VY/vVMq9m8IObYnLna0Xlg+ytCi2FN2rOL0Sg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + + '@tailwindcss/oxide-darwin-x64@4.1.4': + resolution: {integrity: sha512-sdDeLNvs3cYeWsEJ4H1DvjOzaGios4QbBTNLVLVs0XQ0V95bffT3+scptzYGPMjm7xv4+qMhCDrkHwhnUySEzA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + '@tailwindcss/oxide-freebsd-x64@4.1.4': + resolution: {integrity: sha512-VHxAqxqdghM83HslPhRsNhHo91McsxRJaEnShJOMu8mHmEj9Ig7ToHJtDukkuLWLzLboh2XSjq/0zO6wgvykNA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [freebsd] + + '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.4': + resolution: {integrity: sha512-OTU/m/eV4gQKxy9r5acuesqaymyeSCnsx1cFto/I1WhPmi5HDxX1nkzb8KYBiwkHIGg7CTfo/AcGzoXAJBxLfg==} + engines: {node: '>= 10'} + cpu: [arm] + os: [linux] + + '@tailwindcss/oxide-linux-arm64-gnu@4.1.4': + resolution: {integrity: sha512-hKlLNvbmUC6z5g/J4H+Zx7f7w15whSVImokLPmP6ff1QqTVE+TxUM9PGuNsjHvkvlHUtGTdDnOvGNSEUiXI1Ww==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@tailwindcss/oxide-linux-arm64-musl@4.1.4': + resolution: {integrity: sha512-X3As2xhtgPTY/m5edUtddmZ8rCruvBvtxYLMw9OsZdH01L2gS2icsHRwxdU0dMItNfVmrBezueXZCHxVeeb7Aw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@tailwindcss/oxide-linux-x64-gnu@4.1.4': + resolution: {integrity: sha512-2VG4DqhGaDSmYIu6C4ua2vSLXnJsb/C9liej7TuSO04NK+JJJgJucDUgmX6sn7Gw3Cs5ZJ9ZLrnI0QRDOjLfNQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@tailwindcss/oxide-linux-x64-musl@4.1.4': + resolution: {integrity: sha512-v+mxVgH2kmur/X5Mdrz9m7TsoVjbdYQT0b4Z+dr+I4RvreCNXyCFELZL/DO0M1RsidZTrm6O1eMnV6zlgEzTMQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@tailwindcss/oxide-wasm32-wasi@4.1.4': + resolution: {integrity: sha512-2TLe9ir+9esCf6Wm+lLWTMbgklIjiF0pbmDnwmhR9MksVOq+e8aP3TSsXySnBDDvTTVd/vKu1aNttEGj3P6l8Q==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + bundledDependencies: + - '@napi-rs/wasm-runtime' + - '@emnapi/core' + - '@emnapi/runtime' + - '@tybys/wasm-util' + - '@emnapi/wasi-threads' + - tslib + + '@tailwindcss/oxide-win32-arm64-msvc@4.1.4': + resolution: {integrity: sha512-VlnhfilPlO0ltxW9/BgfLI5547PYzqBMPIzRrk4W7uupgCt8z6Trw/tAj6QUtF2om+1MH281Pg+HHUJoLesmng==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + + '@tailwindcss/oxide-win32-x64-msvc@4.1.4': + resolution: {integrity: sha512-+7S63t5zhYjslUGb8NcgLpFXD+Kq1F/zt5Xv5qTv7HaFTG/DHyHD9GA6ieNAxhgyA4IcKa/zy7Xx4Oad2/wuhw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + + '@tailwindcss/oxide@4.1.4': + resolution: {integrity: sha512-p5wOpXyOJx7mKh5MXh5oKk+kqcz8T+bA3z/5VWWeQwFrmuBItGwz8Y2CHk/sJ+dNb9B0nYFfn0rj/cKHZyjahQ==} + engines: {node: '>= 10'} + + '@tailwindcss/postcss@4.1.4': + resolution: {integrity: sha512-bjV6sqycCEa+AQSt2Kr7wpGF1bOZJ5wsqnLEkqSbM/JEHxx/yhMH8wHmdkPyApF9xhHeMSwnnkDUUMMM/hYnXw==} + + '@tybys/wasm-util@0.9.0': + resolution: {integrity: sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==} '@types/debug@4.1.12': resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} @@ -520,14 +966,14 @@ packages: '@types/estree-jsx@1.0.5': resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==} - '@types/estree@1.0.6': - resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} + '@types/estree@1.0.7': + resolution: {integrity: sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==} '@types/hast@3.0.4': resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} - '@types/js-yaml@4.0.9': - resolution: {integrity: sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==} + '@types/json5@0.0.29': + resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} '@types/mdast@4.0.4': resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} @@ -538,14 +984,16 @@ packages: '@types/ms@2.1.0': resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} - '@types/nlcst@2.0.3': - resolution: {integrity: sha512-vSYNSDe6Ix3q+6Z7ri9lyWqgGhJTmzRjZRqyq15N0Z/1/UnVsno9G/N40NBijoYx2seFDIl0+B2mgAb9mezUCA==} + '@types/node@22.14.0': + resolution: {integrity: sha512-Kmpl+z84ILoG+3T/zQFyAJsU6EPTmOCj8/2+83fSN6djd6I4o7uOuGIH6vq3PrjY5BGitSbFuMN18j3iknubbA==} - '@types/node@17.0.45': - resolution: {integrity: sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==} + '@types/react-dom@19.1.2': + resolution: {integrity: sha512-XGJkWF41Qq305SKWEILa1O8vzhb3aOo3ogBlSmiqNko/WmRb6QIaweuZCXjKygVDXpzXb5wyxKTSOsmkuqj+Qw==} + peerDependencies: + '@types/react': ^19.0.0 - '@types/sax@1.2.7': - resolution: {integrity: sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==} + '@types/react@19.1.2': + resolution: {integrity: sha512-oxLPMytKchWGbnQM9O7D67uPa9paTNxO7jVoNMXgkkErULBPhPARCfkKL9ytcIJJRGjbsVwW4ugJzyFFvm/Tiw==} '@types/unist@2.0.11': resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} @@ -553,9 +1001,136 @@ packages: '@types/unist@3.0.3': resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + '@typescript-eslint/eslint-plugin@8.30.1': + resolution: {integrity: sha512-v+VWphxMjn+1t48/jO4t950D6KR8JaJuNXzi33Ve6P8sEmPr5k6CEXjdGwT6+LodVnEa91EQCtwjWNUCPweo+Q==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0 + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <5.9.0' + + '@typescript-eslint/parser@8.30.1': + resolution: {integrity: sha512-H+vqmWwT5xoNrXqWs/fesmssOW70gxFlgcMlYcBaWNPIEWDgLa4W9nkSPmhuOgLnXq9QYgkZ31fhDyLhleCsAg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <5.9.0' + + '@typescript-eslint/scope-manager@8.30.1': + resolution: {integrity: sha512-+C0B6ChFXZkuaNDl73FJxRYT0G7ufVPOSQkqkpM/U198wUwUFOtgo1k/QzFh1KjpBitaK7R1tgjVz6o9HmsRPg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/type-utils@8.30.1': + resolution: {integrity: sha512-64uBF76bfQiJyHgZISC7vcNz3adqQKIccVoKubyQcOnNcdJBvYOILV1v22Qhsw3tw3VQu5ll8ND6hycgAR5fEA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <5.9.0' + + '@typescript-eslint/types@8.30.1': + resolution: {integrity: sha512-81KawPfkuulyWo5QdyG/LOKbspyyiW+p4vpn4bYO7DM/hZImlVnFwrpCTnmNMOt8CvLRr5ojI9nU1Ekpw4RcEw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/typescript-estree@8.30.1': + resolution: {integrity: sha512-kQQnxymiUy9tTb1F2uep9W6aBiYODgq5EMSk6Nxh4Z+BDUoYUSa029ISs5zTzKBFnexQEh71KqwjKnRz58lusQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <5.9.0' + + '@typescript-eslint/utils@8.30.1': + resolution: {integrity: sha512-T/8q4R9En2tcEsWPQgB5BQ0XJVOtfARcUvOa8yJP3fh9M/mXraLxZrkCfGb6ChrO/V3W+Xbd04RacUEqk1CFEQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <5.9.0' + + '@typescript-eslint/visitor-keys@8.30.1': + resolution: {integrity: sha512-aEhgas7aJ6vZnNFC7K4/vMGDGyOiqWcYZPpIWrTKuTAlsvDNKy2GFDqh9smL+iq069ZvR0YzEeq0B8NJlLzjFA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@ungap/structured-clone@1.3.0': resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} + '@unrs/resolver-binding-darwin-arm64@1.5.0': + resolution: {integrity: sha512-YmocNlEcX/AgJv8gI41bhjMOTcKcea4D2nRIbZj+MhRtSH5+vEU8r/pFuTuoF+JjVplLsBueU+CILfBPVISyGQ==} + cpu: [arm64] + os: [darwin] + + '@unrs/resolver-binding-darwin-x64@1.5.0': + resolution: {integrity: sha512-qpUrXgH4e/0xu1LOhPEdfgSY3vIXOxDQv370NEL8npN8h40HcQDA+Pl2r4HBW6tTXezWIjxUFcP7tj529RZtDw==} + cpu: [x64] + os: [darwin] + + '@unrs/resolver-binding-freebsd-x64@1.5.0': + resolution: {integrity: sha512-3tX8r8vgjvZzaJZB4jvxUaaFCDCb3aWDCpZN3EjhGnnwhztslI05KSG5NY/jNjlcZ5QWZ7dEZZ/rNBFsmTaSPw==} + cpu: [x64] + os: [freebsd] + + '@unrs/resolver-binding-linux-arm-gnueabihf@1.5.0': + resolution: {integrity: sha512-FH+ixzBKaUU9fWOj3TYO+Yn/eO6kYvMLV9eNJlJlkU7OgrxkCmiMS6wUbyT0KA3FOZGxnEQ2z3/BHgYm2jqeLA==} + cpu: [arm] + os: [linux] + + '@unrs/resolver-binding-linux-arm-musleabihf@1.5.0': + resolution: {integrity: sha512-pxCgXMgwB/4PfqFQg73lMhmWwcC0j5L+dNXhZoz/0ek0iS/oAWl65fxZeT/OnU7fVs52MgdP2q02EipqJJXHSg==} + cpu: [arm] + os: [linux] + + '@unrs/resolver-binding-linux-arm64-gnu@1.5.0': + resolution: {integrity: sha512-FX2FV7vpLE/+Z0NZX9/1pwWud5Wocm/2PgpUXbT5aSV3QEB10kBPJAzssOQylvdj8mOHoKl5pVkXpbCwww/T2g==} + cpu: [arm64] + os: [linux] + + '@unrs/resolver-binding-linux-arm64-musl@1.5.0': + resolution: {integrity: sha512-+gF97xst1BZb28T3nwwzEtq2ewCoMDGKsenYsZuvpmNrW0019G1iUAunZN+FG55L21y+uP7zsGX06OXDQ/viKw==} + cpu: [arm64] + os: [linux] + + '@unrs/resolver-binding-linux-ppc64-gnu@1.5.0': + resolution: {integrity: sha512-5bEmVcQw9js8JYM2LkUBw5SeELSIxX+qKf9bFrfFINKAp4noZ//hUxLpbF7u/3gTBN1GsER6xOzIZlw/VTdXtA==} + cpu: [ppc64] + os: [linux] + + '@unrs/resolver-binding-linux-riscv64-gnu@1.5.0': + resolution: {integrity: sha512-GGk/8TPUsf1Q99F+lzMdjE6sGL26uJCwQ9TlvBs8zR3cLQNw/MIumPN7zrs3GFGySjnwXc8gA6J3HKbejywmqA==} + cpu: [riscv64] + os: [linux] + + '@unrs/resolver-binding-linux-s390x-gnu@1.5.0': + resolution: {integrity: sha512-5uRkFYYVNAeVaA4W/CwugjFN3iDOHCPqsBLCCOoJiMfFMMz4evBRsg+498OFa9w6VcTn2bD5aI+RRayaIgk2Sw==} + cpu: [s390x] + os: [linux] + + '@unrs/resolver-binding-linux-x64-gnu@1.5.0': + resolution: {integrity: sha512-j905CZH3nehYy6NimNqC2B14pxn4Ltd7guKMyPTzKehbFXTUgihQS/ZfHQTdojkMzbSwBOSgq1dOrY+IpgxDsA==} + cpu: [x64] + os: [linux] + + '@unrs/resolver-binding-linux-x64-musl@1.5.0': + resolution: {integrity: sha512-dmLevQTuzQRwu5A+mvj54R5aye5I4PVKiWqGxg8tTaYP2k2oTs/3Mo8mgnhPk28VoYCi0fdFYpgzCd4AJndQvQ==} + cpu: [x64] + os: [linux] + + '@unrs/resolver-binding-wasm32-wasi@1.5.0': + resolution: {integrity: sha512-LtJMhwu7avhoi+kKfAZOKN773RtzLBVVF90YJbB0wyMpUj9yQPeA+mteVUI9P70OG/opH47FeV5AWeaNWWgqJg==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@unrs/resolver-binding-win32-arm64-msvc@1.5.0': + resolution: {integrity: sha512-FTZBxLL4SO1mgIM86KykzJmPeTPisBDHQV6xtfDXbTMrentuZ6SdQKJUV5BWaoUK3p8kIULlrCcucqdCnk8Npg==} + cpu: [arm64] + os: [win32] + + '@unrs/resolver-binding-win32-ia32-msvc@1.5.0': + resolution: {integrity: sha512-i5bB7vJ1waUsFciU/FKLd4Zw0VnAkvhiJ4//jYQXyDUuiLKodmtQZVTcOPU7pp97RrNgCFtXfC1gnvj/DHPJTw==} + cpu: [ia32] + os: [win32] + + '@unrs/resolver-binding-win32-x64-msvc@1.5.0': + resolution: {integrity: sha512-wAvXp4k7jhioi4SebXW/yfzzYwsUCr9kIX4gCsUFKpCTUf8Mi7vScJXI3S+kupSUf0LbVHudR8qBbe2wFMSNUw==} + cpu: [x64] + os: [win32] + acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: @@ -566,122 +1141,131 @@ packages: engines: {node: '>=0.4.0'} hasBin: true - ansi-align@3.0.1: - resolution: {integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==} + ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} - ansi-regex@6.1.0: - resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} - engines: {node: '>=12'} + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} - ansi-styles@6.2.1: - resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} - engines: {node: '>=12'} - - anymatch@3.1.3: - resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} - engines: {node: '>= 8'} - - arg@5.0.2: - resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} + argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + aria-hidden@1.2.4: + resolution: {integrity: sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==} + engines: {node: '>=10'} + aria-query@5.3.2: resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} engines: {node: '>= 0.4'} - array-iterate@2.0.1: - resolution: {integrity: sha512-I1jXZMjAgCMmxT4qxXfPXa6SthSoE8h6gkSI9BGGNv8mP8G/v0blc+qFnZu6K42vTOiuME596QaLO0TP3Lk0xg==} + array-buffer-byte-length@1.0.2: + resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} + engines: {node: '>= 0.4'} + + array-includes@3.1.8: + resolution: {integrity: sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==} + engines: {node: '>= 0.4'} + + array.prototype.findlast@1.2.5: + resolution: {integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==} + engines: {node: '>= 0.4'} + + array.prototype.findlastindex@1.2.6: + resolution: {integrity: sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==} + engines: {node: '>= 0.4'} + + array.prototype.flat@1.3.3: + resolution: {integrity: sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==} + engines: {node: '>= 0.4'} + + array.prototype.flatmap@1.3.3: + resolution: {integrity: sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==} + engines: {node: '>= 0.4'} + + array.prototype.tosorted@1.1.4: + resolution: {integrity: sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==} + engines: {node: '>= 0.4'} + + arraybuffer.prototype.slice@1.0.4: + resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} + engines: {node: '>= 0.4'} + + ast-types-flow@0.0.8: + resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==} astring@1.9.0: resolution: {integrity: sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==} hasBin: true - astro-expressive-code@0.40.2: - resolution: {integrity: sha512-yJMQId0yXSAbW9I6yqvJ3FcjKzJ8zRL7elbJbllkv1ZJPlsI0NI83Pxn1YL1IapEM347EvOOkSW2GL+2+NO61w==} - peerDependencies: - astro: ^4.0.0-beta || ^5.0.0-beta || ^3.3.0 + async-function@1.0.0: + resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} + engines: {node: '>= 0.4'} - astro@5.5.2: - resolution: {integrity: sha512-SOTJxB8mqxe/KEYEJiLIot0YULiCffyfTEclwmdeaASitDJ7eLM/KYrJ9sx3U5hq9GVI17Z4Y0P/1T2aQ0ZN3A==} - engines: {node: ^18.17.1 || ^20.3.0 || >=22.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0'} - hasBin: true + available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + + axe-core@4.10.3: + resolution: {integrity: sha512-Xm7bpRXnDSX2YE2YFfBk2FnF0ep6tmG7xPh8iHee8MIcrgq762Nkce856dYtJYLkuIoYZvGfTs/PbZhideTcEg==} + engines: {node: '>=4'} axobject-query@4.1.0: resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} engines: {node: '>= 0.4'} - b4a@1.6.7: - resolution: {integrity: sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==} - bail@2.0.2: resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} - bare-events@2.5.4: - resolution: {integrity: sha512-+gFfDkR8pj4/TrWCGUGWmJIkBwuxPS5F+a5yWjOHQt2hHvNZd5YLzadjmDUtFmMM4y429bnKLa8bYBMHcYdnQA==} + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - bare-fs@4.0.1: - resolution: {integrity: sha512-ilQs4fm/l9eMfWY2dY0WCIUplSUp7U0CT1vrqMg1MUdeZl4fypu5UP0XcDBK5WBQPJAKP1b7XEodISmekH/CEg==} - engines: {bare: '>=1.7.0'} + brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} - bare-os@3.6.0: - resolution: {integrity: sha512-BUrFS5TqSBdA0LwHop4OjPJwisqxGy6JsWVqV6qaFoe965qqtaKfDzHY5T2YA1gUL0ZeeQeA+4BBc1FJTcHiPw==} - engines: {bare: '>=1.14.0'} + brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} - bare-path@3.0.0: - resolution: {integrity: sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==} + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} - bare-stream@2.6.5: - resolution: {integrity: sha512-jSmxKJNJmHySi6hC42zlZnq00rga4jjxcgNZjY9N5WlOe/iOoGRtdwGsHzQv2RlH2KOYMwGUXhf2zXd32BA9RA==} - peerDependencies: - bare-buffer: '*' - bare-events: '*' - peerDependenciesMeta: - bare-buffer: - optional: true - bare-events: - optional: true + busboy@1.6.0: + resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} + engines: {node: '>=10.16.0'} - base-64@1.0.0: - resolution: {integrity: sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg==} + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} - base64-js@1.5.1: - resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + call-bind@1.0.8: + resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==} + engines: {node: '>= 0.4'} - bcp-47-match@2.0.3: - resolution: {integrity: sha512-JtTezzbAibu8G0R9op9zb3vcWZd9JF6M0xOYGPn0fNCd7wOpRB1mU2mH9T8gaBGbAAyIIVgB2G7xG0GP98zMAQ==} + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} - bcp-47@2.1.0: - resolution: {integrity: sha512-9IIS3UPrvIa1Ej+lVDdDwO7zLehjqsaByECw0bu2RRGP73jALm6FYbzI5gWbgHLvNdkvfXB5YrSbocZdOS0c0w==} + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} - bl@4.1.0: - resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} - - boolbase@1.0.0: - resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} - - boxen@8.0.1: - resolution: {integrity: sha512-F3PH5k5juxom4xktynS7MoFY+NUWH5LC4CnH11YB8NPew+HLpmBLCybSAEyb2F+4pRXhuhWqFesoQd6DAyc2hw==} - engines: {node: '>=18'} - - buffer@5.7.1: - resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} - - camelcase@8.0.0: - resolution: {integrity: sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==} - engines: {node: '>=16'} + caniuse-lite@1.0.30001714: + resolution: {integrity: sha512-mtgapdwDLSSBnCI3JokHM7oEQBLxiJKVRtg10AxM1AyeiKcM96f0Mkbqeq+1AbiCtvMcHRulAAEMu693JrSWqg==} ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} - chalk@5.4.1: - resolution: {integrity: sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==} - engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} character-entities-html4@2.1.0: resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} @@ -699,16 +1283,11 @@ packages: resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} engines: {node: '>= 14.16.0'} - chownr@1.1.4: - resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} + class-variance-authority@0.7.1: + resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==} - ci-info@4.2.0: - resolution: {integrity: sha512-cYY9mypksY8NRqgDB1XD1RiJL338v/551niynFTGkZOO2LHuB2OmOYxDIe/ttN9AHwrqdum1360G3ald0W9kCg==} - engines: {node: '>=8'} - - cli-boxes@3.0.0: - resolution: {integrity: sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==} - engines: {node: '>=10'} + client-only@0.0.1: + resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} clsx@2.1.1: resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} @@ -734,27 +1313,47 @@ packages: comma-separated-tokens@2.0.3: resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} - common-ancestor-path@1.0.1: - resolution: {integrity: sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w==} + compute-scroll-into-view@3.1.1: + resolution: {integrity: sha512-VRhuHOLoKYOy4UbilLbUzbYg93XLjv2PncJC50EuTWPA3gaja1UjBsUP/D/9/juV3vQFr6XBEzn9KCAHdUvOHw==} - cookie-es@1.2.2: - resolution: {integrity: sha512-+W7VmiVINB+ywl1HGXJXmrqkOhpKrIiVZV6tQuV54ZyQC7MMuBt81Vc336GMLoHBq5hV/F9eXgt5Mnx0Rha5Fg==} + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - cookie@0.7.2: - resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} - engines: {node: '>= 0.6'} - - crossws@0.3.4: - resolution: {integrity: sha512-uj0O1ETYX1Bh6uSgktfPvwDiPYGQ3aI4qVsaC/LWpkIzGj1nUYm5FK3K+t11oOlpN01lGbprFCH4wBlKdJjVgw==} - - css-selector-parser@3.0.5: - resolution: {integrity: sha512-3itoDFbKUNx1eKmVpYMFyqKX04Ww9osZ+dLgrk6GEv6KMVeXUhUnp4I5X+evw+u3ZxVU6RFXSSRxlTeMh8bA+g==} + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} cssesc@3.0.0: resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} engines: {node: '>=4'} hasBin: true + csstype@3.1.3: + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + + damerau-levenshtein@1.0.8: + resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} + + data-view-buffer@1.0.2: + resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==} + engines: {node: '>= 0.4'} + + data-view-byte-length@1.0.2: + resolution: {integrity: sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==} + engines: {node: '>= 0.4'} + + data-view-byte-offset@1.0.1: + resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} + engines: {node: '>= 0.4'} + + debug@3.2.7: + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + debug@4.4.0: resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==} engines: {node: '>=6.0'} @@ -767,71 +1366,84 @@ packages: decode-named-character-reference@1.1.0: resolution: {integrity: sha512-Wy+JTSbFThEOXQIR2L6mxJvEs+veIzpmqD7ynWxMXGpnk3smkHQOp6forLdHsKpAMW9iJpaBBIxz285t1n1C3w==} - decompress-response@6.0.0: - resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} - engines: {node: '>=10'} + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} - deep-extend@0.6.0: - resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} - engines: {node: '>=4.0.0'} + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} - defu@6.1.4: - resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} + define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} dequal@2.0.3: resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} engines: {node: '>=6'} - destr@2.0.3: - resolution: {integrity: sha512-2N3BOUU4gYMpTP24s5rF5iP7BDr7uNTCs4ozw3kf/eKfvWSIu93GEBi5m427YoyJoeOzQ5smuu4nNAPGb8idSQ==} - detect-libc@2.0.3: resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==} engines: {node: '>=8'} - deterministic-object-hash@2.0.2: - resolution: {integrity: sha512-KxektNH63SrbfUyDiwXqRb1rLwKt33AmMv+5Nhsw1kqZ13SJBRTgZHtGbE+hH3a1mVW1cz+4pqSWVPAtLVXTzQ==} - engines: {node: '>=18'} - - devalue@5.1.1: - resolution: {integrity: sha512-maua5KUiapvEwiEAe+XnlZ3Rh0GD+qI1J/nb9vrJc3muPXvcF/8gXYTWF76+5DAqHyDUtOIImEuo0YKE9mshVw==} + detect-node-es@1.1.0: + resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} devlop@1.1.0: resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} - diff@5.2.0: - resolution: {integrity: sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==} - engines: {node: '>=0.3.1'} + doctrine@2.1.0: + resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} + engines: {node: '>=0.10.0'} - direction@2.0.1: - resolution: {integrity: sha512-9S6m9Sukh1cZNknO1CWAr2QAWsbKLafQiyM5gZ7VgXHeuaoUwffKN4q6NC4A/Mf9iiPlOXQEKW/Mv/mh9/3YFA==} - hasBin: true + doctrine@3.0.0: + resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} + engines: {node: '>=6.0.0'} - dlv@1.1.3: - resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} - - dset@3.1.4: - resolution: {integrity: sha512-2QF/g9/zTaPDc3BjNcVTGoBbXBgYfMTTceLaYcFJ/W9kggFUkhxD/hMEeuLKbugyef9SqAx8cpgwlIP/jinUTA==} - engines: {node: '>=4'} + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} emoji-regex-xs@1.0.0: resolution: {integrity: sha512-LRlerrMYoIDrT6jgpeZ2YYl/L8EulRTt5hQcYjy5AInh7HWXKimpqx68aknBFpGL2+/IcogTcaydJEgaTmOpDg==} - emoji-regex@10.4.0: - resolution: {integrity: sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==} + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} - emoji-regex@8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + enhanced-resolve@5.18.1: + resolution: {integrity: sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==} + engines: {node: '>=10.13.0'} - end-of-stream@1.4.4: - resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} + es-abstract@1.23.9: + resolution: {integrity: sha512-py07lI0wjxAC/DcfK1S6G7iANonniZwTISvdPzk9hzeH0IZIshbuuFxLIU96OyF89Yb9hiqWn8M/bY83KY5vzA==} + engines: {node: '>= 0.4'} - entities@4.5.0: - resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} - engines: {node: '>=0.12'} + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} - es-module-lexer@1.6.0: - resolution: {integrity: sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==} + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-iterator-helpers@1.2.1: + resolution: {integrity: sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==} + engines: {node: '>= 0.4'} + + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} + engines: {node: '>= 0.4'} + + es-shim-unscopables@1.1.0: + resolution: {integrity: sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==} + engines: {node: '>= 0.4'} + + es-to-primitive@1.3.0: + resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} + engines: {node: '>= 0.4'} esast-util-from-estree@2.0.0: resolution: {integrity: sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ==} @@ -839,15 +1451,132 @@ packages: esast-util-from-js@2.0.1: resolution: {integrity: sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw==} - esbuild@0.25.1: - resolution: {integrity: sha512-BGO5LtrGC7vxnqucAe/rmvKdJllfGaYWdyABvyMoXQlfYMb2bbRuReWR5tEGE//4LcNJj9XrkovTqNYRFZHAMQ==} + esbuild@0.25.2: + resolution: {integrity: sha512-16854zccKPnC+toMywC+uKNeYSv+/eXkevRAfwRD/G9Cleq66m8XFIrigkbvauLLlCfDL45Q2cWegSg53gGBnQ==} engines: {node: '>=18'} hasBin: true + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + escape-string-regexp@5.0.0: resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} engines: {node: '>=12'} + eslint-config-next@15.3.0: + resolution: {integrity: sha512-+Z3M1W9MnJjX3W4vI9CHfKlEyhTWOUHvc5dB89FyRnzPsUkJlLWZOi8+1pInuVcSztSM4MwBFB0hIHf4Rbwu4g==} + peerDependencies: + eslint: ^7.23.0 || ^8.0.0 || ^9.0.0 + typescript: '>=3.3.1' + peerDependenciesMeta: + typescript: + optional: true + + eslint-import-resolver-node@0.3.9: + resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} + + eslint-import-resolver-typescript@3.10.0: + resolution: {integrity: sha512-aV3/dVsT0/H9BtpNwbaqvl+0xGMRGzncLyhm793NFGvbwGGvzyAykqWZ8oZlZuGwuHkwJjhWJkG1cM3ynvd2pQ==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + eslint: '*' + eslint-plugin-import: '*' + eslint-plugin-import-x: '*' + peerDependenciesMeta: + eslint-plugin-import: + optional: true + eslint-plugin-import-x: + optional: true + + eslint-module-utils@2.12.0: + resolution: {integrity: sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: '*' + eslint-import-resolver-node: '*' + eslint-import-resolver-typescript: '*' + eslint-import-resolver-webpack: '*' + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + eslint: + optional: true + eslint-import-resolver-node: + optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true + + eslint-plugin-import@2.31.0: + resolution: {integrity: sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + + eslint-plugin-jsx-a11y@6.10.2: + resolution: {integrity: sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==} + engines: {node: '>=4.0'} + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9 + + eslint-plugin-react-hooks@5.2.0: + resolution: {integrity: sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==} + engines: {node: '>=10'} + peerDependencies: + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 + + eslint-plugin-react@7.37.5: + resolution: {integrity: sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==} + engines: {node: '>=4'} + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7 + + eslint-scope@7.2.2: + resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@4.2.0: + resolution: {integrity: sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint@8.57.1: + resolution: {integrity: sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. + hasBin: true + + espree@9.6.1: + resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + + esquery@1.6.0: + resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + estree-util-attach-comments@3.0.0: resolution: {integrity: sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==} @@ -863,30 +1592,45 @@ packages: estree-util-to-js@2.0.0: resolution: {integrity: sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==} + estree-util-value-to-estree@3.3.3: + resolution: {integrity: sha512-Db+m1WSD4+mUO7UgMeKkAwdbfNWwIxLt48XF2oFU9emPfXkIu+k5/nlOj313v7wqtAPo0f9REhUvznFrPkG8CQ==} + estree-util-visit@2.0.0: resolution: {integrity: sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==} - estree-walker@2.0.2: - resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} - estree-walker@3.0.3: resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} - eventemitter3@5.0.1: - resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} - expand-template@2.0.3: - resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} - engines: {node: '>=6'} - - expressive-code@0.40.2: - resolution: {integrity: sha512-1zIda2rB0qiDZACawzw2rbdBQiWHBT56uBctS+ezFe5XMAaFaHLnnSYND/Kd+dVzO9HfCXRDpzH3d+3fvOWRcw==} + extend-shallow@2.0.1: + resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} + engines: {node: '>=0.10.0'} extend@3.0.2: resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} - fast-fifo@1.3.2: - resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==} + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-glob@3.3.1: + resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==} + engines: {node: '>=8.6.0'} + + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} + engines: {node: '>=8.6.0'} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + + fastq@1.19.1: + resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} fdir@6.4.3: resolution: {integrity: sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw==} @@ -896,66 +1640,180 @@ packages: picomatch: optional: true - flattie@1.1.1: - resolution: {integrity: sha512-9UbaD6XdAL97+k/n+N7JwX46K/M6Zc6KcFYskrYL8wbBV/Uyk0CTAMY0VT+qiK5PM7AIc9aTWYtq65U7T+aCNQ==} + file-entry-cache@6.0.1: + resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} + engines: {node: ^10.12.0 || >=12.0.0} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} - fs-constants@1.0.0: - resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} - fsevents@2.3.3: - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] + flat-cache@3.2.0: + resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} + engines: {node: ^10.12.0 || >=12.0.0} - get-east-asian-width@1.3.0: - resolution: {integrity: sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ==} - engines: {node: '>=18'} + flatted@3.3.3: + resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} - github-from-package@0.0.0: - resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==} + for-each@0.3.5: + resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} + engines: {node: '>= 0.4'} + + framer-motion@12.9.1: + resolution: {integrity: sha512-dZBp2TO0a39Cc24opshlLoM0/OdTZVKzcXWuhntfwy2Qgz3t9+N4sTyUqNANyHaRFiJUWbwwsXeDvQkEBPky+g==} + peerDependencies: + '@emotion/is-prop-valid': '*' + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@emotion/is-prop-valid': + optional: true + react: + optional: true + react-dom: + optional: true + + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + + fumadocs-core@15.2.7: + resolution: {integrity: sha512-uPMOlU+W4nT+qg1hyr8QBI+tMMpDys7QtIWWKFBhZFnVYCHPGuYKykSn5MbCkVkRH5HW3KMpm6zThAWk7gLCjQ==} + peerDependencies: + '@oramacloud/client': 1.x.x || 2.x.x + algoliasearch: 4.24.0 + next: 14.x.x || 15.x.x + react: 18.x.x || 19.x.x + react-dom: 18.x.x || 19.x.x + peerDependenciesMeta: + '@oramacloud/client': + optional: true + algoliasearch: + optional: true + next: + optional: true + react: + optional: true + react-dom: + optional: true + + fumadocs-mdx@11.6.0: + resolution: {integrity: sha512-g0mArgliPBcZgi4691lwTCIw52y2BbxwIila7a6fQ6AEcu236uiBsDHWT4dm+xyjR3S84MlYkty9z2BWVTTNhg==} + hasBin: true + peerDependencies: + '@fumadocs/mdx-remote': ^1.2.0 + fumadocs-core: ^14.0.0 || ^15.0.0 + next: ^15.3.0 + peerDependenciesMeta: + '@fumadocs/mdx-remote': + optional: true + + fumadocs-ui@15.2.7: + resolution: {integrity: sha512-sixoRJdXW2ZyIG0DnuNLbv4Ov4xxu0H2A60una62TJ2uLrxIwFiFq2FfzhmZlT1EK0Gg9pzl2zM4QlFDdLKGjA==} + peerDependencies: + next: 14.x.x || 15.x.x + react: 18.x.x || 19.x.x + react-dom: 18.x.x || 19.x.x + tailwindcss: ^3.4.14 || ^4.0.0 + peerDependenciesMeta: + tailwindcss: + optional: true + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + function.prototype.name@1.1.8: + resolution: {integrity: sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==} + engines: {node: '>= 0.4'} + + functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-nonce@1.0.1: + resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} + engines: {node: '>=6'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + get-symbol-description@1.1.0: + resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} + engines: {node: '>= 0.4'} + + get-tsconfig@4.10.0: + resolution: {integrity: sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A==} github-slugger@2.0.0: resolution: {integrity: sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==} - h3@1.15.1: - resolution: {integrity: sha512-+ORaOBttdUm1E2Uu/obAyCguiI7MbBvsLTndc3gyK3zU+SYLoZXlyCP9Xgy0gikkGufFLTZXCXD6+4BsufnmHA==} + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} - hast-util-embedded@3.0.0: - resolution: {integrity: sha512-naH8sld4Pe2ep03qqULEtvYr7EjrLK2QHY8KJR6RJkTUjPGObe1vnx585uzem2hGra+s1q08DZZpfgDVYRbaXA==} + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} - hast-util-format@1.1.0: - resolution: {integrity: sha512-yY1UDz6bC9rDvCWHpx12aIBGRG7krurX0p0Fm6pT547LwDIZZiNr8a+IHDogorAdreULSEzP82Nlv5SZkHZcjA==} + glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Glob versions prior to v9 are no longer supported - hast-util-from-html@2.0.3: - resolution: {integrity: sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw==} + globals@13.24.0: + resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} + engines: {node: '>=8'} - hast-util-from-parse5@8.0.3: - resolution: {integrity: sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==} + globalthis@1.0.4: + resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} + engines: {node: '>= 0.4'} - hast-util-has-property@3.0.0: - resolution: {integrity: sha512-MNilsvEKLFpV604hwfhVStK0usFY/QmM5zX16bo7EjnAEGofr5YyI37kzopBlZJkHD4t887i+q/C8/tr5Q94cA==} + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} - hast-util-is-body-ok-link@3.0.1: - resolution: {integrity: sha512-0qpnzOBLztXHbHQenVB8uNuxTnm/QBFUOmdOSsEn7GnBtyY07+ENTWVFBAnXd/zEgd9/SUG3lRY7hSIBWRgGpQ==} + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} - hast-util-is-element@3.0.0: - resolution: {integrity: sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==} + graphemer@1.4.0: + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} - hast-util-minify-whitespace@1.0.1: - resolution: {integrity: sha512-L96fPOVpnclQE0xzdWb/D12VT5FabA7SnZOUMtL1DbXmYiHJMXZvFkIZfiMmTCNJHUeO2K9UYNXoVyfz+QHuOw==} + gray-matter@4.0.3: + resolution: {integrity: sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==} + engines: {node: '>=6.0'} - hast-util-parse-selector@4.0.0: - resolution: {integrity: sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==} + has-bigints@1.1.0: + resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} + engines: {node: '>= 0.4'} - hast-util-phrasing@3.0.1: - resolution: {integrity: sha512-6h60VfI3uBQUxHqTyMymMZnEbNl1XmEGtOxxKYL7stY2o601COo62AWAYBQR9lZbYXYSBoxag8UpPRXK+9fqSQ==} + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} - hast-util-raw@9.1.0: - resolution: {integrity: sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==} + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} - hast-util-select@6.0.4: - resolution: {integrity: sha512-RqGS1ZgI0MwxLaKLDxjprynNzINEkRHY2i8ln4DDjgv9ZhcYVIHN9rlpiYsqtFwrgpYU361SyWDQcGNIBVu3lw==} + has-proto@1.2.0: + resolution: {integrity: sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==} + engines: {node: '>= 0.4'} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} hast-util-to-estree@3.1.3: resolution: {integrity: sha512-48+B/rJWAp0jamNbAAf9M7Uf//UVqAoMmgXhBdxTDJLGKY+LRnZ99qcG+Qjl5HfMpYNzS5v4EAwVEF34LeAj7w==} @@ -966,53 +1824,45 @@ packages: hast-util-to-jsx-runtime@2.3.6: resolution: {integrity: sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==} - hast-util-to-parse5@8.0.0: - resolution: {integrity: sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw==} - hast-util-to-string@3.0.1: resolution: {integrity: sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A==} - hast-util-to-text@4.0.2: - resolution: {integrity: sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==} - hast-util-whitespace@3.0.0: resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} - hastscript@9.0.1: - resolution: {integrity: sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==} - - html-escaper@3.0.3: - resolution: {integrity: sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==} - html-void-elements@3.0.0: resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} - html-whitespace-sensitive-tag-names@3.0.1: - resolution: {integrity: sha512-q+310vW8zmymYHALr1da4HyXUQ0zgiIwIicEfotYPWGN0OJVEN/58IJ3A4GBYcEq3LGAZqKb+ugvP0GNB9CEAA==} + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} - http-cache-semantics@4.1.1: - resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==} + image-size@2.0.2: + resolution: {integrity: sha512-IRqXKlaXwgSMAMtpNzZa1ZAe8m+Sa1770Dhk8VkSsP9LS+iHD62Zd8FQKs8fbPiagBE7BzoFX23cxFnwshpV6w==} + engines: {node: '>=16.x'} + hasBin: true - i18next@23.16.8: - resolution: {integrity: sha512-06r/TitrM88Mg5FdUXAKL96dJMzgqLE5dv3ryBAra4KCwD9mJ4ndOTS95ZuymIGoE+2hzfdaMak2X11/es7ZWg==} + import-fresh@3.3.1: + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} + engines: {node: '>=6'} - ieee754@1.2.1: - resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} - import-meta-resolve@4.1.0: - resolution: {integrity: sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==} + inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - ini@1.3.8: - resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} - inline-style-parser@0.2.4: resolution: {integrity: sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q==} - iron-webcrypto@1.2.1: - resolution: {integrity: sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==} + internal-slot@1.1.0: + resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} + engines: {node: '>= 0.4'} is-alphabetical@2.0.1: resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==} @@ -1020,64 +1870,277 @@ packages: is-alphanumerical@2.0.1: resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==} + is-array-buffer@3.0.5: + resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} + engines: {node: '>= 0.4'} + is-arrayish@0.3.2: resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} + is-async-function@2.1.1: + resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==} + engines: {node: '>= 0.4'} + + is-bigint@1.1.0: + resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==} + engines: {node: '>= 0.4'} + + is-boolean-object@1.2.2: + resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==} + engines: {node: '>= 0.4'} + + is-bun-module@2.0.0: + resolution: {integrity: sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ==} + + is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + + is-core-module@2.16.1: + resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} + engines: {node: '>= 0.4'} + + is-data-view@1.0.2: + resolution: {integrity: sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==} + engines: {node: '>= 0.4'} + + is-date-object@1.1.0: + resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} + engines: {node: '>= 0.4'} + is-decimal@2.0.1: resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==} - is-docker@3.0.0: - resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - hasBin: true + is-extendable@0.1.1: + resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} + engines: {node: '>=0.10.0'} - is-fullwidth-code-point@3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} - engines: {node: '>=8'} + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-finalizationregistry@1.1.1: + resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==} + engines: {node: '>= 0.4'} + + is-generator-function@1.1.0: + resolution: {integrity: sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==} + engines: {node: '>= 0.4'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} is-hexadecimal@2.0.1: resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==} - is-inside-container@1.0.0: - resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} - engines: {node: '>=14.16'} - hasBin: true + is-map@2.0.3: + resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} + engines: {node: '>= 0.4'} + + is-number-object@1.1.1: + resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} + engines: {node: '>= 0.4'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-path-inside@3.0.3: + resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} + engines: {node: '>=8'} is-plain-obj@4.1.0: resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} engines: {node: '>=12'} - is-wsl@3.1.0: - resolution: {integrity: sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==} - engines: {node: '>=16'} + is-regex@1.2.1: + resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} + engines: {node: '>= 0.4'} + + is-set@2.0.3: + resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} + engines: {node: '>= 0.4'} + + is-shared-array-buffer@1.0.4: + resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==} + engines: {node: '>= 0.4'} + + is-string@1.1.1: + resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==} + engines: {node: '>= 0.4'} + + is-symbol@1.1.1: + resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==} + engines: {node: '>= 0.4'} + + is-typed-array@1.1.15: + resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} + engines: {node: '>= 0.4'} + + is-weakmap@2.0.2: + resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} + engines: {node: '>= 0.4'} + + is-weakref@1.1.1: + resolution: {integrity: sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==} + engines: {node: '>= 0.4'} + + is-weakset@2.0.4: + resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==} + engines: {node: '>= 0.4'} + + isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + iterator.prototype@1.1.5: + resolution: {integrity: sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==} + engines: {node: '>= 0.4'} + + jiti@2.4.2: + resolution: {integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==} + hasBin: true + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-yaml@3.14.1: + resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} + hasBin: true js-yaml@4.1.0: resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} hasBin: true - kleur@3.0.3: - resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} - engines: {node: '>=6'} + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} - kleur@4.1.5: - resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} - engines: {node: '>=6'} + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} - klona@2.0.6: - resolution: {integrity: sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==} - engines: {node: '>= 8'} + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + json5@1.0.2: + resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} + hasBin: true + + jsx-ast-utils@3.3.5: + resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} + engines: {node: '>=4.0'} + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + kind-of@6.0.3: + resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} + engines: {node: '>=0.10.0'} + + language-subtag-registry@0.3.23: + resolution: {integrity: sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==} + + language-tags@1.0.9: + resolution: {integrity: sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==} + engines: {node: '>=0.10'} + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + lightningcss-darwin-arm64@1.29.2: + resolution: {integrity: sha512-cK/eMabSViKn/PG8U/a7aCorpeKLMlK0bQeNHmdb7qUnBkNPnL+oV5DjJUo0kqWsJUapZsM4jCfYItbqBDvlcA==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] + + lightningcss-darwin-x64@1.29.2: + resolution: {integrity: sha512-j5qYxamyQw4kDXX5hnnCKMf3mLlHvG44f24Qyi2965/Ycz829MYqjrVg2H8BidybHBp9kom4D7DR5VqCKDXS0w==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] + + lightningcss-freebsd-x64@1.29.2: + resolution: {integrity: sha512-wDk7M2tM78Ii8ek9YjnY8MjV5f5JN2qNVO+/0BAGZRvXKtQrBC4/cn4ssQIpKIPP44YXw6gFdpUF+Ps+RGsCwg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] + + lightningcss-linux-arm-gnueabihf@1.29.2: + resolution: {integrity: sha512-IRUrOrAF2Z+KExdExe3Rz7NSTuuJ2HvCGlMKoquK5pjvo2JY4Rybr+NrKnq0U0hZnx5AnGsuFHjGnNT14w26sg==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] + + lightningcss-linux-arm64-gnu@1.29.2: + resolution: {integrity: sha512-KKCpOlmhdjvUTX/mBuaKemp0oeDIBBLFiU5Fnqxh1/DZ4JPZi4evEH7TKoSBFOSOV3J7iEmmBaw/8dpiUvRKlQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + + lightningcss-linux-arm64-musl@1.29.2: + resolution: {integrity: sha512-Q64eM1bPlOOUgxFmoPUefqzY1yV3ctFPE6d/Vt7WzLW4rKTv7MyYNky+FWxRpLkNASTnKQUaiMJ87zNODIrrKQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + + lightningcss-linux-x64-gnu@1.29.2: + resolution: {integrity: sha512-0v6idDCPG6epLXtBH/RPkHvYx74CVziHo6TMYga8O2EiQApnUPZsbR9nFNrg2cgBzk1AYqEd95TlrsL7nYABQg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + + lightningcss-linux-x64-musl@1.29.2: + resolution: {integrity: sha512-rMpz2yawkgGT8RULc5S4WiZopVMOFWjiItBT7aSfDX4NQav6M44rhn5hjtkKzB+wMTRlLLqxkeYEtQ3dd9696w==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + + lightningcss-win32-arm64-msvc@1.29.2: + resolution: {integrity: sha512-nL7zRW6evGQqYVu/bKGK+zShyz8OVzsCotFgc7judbt6wnB2KbiKKJwBE4SGoDBQ1O94RjW4asrCjQL4i8Fhbw==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] + + lightningcss-win32-x64-msvc@1.29.2: + resolution: {integrity: sha512-EdIUW3B2vLuHmv7urfzMI/h2fmlnOQBk1xlsDxkN1tCWKjNFjfLhGxYk8C8mzpSfr+A6jFFIi8fU6LbQGsRWjA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] + + lightningcss@1.29.2: + resolution: {integrity: sha512-6b6gd/RUXKaw5keVdSEtqFVdzWnU5jMxTUjA2bVcMNPLwSQ08Sv/UodBVtETLCn7k4S1Ibxwh7k68IwLZPgKaA==} + engines: {node: '>= 12.0.0'} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} longest-streak@3.1.0: resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} - lru-cache@10.4.3: - resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true - magic-string@0.30.17: - resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} + lru-cache@11.1.0: + resolution: {integrity: sha512-QIXZUBJUx+2zHUdQujWejBkcD9+cs94tLn0+YL8UrCh+D5sCXZ4c7LaEH48pNwRY3MLDgqUFyhlCyjJPf1WP0A==} + engines: {node: 20 || >=22} - magicast@0.3.5: - resolution: {integrity: sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==} + lucide-react@0.487.0: + resolution: {integrity: sha512-aKqhOQ+YmFnwq8dWgGjOuLc8V1R9/c/yOd+zDY4+ohsR2Jo05lSGc3WsstYPIzcTpeosN7LoCkLReUUITvaIvw==} + peerDependencies: + react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + lucide-react@0.488.0: + resolution: {integrity: sha512-ronlL0MyKut4CEzBY/ai2ZpKPxyWO4jUqdAkm2GNK5Zn3Rj+swDz+3lvyAUXN0PNqPKIX6XM9Xadwz/skLs/pQ==} + peerDependencies: + react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 markdown-extensions@2.0.0: resolution: {integrity: sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==} @@ -1086,11 +2149,9 @@ packages: markdown-table@3.0.4: resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} - mdast-util-definitions@6.0.0: - resolution: {integrity: sha512-scTllyX6pnYNZH/AIp/0ePz6s4cZtARxImwoPJ7kS42n+MnVsI4XbnG6d4ibehRIldYMWM2LD7ImQblVhUejVQ==} - - mdast-util-directive@3.1.0: - resolution: {integrity: sha512-I3fNFt+DHmpWCYAT7quoM6lHf9wuqtI+oCOfvILnoicNIqjh5E3dEJWiXuYME2gNe8vl1iMQwyUHa7bgFmak6Q==} + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} mdast-util-find-and-replace@3.0.2: resolution: {integrity: sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==} @@ -1140,12 +2201,13 @@ packages: mdast-util-to-string@4.0.0: resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + micromark-core-commonmark@2.0.3: resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==} - micromark-extension-directive@3.0.2: - resolution: {integrity: sha512-wjcXHgk+PPdmvR58Le9d7zQYWy+vKEU9Se44p2CrCDPiLr2FMyiT4Fyb5UFKFC66wGB3kPlgD7q3TnoqPS7SZA==} - micromark-extension-gfm-autolink-literal@2.1.0: resolution: {integrity: sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==} @@ -1167,11 +2229,11 @@ packages: micromark-extension-gfm@3.0.0: resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==} - micromark-extension-mdx-expression@3.0.0: - resolution: {integrity: sha512-sI0nwhUDz97xyzqJAbHQhp5TfaxEvZZZ2JDqUo+7NvyIYG6BZ5CPPqj2ogUoPJlmXHBnyZUzISg9+oUmU6tUjQ==} + micromark-extension-mdx-expression@3.0.1: + resolution: {integrity: sha512-dD/ADLJ1AeMvSAKBwO22zG22N4ybhe7kFIZ3LsDI0GlsNr2A3KYxb0LdC1u5rj4Nw+CHKY0RVdnHX8vj8ejm4Q==} - micromark-extension-mdx-jsx@3.0.1: - resolution: {integrity: sha512-vNuFb9czP8QCtAQcEJn0UJQJZA8Dk6DXKBqx+bg/w0WGuSxDxNr7hErW89tHUY31dUW4NqEOWwmEUNhjTFmHkg==} + micromark-extension-mdx-jsx@3.0.2: + resolution: {integrity: sha512-e5+q1DjMh62LZAJOnDraSSbDMvGJ8x3cbjygy2qFEi7HCeUT4BDKCvMozPozcD6WmOt6sVvYDNBKhFSz3kjOVQ==} micromark-extension-mdx-md@2.0.0: resolution: {integrity: sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==} @@ -1188,8 +2250,8 @@ packages: micromark-factory-label@2.0.1: resolution: {integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==} - micromark-factory-mdx-expression@2.0.2: - resolution: {integrity: sha512-5E5I2pFzJyg2CtemqAbcyCktpHXuJbABnsb32wX2U8IQKhhVFBqkcZR5LRm1WVoFqa4kTueZK4abep7wdo9nrw==} + micromark-factory-mdx-expression@2.0.3: + resolution: {integrity: sha512-kQnEtA3vzucU2BkrIa8/VaSAsP+EJ3CKOvhMuJgOEGg9KDC6OAY6nSnNDVRiVNRqj7Y4SlSzcStaH/5jge8JdQ==} micromark-factory-space@2.0.1: resolution: {integrity: sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==} @@ -1221,8 +2283,8 @@ packages: micromark-util-encode@2.0.1: resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} - micromark-util-events-to-acorn@2.0.2: - resolution: {integrity: sha512-Fk+xmBrOv9QZnEDguL9OI9/NQQp6Hz4FuQ4YmCb/5V7+9eAh1s6AYSvL20kHkD67YIg7EpE54TiSlcsf3vyZgA==} + micromark-util-events-to-acorn@2.0.3: + resolution: {integrity: sha512-jmsiEIiZ1n7X1Rr5k8wVExBQCg5jy4UXVADItHmNk1zkwEVhBuIUKRu3fqv+hs4nxLISi2DQGlqIOGiFxgbfHg==} micromark-util-html-tag-name@2.0.1: resolution: {integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==} @@ -1248,94 +2310,160 @@ packages: micromark@4.0.2: resolution: {integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==} - mimic-response@3.1.0: - resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} - engines: {node: '>=10'} + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - mkdirp-classic@0.5.3: - resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} + motion-dom@12.9.1: + resolution: {integrity: sha512-xqXEwRLDYDTzOgXobSoWtytRtGlf7zdkRfFbrrdP7eojaGQZ5Go4OOKtgnx7uF8sAkfr1ZjMvbCJSCIT2h6fkQ==} - mrmime@2.0.1: - resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==} - engines: {node: '>=10'} + motion-utils@12.8.3: + resolution: {integrity: sha512-GYVauZEbca8/zOhEiYOY9/uJeedYQld6co/GJFKOy//0c/4lDqk0zB549sBYqqV2iMuX+uHrY1E5zd8A2L+1Lw==} + + motion@12.9.1: + resolution: {integrity: sha512-amdtlwafU+XLPcrfSrOQ/S2sqiSw+UTywH+X/Yoqaz0qYEocqJKh8bs6M09CdRmkjZuKx2YM+BHodXjsqoTEag==} + peerDependencies: + '@emotion/is-prop-valid': '*' + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@emotion/is-prop-valid': + optional: true + react: + optional: true + react-dom: + optional: true ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - nanoid@3.3.9: - resolution: {integrity: sha512-SppoicMGpZvbF1l3z4x7No3OlIjP7QJvC9XR7AhZr1kL133KHnKPztkKDc+Ir4aJ/1VhTySrtKhrsycmrMQfvg==} + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true - napi-build-utils@2.0.0: - resolution: {integrity: sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==} + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - neotraverse@0.6.18: - resolution: {integrity: sha512-Z4SmBUweYa09+o6pG+eASabEpP6QkQ70yHj351pQoEXIs8uHbaU2DWVmzBANKgflPa47A50PtB2+NgRpQvr7vA==} - engines: {node: '>= 10'} + negotiator@1.0.0: + resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==} + engines: {node: '>= 0.6'} - nlcst-to-string@4.0.0: - resolution: {integrity: sha512-YKLBCcUYKAg0FNlOBT6aI91qFmSiFKiluk655WzPF+DDMA02qIyy8uiRqI8QXtcFpEvll12LpL5MXqEmAZ+dcA==} + 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-abi@3.74.0: - resolution: {integrity: sha512-c5XK0MjkGBrQPGYG24GBADZud0NCbznxNx0ZkS+ebUTrmV1qTDxPxSL8zEAPURXSbLRWVexxmP4986BziahL5w==} - engines: {node: '>=10'} + next@15.3.0: + resolution: {integrity: sha512-k0MgP6BsK8cZ73wRjMazl2y2UcXj49ZXLDEgx6BikWuby/CN+nh81qFFI16edgd7xYpe/jj2OZEIwCoqnzz0bQ==} + engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0} + hasBin: true + peerDependencies: + '@opentelemetry/api': ^1.1.0 + '@playwright/test': ^1.41.2 + babel-plugin-react-compiler: '*' + react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 + react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 + sass: ^1.3.0 + peerDependenciesMeta: + '@opentelemetry/api': + optional: true + '@playwright/test': + optional: true + babel-plugin-react-compiler: + optional: true + sass: + optional: true - node-addon-api@6.1.0: - resolution: {integrity: sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==} - - node-fetch-native@1.6.6: - resolution: {integrity: sha512-8Mc2HhqPdlIfedsuZoc3yioPuzp6b+L5jRCRY1QzuWZh2EGJVQrGppC6V6cF0bLdbW0+O2YpqCA25aF/1lvipQ==} - - node-mock-http@1.0.0: - resolution: {integrity: sha512-0uGYQ1WQL1M5kKvGRXWQ3uZCHtLTO8hln3oBjIusM75WoesZ909uQJs/Hb946i2SS+Gsrhkaa6iAO17jRIv6DQ==} - - normalize-path@3.0.0: - resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} - nth-check@2.1.1: - resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} - ofetch@1.4.1: - resolution: {integrity: sha512-QZj2DfGplQAr2oj9KzceK9Hwz6Whxazmn85yYeVuS3u9XTMOGMRx0kO95MQ+vLsj/S/NwBDMMLU5hpxvI6Tklw==} + object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + + object.assign@4.1.7: + resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} + engines: {node: '>= 0.4'} + + object.entries@1.1.9: + resolution: {integrity: sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==} + engines: {node: '>= 0.4'} + + object.fromentries@2.0.8: + resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} + engines: {node: '>= 0.4'} + + object.groupby@1.0.3: + resolution: {integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==} + engines: {node: '>= 0.4'} + + object.values@1.2.1: + resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} + engines: {node: '>= 0.4'} once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} - oniguruma-to-es@2.3.0: - resolution: {integrity: sha512-bwALDxriqfKGfUufKGGepCzu9x7nJQuoRoAFp4AnwehhC2crqrDIAP/uN2qdlsAvSMpeRC3+Yzhqc7hLmle5+g==} + oniguruma-parser@0.11.2: + resolution: {integrity: sha512-F7Ld4oDZJCI5/wCZ8AOffQbqjSzIRpKH7I/iuSs1SkhZeCj0wS6PMZ4W6VA16TWHrAo0Y9bBKEJOe7tvwcTXnw==} - p-limit@6.2.0: - resolution: {integrity: sha512-kuUqqHNUqoIWp/c467RI4X6mmyuojY5jGutNU0wVTmEOOfcuwLqyMVoAi9MKi2Ak+5i9+nhmrK4ufZE8069kHA==} - engines: {node: '>=18'} + oniguruma-to-es@4.2.0: + resolution: {integrity: sha512-MDPs6KSOLS0tKQ7joqg44dRIRZUyotfTy0r+7oEEs6VwWWP0+E2PPDYWMFN0aqOjRyWHBYq7RfKw9GQk2S2z5g==} - p-queue@8.1.0: - resolution: {integrity: sha512-mxLDbbGIBEXTJL0zEx8JIylaj3xQ7Z/7eEVjcF9fJX4DBiH9oqe+oahYnlKKxm0Ci9TlWTyhSHgygxMxjIB2jw==} - engines: {node: '>=18'} + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} - p-timeout@6.1.4: - resolution: {integrity: sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg==} - engines: {node: '>=14.16'} + own-keys@1.0.1: + resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} + engines: {node: '>= 0.4'} - package-manager-detector@1.0.0: - resolution: {integrity: sha512-7elnH+9zMsRo7aS72w6MeRugTpdRvInmEB4Kmm9BVvPw/SLG8gXUGQ+4wF0Mys0RSWPz0B9nuBbDe8vFeA2sfg==} + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} - pagefind@1.3.0: - resolution: {integrity: sha512-8KPLGT5g9s+olKMRTU9LFekLizkVIu9tes90O1/aigJ0T5LmyPqTzGJrETnSw3meSYg58YH7JTzhTTW/3z6VAw==} - hasBin: true + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} parse-entities@4.0.2: resolution: {integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==} - parse-latin@7.0.0: - resolution: {integrity: sha512-mhHgobPPua5kZ98EF4HWiH167JWBfl4pvAIXXdbaVohtK7a6YBOy56kvhCqduqyo/f3yrHFWmqmiMg/BkBkYYQ==} + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} - parse5@7.2.1: - resolution: {integrity: sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==} + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} @@ -1348,52 +2476,86 @@ packages: resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} engines: {node: '>=12'} - postcss-nested@6.2.0: - resolution: {integrity: sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==} - engines: {node: '>=12.0'} - peerDependencies: - postcss: ^8.2.14 + possible-typed-array-names@1.1.0: + resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} + engines: {node: '>= 0.4'} - postcss-selector-parser@6.1.2: - resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} + postcss-selector-parser@7.1.0: + resolution: {integrity: sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==} engines: {node: '>=4'} + postcss@8.4.31: + resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} + engines: {node: ^10 || ^12 || >=14} + postcss@8.5.3: resolution: {integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==} engines: {node: ^10 || ^12 || >=14} - prebuild-install@7.1.3: - resolution: {integrity: sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==} - engines: {node: '>=10'} - hasBin: true + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} - prismjs@1.30.0: - resolution: {integrity: sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==} - engines: {node: '>=6'} - - prompts@2.4.2: - resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} - engines: {node: '>= 6'} - - property-information@6.5.0: - resolution: {integrity: sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==} + prop-types@15.8.1: + resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} property-information@7.0.0: resolution: {integrity: sha512-7D/qOz/+Y4X/rzSB6jKxKUsQnphO046ei8qxG59mtM3RG3DHgTK81HrxrmoDVINJb8NKT5ZsRbwHvQ6B68Iyhg==} - pump@3.0.2: - resolution: {integrity: sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==} + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} - radix3@1.1.2: - resolution: {integrity: sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==} + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - rc@1.2.8: - resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} - hasBin: true + react-dom@19.1.0: + resolution: {integrity: sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==} + peerDependencies: + react: ^19.1.0 - readable-stream@3.6.2: - resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} - engines: {node: '>= 6'} + react-is@16.13.1: + resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + + react-medium-image-zoom@5.2.14: + resolution: {integrity: sha512-nfTVYcAUnBzXQpPDcZL+cG/e6UceYUIG+zDcnemL7jtAqbJjVVkA85RgneGtJeni12dTyiRPZVM6Szkmwd/o8w==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.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.6.3: + resolution: {integrity: sha512-pnAi91oOk8g8ABQKGF5/M9qxmmOPxaAnopyTHYfqYEwJhyFrbbBtHuSgtKEoH0jpcxx5o3hXqH1mNd9/Oi+8iQ==} + 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-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.1.0: + resolution: {integrity: sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==} + engines: {node: '>=0.10.0'} readdirp@4.1.2: resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} @@ -1411,42 +2573,26 @@ packages: recma-stringify@1.0.0: resolution: {integrity: sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g==} - regenerator-runtime@0.14.1: - resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} + reflect.getprototypeof@1.0.10: + resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} + engines: {node: '>= 0.4'} - regex-recursion@5.1.1: - resolution: {integrity: sha512-ae7SBCbzVNrIjgSbh7wMznPcQel1DNlDtzensnFxpiNpXt1U2ju/bHugH422r+4LAVS1FpW1YCwilmnNsjum9w==} + regex-recursion@6.0.2: + resolution: {integrity: sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==} regex-utilities@2.3.0: resolution: {integrity: sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==} - regex@5.1.1: - resolution: {integrity: sha512-dN5I359AVGPnwzJm2jN1k0W9LPZ+ePvoOeVMMfqIMFz53sSwXkxaJoxr50ptnsC771lK95BnTrVSZxq0b9yCGw==} + regex@6.0.1: + resolution: {integrity: sha512-uorlqlzAKjKQZ5P+kTJr3eeJGSVroLKoHmquUj4zHWuR+hEyNqlXsSKlYYF5F4NI6nl7tWCs0apKJ0lmfsXAPA==} - rehype-expressive-code@0.40.2: - resolution: {integrity: sha512-+kn+AMGCrGzvtH8Q5lC6Y5lnmTV/r33fdmi5QU/IH1KPHKobKr5UnLwJuqHv5jBTSN/0v2wLDS7RTM73FVzqmQ==} - - rehype-format@5.0.1: - resolution: {integrity: sha512-zvmVru9uB0josBVpr946OR8ui7nJEdzZobwLOOqHb/OOD88W0Vk2SqLwoVOj0fM6IPCCO6TaV9CvQvJMWwukFQ==} - - rehype-parse@9.0.1: - resolution: {integrity: sha512-ksCzCD0Fgfh7trPDxr2rSylbwq9iYDkSn8TCDmEJ49ljEUBxDVCzCHv7QNzZOfODanX4+bWQ4WZqLCRWYLfhag==} - - rehype-raw@7.0.0: - resolution: {integrity: sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==} + regexp.prototype.flags@1.5.4: + resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} + engines: {node: '>= 0.4'} rehype-recma@1.0.0: resolution: {integrity: sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw==} - rehype-stringify@10.0.1: - resolution: {integrity: sha512-k9ecfXHmIPuFVI61B9DeLPN0qFHfawM6RsuX48hoqlaKSF61RskNjSm1lI8PhBEM0MRdLxVVm4WmTqJQccH9mA==} - - rehype@13.0.2: - resolution: {integrity: sha512-j31mdaRFrwFRUIlxGeuPXXKWQxet52RBQRvCmzl5eCefn/KGbomK5GMHNMsOJf55fgo3qw5tST5neDuarDYR2A==} - - remark-directive@3.0.1: - resolution: {integrity: sha512-gwglrEQEZcZYgVyG1tQuA+h58EZfq5CSULw7J90AFuCTyib1thgHPoqQ+h9iFvU6R+vnZ5oNFQR5QKgGpk741A==} - remark-gfm@4.0.1: resolution: {integrity: sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==} @@ -1456,76 +2602,120 @@ packages: remark-parse@11.0.0: resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==} - remark-rehype@11.1.1: - resolution: {integrity: sha512-g/osARvjkBXb6Wo0XvAeXQohVta8i84ACbenPpoSsxTOQH/Ae0/RGP4WZgnMH5pMLpsj4FG7OHmcIcXxpza8eQ==} - - remark-smartypants@3.0.2: - resolution: {integrity: sha512-ILTWeOriIluwEvPjv67v7Blgrcx+LZOkAUVtKI3putuhlZm84FnqDORNXPPm+HY3NdZOMhyDwZ1E+eZB/Df5dA==} - engines: {node: '>=16.0.0'} + remark-rehype@11.1.2: + resolution: {integrity: sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==} remark-stringify@11.0.0: resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==} - retext-latin@4.0.0: - resolution: {integrity: sha512-hv9woG7Fy0M9IlRQloq/N6atV82NxLGveq+3H2WOi79dtIYWN8OaxogDm77f8YnVXJL2VD3bbqowu5E3EMhBYA==} + remark@15.0.1: + resolution: {integrity: sha512-Eht5w30ruCXgFmxVUSlNWQ9iiimq07URKeFS3hNc8cUWy1llX4KDWfyEDZRycMc+znsN9Ux5/tJ/BFdgdOwA3A==} - retext-smartypants@6.2.0: - resolution: {integrity: sha512-kk0jOU7+zGv//kfjXEBjdIryL1Acl4i9XNkHxtM7Tm5lFiCog576fjNC9hjoR7LTKQ0DsPWy09JummSsH1uqfQ==} + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} - retext-stringify@4.0.0: - resolution: {integrity: sha512-rtfN/0o8kL1e+78+uxPTqu1Klt0yPzKuQ2BfWwwfgIUSayyzxpM1PJzkKt4V8803uB9qSy32MvI7Xep9khTpiA==} + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} - retext@9.0.0: - resolution: {integrity: sha512-sbMDcpHCNjvlheSgMfEcVrZko3cDzdbe1x/e7G66dFp0Ff7Mldvi2uv6JkJQzdRcvLYE8CA8Oe8siQx8ZOgTcA==} - - rollup@4.35.0: - resolution: {integrity: sha512-kg6oI4g+vc41vePJyO6dHt/yl0Rz3Thv0kJeVQ3D1kS3E5XSuKbPc29G4IpT/Kv1KQwgHVcN+HtyS+HYLNSvQg==} - engines: {node: '>=18.0.0', npm: '>=8.0.0'} + resolve@1.22.10: + resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==} + engines: {node: '>= 0.4'} hasBin: true - safe-buffer@5.2.1: - resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + resolve@2.0.0-next.5: + resolution: {integrity: sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==} + hasBin: true - sax@1.4.1: - resolution: {integrity: sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==} + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + deprecated: Rimraf versions prior to v4 are no longer supported + hasBin: true + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + safe-array-concat@1.1.3: + resolution: {integrity: sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==} + engines: {node: '>=0.4'} + + safe-push-apply@1.0.0: + resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==} + engines: {node: '>= 0.4'} + + safe-regex-test@1.1.0: + resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} + engines: {node: '>= 0.4'} + + scheduler@0.26.0: + resolution: {integrity: sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==} + + scroll-into-view-if-needed@3.1.0: + resolution: {integrity: sha512-49oNpRjWRvnU8NyGVmUaYG4jtTkNonFZI86MmGRDqBphEK2EXT9gdEUoQPZhuBM8yWHxCWbobltqYO5M4XrUvQ==} + + section-matter@1.0.0: + resolution: {integrity: sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==} + engines: {node: '>=4'} + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true semver@7.7.1: resolution: {integrity: sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==} engines: {node: '>=10'} hasBin: true - sharp@0.32.6: - resolution: {integrity: sha512-KyLTWwgcR9Oe4d9HwCwNM2l7+J0dUQwn/yf7S0EnTtb0eVS4RxO0eUSvxPtzT4F3SY+C4K6fqdv/DO27sJ/v/w==} - engines: {node: '>=14.15.0'} + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} - sharp@0.33.5: - resolution: {integrity: sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==} + set-function-name@2.0.2: + resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} + engines: {node: '>= 0.4'} + + set-proto@1.0.0: + resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==} + engines: {node: '>= 0.4'} + + sharp@0.34.1: + resolution: {integrity: sha512-1j0w61+eVxu7DawFJtnfYcvSv6qPFvfTaqzTQ2BLknVhHTwGS8sc63ZBF4rzkWMBVKybo4S5OBtDdZahh2A1xg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - shiki@1.29.2: - resolution: {integrity: sha512-njXuliz/cP+67jU2hukkxCNuH1yUi4QfdZZY+sMr5PPrIyXSu5iTb/qYC4BiWWB0vZ+7TbdvYUCeL23zpwCfbg==} + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} - simple-concat@1.0.1: - resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==} + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} - simple-get@4.0.1: - resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==} + shiki@3.2.2: + resolution: {integrity: sha512-0qWBkM2t/0NXPRcVgtLhtHv6Ak3Q5yI4K/ggMqcgLRKm4+pCs3namgZlhlat/7u2CuqNtlShNs9lENOG6n7UaQ==} + + side-channel-list@1.0.0: + resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} + engines: {node: '>= 0.4'} + + side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + + side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + + side-channel@1.1.0: + resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} + engines: {node: '>= 0.4'} simple-swizzle@0.2.2: resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} - sisteransi@1.0.5: - resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} - - sitemap@8.0.0: - resolution: {integrity: sha512-+AbdxhM9kJsHtruUF39bwS/B0Fytw6Fr1o4ZAIAEqA6cke2xcoO2GleBw9Zw7nRzILVEgz7zBM5GiTJjie1G9A==} - engines: {node: '>=14.0.0', npm: '>=6.0.0'} - hasBin: true - - smol-toml@1.3.1: - resolution: {integrity: sha512-tEYNll18pPKHroYSmLLrksq233j021G0giwW7P3D24jC54pQ5W5BXMsQ/Mvw1OJCmEYDgY+lrzT+3nNUtoNfXQ==} - engines: {node: '>= 18'} - source-map-js@1.2.1: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} @@ -1537,22 +2727,38 @@ packages: space-separated-tokens@2.0.2: resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} - stream-replace-string@2.0.0: - resolution: {integrity: sha512-TlnjJ1C0QrmxRNrON00JvaFFlNh5TTG00APw23j74ET7gkQpTASi6/L2fuiav8pzK715HXtUeClpBTw2NPSn6w==} + sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} - streamx@2.22.0: - resolution: {integrity: sha512-sLh1evHOzBy/iWRiR6d1zRcLao4gGZr3C1kzNz4fopCOKJb6xD9ub8Mpi9Mr1R6id5o43S+d93fI48UC5uM9aw==} + stable-hash@0.0.5: + resolution: {integrity: sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA==} - string-width@4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} - engines: {node: '>=8'} + streamsearch@1.1.0: + resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} + engines: {node: '>=10.0.0'} - string-width@7.2.0: - resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} - engines: {node: '>=18'} + string.prototype.includes@2.0.1: + resolution: {integrity: sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==} + engines: {node: '>= 0.4'} - string_decoder@1.3.0: - resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + string.prototype.matchall@4.0.12: + resolution: {integrity: sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==} + engines: {node: '>= 0.4'} + + string.prototype.repeat@1.0.0: + resolution: {integrity: sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==} + + string.prototype.trim@1.2.10: + resolution: {integrity: sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==} + engines: {node: '>= 0.4'} + + string.prototype.trimend@1.0.9: + resolution: {integrity: sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==} + engines: {node: '>= 0.4'} + + string.prototype.trimstart@1.0.8: + resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} + engines: {node: '>= 0.4'} stringify-entities@4.0.4: resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} @@ -1561,282 +2767,210 @@ packages: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} - strip-ansi@7.1.0: - resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} - engines: {node: '>=12'} - - strip-json-comments@2.0.1: - resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} + strip-bom-string@1.0.0: + resolution: {integrity: sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==} engines: {node: '>=0.10.0'} + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + style-to-js@1.1.16: resolution: {integrity: sha512-/Q6ld50hKYPH3d/r6nr117TZkHR0w0kGGIVfpG9N6D8NymRPM9RqCUv4pRpJ62E5DqOYx2AFpbZMyCPnjQCnOw==} style-to-object@1.0.8: resolution: {integrity: sha512-xT47I/Eo0rwJmaXC4oilDGDWLohVhR6o/xAQcPQN8q6QBuZVL8qMYL85kLmST5cPjAorwvqIA4qXTRQoYHaL6g==} - tar-fs@2.1.2: - resolution: {integrity: sha512-EsaAXwxmx8UB7FRKqeozqEPop69DXcmYwTQwXvyAPF352HJsPdkVhvTaDPYqfNgruveJIJy3TA2l+2zj8LJIJA==} + styled-jsx@5.1.6: + resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==} + engines: {node: '>= 12.0.0'} + peerDependencies: + '@babel/core': '*' + babel-plugin-macros: '*' + react: '>= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0' + peerDependenciesMeta: + '@babel/core': + optional: true + babel-plugin-macros: + optional: true - tar-fs@3.0.8: - resolution: {integrity: sha512-ZoROL70jptorGAlgAYiLoBLItEKw/fUxg9BSYK/dF/GAGYFJOJJJMvjPAKDJraCXFwadD456FCuvLWgfhMsPwg==} + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} - tar-stream@2.2.0: - resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + tailwind-merge@3.2.0: + resolution: {integrity: sha512-FQT/OVqCD+7edmmJpsgCsY820RTD5AkBryuG5IUqR5YQZSdj5xlH5nLgH7YPths7WsLPSpSBNneJdM8aS8aeFA==} + + tailwindcss@4.1.4: + resolution: {integrity: sha512-1ZIUqtPITFbv/DxRmDr5/agPqJwF69d24m9qmM1939TJehgY539CtzeZRjbLt5G6fSy/7YqqYsfvoTEw9xUI2A==} + + tapable@2.2.1: + resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} engines: {node: '>=6'} - tar-stream@3.1.7: - resolution: {integrity: sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==} - - text-decoder@1.2.3: - resolution: {integrity: sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==} - - tinyexec@0.3.2: - resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} + text-table@0.2.0: + resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} tinyglobby@0.2.12: resolution: {integrity: sha512-qkf4trmKSIiMTs/E63cxH+ojC2unam7rJ0WrauAzpT3ECNTxGRMlaXxVbfxMUC/w0LaYk6jQ4y/nGR9uBO3tww==} engines: {node: '>=12.0.0'} + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + trim-lines@3.0.1: resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} trough@2.2.0: resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==} - tsconfck@3.1.5: - resolution: {integrity: sha512-CLDfGgUp7XPswWnezWwsCRxNmgQjhYq3VXHM0/XIRxhVrKw0M1if9agzryh1QS3nxjCROvV+xWxoJO1YctzzWg==} - engines: {node: ^18 || >=20} - hasBin: true + ts-api-utils@2.1.0: + resolution: {integrity: sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==} + engines: {node: '>=18.12'} peerDependencies: - typescript: ^5.0.0 - peerDependenciesMeta: - typescript: - optional: true + typescript: '>=4.8.4' + + tsconfig-paths@3.15.0: + resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} - tunnel-agent@0.6.0: - resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} + tw-animate-css@1.2.8: + resolution: {integrity: sha512-AxSnYRvyFnAiZCUndS3zQZhNfV/B77ZhJ+O7d3K6wfg/jKJY+yv6ahuyXwnyaYA9UdLqnpCwhTRv9pPTBnPR2g==} - type-fest@4.37.0: - resolution: {integrity: sha512-S/5/0kFftkq27FPNye0XM1e2NsnoD/3FS+pBmbjmmtLT6I+i344KoOf7pvXreaFsDamWeaJX55nczA1m5PsBDg==} - engines: {node: '>=16'} + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} - typescript@5.8.2: - resolution: {integrity: sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==} + type-fest@0.20.2: + resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} + engines: {node: '>=10'} + + typed-array-buffer@1.0.3: + resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} + engines: {node: '>= 0.4'} + + typed-array-byte-length@1.0.3: + resolution: {integrity: sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==} + engines: {node: '>= 0.4'} + + typed-array-byte-offset@1.0.4: + resolution: {integrity: sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==} + engines: {node: '>= 0.4'} + + typed-array-length@1.0.7: + resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} + engines: {node: '>= 0.4'} + + typescript@5.8.3: + resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==} engines: {node: '>=14.17'} hasBin: true - ufo@1.5.4: - resolution: {integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==} + unbox-primitive@1.1.0: + resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} + engines: {node: '>= 0.4'} - ultrahtml@1.5.3: - resolution: {integrity: sha512-GykOvZwgDWZlTQMtp5jrD4BVL+gNn2NVlVafjcFUJ7taY20tqYdwdoWBFy6GBJsNTZe1GkGPkSl5knQAjtgceg==} - - uncrypto@0.1.3: - resolution: {integrity: sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==} + undici-types@6.21.0: + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} unified@11.0.5: resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} - unist-util-find-after@5.0.0: - resolution: {integrity: sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==} - unist-util-is@6.0.0: resolution: {integrity: sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==} - unist-util-modify-children@4.0.0: - resolution: {integrity: sha512-+tdN5fGNddvsQdIzUF3Xx82CU9sMM+fA0dLgR9vOmT0oPT2jH+P1nd5lSqfCfXAw+93NhcXNY2qqvTUtE4cQkw==} - unist-util-position-from-estree@2.0.0: resolution: {integrity: sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==} unist-util-position@5.0.0: resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} - unist-util-remove-position@5.0.0: - resolution: {integrity: sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==} - unist-util-stringify-position@4.0.0: resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} - unist-util-visit-children@3.0.0: - resolution: {integrity: sha512-RgmdTfSBOg04sdPcpTSD1jzoNBjt9a80/ZCzp5cI9n1qPzLZWF9YdvWGN2zmTumP1HWhXKdUWexjy/Wy/lJ7tA==} - unist-util-visit-parents@6.0.1: resolution: {integrity: sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==} unist-util-visit@5.0.0: resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==} - unstorage@1.15.0: - resolution: {integrity: sha512-m40eHdGY/gA6xAPqo8eaxqXgBuzQTlAKfmB1iF7oCKXE1HfwHwzDJBywK+qQGn52dta+bPlZluPF7++yR3p/bg==} + unrs-resolver@1.5.0: + resolution: {integrity: sha512-6aia3Oy7SEe0MuUGQm2nsyob0L2+g57w178K5SE/3pvSGAIp28BB2O921fKx424Ahc/gQ6v0DXFbhcpyhGZdOA==} + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + use-callback-ref@1.3.3: + resolution: {integrity: sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==} + engines: {node: '>=10'} peerDependencies: - '@azure/app-configuration': ^1.8.0 - '@azure/cosmos': ^4.2.0 - '@azure/data-tables': ^13.3.0 - '@azure/identity': ^4.6.0 - '@azure/keyvault-secrets': ^4.9.0 - '@azure/storage-blob': ^12.26.0 - '@capacitor/preferences': ^6.0.3 - '@deno/kv': '>=0.9.0' - '@netlify/blobs': ^6.5.0 || ^7.0.0 || ^8.1.0 - '@planetscale/database': ^1.19.0 - '@upstash/redis': ^1.34.3 - '@vercel/blob': '>=0.27.1' - '@vercel/kv': ^1.0.1 - aws4fetch: ^1.0.20 - db0: '>=0.2.1' - idb-keyval: ^6.2.1 - ioredis: ^5.4.2 - uploadthing: ^7.4.4 + '@types/react': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc peerDependenciesMeta: - '@azure/app-configuration': + '@types/react': optional: true - '@azure/cosmos': - optional: true - '@azure/data-tables': - optional: true - '@azure/identity': - optional: true - '@azure/keyvault-secrets': - optional: true - '@azure/storage-blob': - optional: true - '@capacitor/preferences': - optional: true - '@deno/kv': - optional: true - '@netlify/blobs': - optional: true - '@planetscale/database': - optional: true - '@upstash/redis': - optional: true - '@vercel/blob': - optional: true - '@vercel/kv': - optional: true - aws4fetch: - optional: true - db0: - optional: true - idb-keyval: - optional: true - ioredis: - optional: true - uploadthing: + + 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 util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - vfile-location@5.0.3: - resolution: {integrity: sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==} - vfile-message@4.0.2: resolution: {integrity: sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==} vfile@6.0.3: resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} - vite@6.2.2: - resolution: {integrity: sha512-yW7PeMM+LkDzc7CgJuRLMW2Jz0FxMOsVJ8Lv3gpgW9WLcb9cTW+121UEr1hvmfR7w3SegR5ItvYyzVz1vxNJgQ==} - engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + which-boxed-primitive@1.1.1: + resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} + engines: {node: '>= 0.4'} + + which-builtin-type@1.2.1: + resolution: {integrity: sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==} + engines: {node: '>= 0.4'} + + which-collection@1.0.2: + resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} + engines: {node: '>= 0.4'} + + which-typed-array@1.1.19: + resolution: {integrity: sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==} + engines: {node: '>= 0.4'} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} hasBin: true - peerDependencies: - '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 - jiti: '>=1.21.0' - less: '*' - lightningcss: ^1.21.0 - sass: '*' - sass-embedded: '*' - stylus: '*' - sugarss: '*' - terser: ^5.16.0 - tsx: ^4.8.1 - yaml: ^2.4.2 - peerDependenciesMeta: - '@types/node': - optional: true - jiti: - optional: true - less: - optional: true - lightningcss: - optional: true - sass: - optional: true - sass-embedded: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - tsx: - optional: true - yaml: - optional: true - vitefu@1.0.6: - resolution: {integrity: sha512-+Rex1GlappUyNN6UfwbVZne/9cYC4+R2XDk9xkNXBKMw6HQagdX9PgZ8V2v1WUSK1wfBLp7qbI1+XSNIlB1xmA==} - peerDependencies: - vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 - peerDependenciesMeta: - vite: - optional: true - - web-namespaces@2.0.1: - resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==} - - which-pm-runs@1.1.0: - resolution: {integrity: sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA==} - engines: {node: '>=4'} - - widest-line@5.0.0: - resolution: {integrity: sha512-c9bZp7b5YtRj2wOe6dlj32MK+Bx/M/d+9VB2SHM1OtsUHR0aV0tdP6DWh/iMt0kWi1t5g1Iudu6hQRNd1A4PVA==} - engines: {node: '>=18'} - - wrap-ansi@9.0.0: - resolution: {integrity: sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==} - engines: {node: '>=18'} + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - xxhash-wasm@1.1.0: - resolution: {integrity: sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA==} - - yargs-parser@21.1.1: - resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} - engines: {node: '>=12'} - - yocto-queue@1.2.0: - resolution: {integrity: sha512-KHBC7z61OJeaMGnF3wqNZj+GGNXOyypZviiKpQeiHirG5Ib1ImwcLBH70rbMSkKfSmUNBsdf2PwaEJtKvgmkNw==} - engines: {node: '>=12.20'} - - yocto-spinner@0.2.1: - resolution: {integrity: sha512-lHHxjh0bXaLgdJy3cNnVb/F9myx3CkhrvSOEVTkaUgNMXnYFa2xYPVhtGnqhh3jErY2gParBOHallCbc7NrlZQ==} - engines: {node: '>=18.19'} - - yoctocolors@2.1.1: - resolution: {integrity: sha512-GQHQqAopRhwU8Kt1DDM8NjibDXHC8eoh1erhGAJPEyveY9qqVeXvVikNKrDz69sHowPMorbPUrH/mx8c50eiBQ==} - engines: {node: '>=18'} - - zod-to-json-schema@3.24.3: - resolution: {integrity: sha512-HIAfWdYIt1sssHfYZFCXp4rU1w2r8hVVXYIlmoa0r0gABLs5di3RCqPU5DDROogVz1pAdYBaz7HK5n9pSUNs3A==} - peerDependencies: - zod: ^3.24.1 - - zod-to-ts@1.2.0: - resolution: {integrity: sha512-x30XE43V+InwGpvTySRNz9kB7qFU8DlyEy7BsSTCHPH1R0QasMmHWZDCzYm6bVXtj/9NNJAZF3jW8rzFvH5OFA==} - peerDependencies: - typescript: ^4.9.4 || ^5.0.2 - zod: ^3 + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} zod@3.24.2: resolution: {integrity: sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ==} @@ -1846,312 +2980,236 @@ packages: snapshots: - '@astrojs/compiler@2.11.0': {} + '@alloc/quick-lru@5.2.0': {} - '@astrojs/internal-helpers@0.6.1': {} - - '@astrojs/markdown-remark@6.3.0': + '@emnapi/core@1.4.3': dependencies: - '@astrojs/internal-helpers': 0.6.1 - '@astrojs/prism': 3.2.0 - github-slugger: 2.0.0 - hast-util-from-html: 2.0.3 - hast-util-to-text: 4.0.2 - import-meta-resolve: 4.1.0 - js-yaml: 4.1.0 - mdast-util-definitions: 6.0.0 - rehype-raw: 7.0.0 - rehype-stringify: 10.0.1 - remark-gfm: 4.0.1 - remark-parse: 11.0.0 - remark-rehype: 11.1.1 - remark-smartypants: 3.0.2 - shiki: 1.29.2 - smol-toml: 1.3.1 - unified: 11.0.5 - unist-util-remove-position: 5.0.0 - unist-util-visit: 5.0.0 - unist-util-visit-parents: 6.0.1 - vfile: 6.0.3 - transitivePeerDependencies: - - supports-color + '@emnapi/wasi-threads': 1.0.2 + tslib: 2.8.1 + optional: true - '@astrojs/mdx@4.2.0(astro@5.5.2(rollup@4.35.0)(typescript@5.8.2))': - dependencies: - '@astrojs/markdown-remark': 6.3.0 - '@mdx-js/mdx': 3.1.0(acorn@8.14.1) - acorn: 8.14.1 - astro: 5.5.2(rollup@4.35.0)(typescript@5.8.2) - es-module-lexer: 1.6.0 - estree-util-visit: 2.0.0 - hast-util-to-html: 9.0.5 - kleur: 4.1.5 - rehype-raw: 7.0.0 - remark-gfm: 4.0.1 - remark-smartypants: 3.0.2 - source-map: 0.7.4 - unist-util-visit: 5.0.0 - vfile: 6.0.3 - transitivePeerDependencies: - - supports-color - - '@astrojs/prism@3.2.0': - dependencies: - prismjs: 1.30.0 - - '@astrojs/sitemap@3.2.1': - dependencies: - sitemap: 8.0.0 - stream-replace-string: 2.0.0 - zod: 3.24.2 - - '@astrojs/starlight@0.32.2(astro@5.5.2(rollup@4.35.0)(typescript@5.8.2))': - dependencies: - '@astrojs/mdx': 4.2.0(astro@5.5.2(rollup@4.35.0)(typescript@5.8.2)) - '@astrojs/sitemap': 3.2.1 - '@pagefind/default-ui': 1.3.0 - '@types/hast': 3.0.4 - '@types/js-yaml': 4.0.9 - '@types/mdast': 4.0.4 - astro: 5.5.2(rollup@4.35.0)(typescript@5.8.2) - astro-expressive-code: 0.40.2(astro@5.5.2(rollup@4.35.0)(typescript@5.8.2)) - bcp-47: 2.1.0 - hast-util-from-html: 2.0.3 - hast-util-select: 6.0.4 - hast-util-to-string: 3.0.1 - hastscript: 9.0.1 - i18next: 23.16.8 - js-yaml: 4.1.0 - klona: 2.0.6 - mdast-util-directive: 3.1.0 - mdast-util-to-markdown: 2.1.2 - mdast-util-to-string: 4.0.0 - pagefind: 1.3.0 - rehype: 13.0.2 - rehype-format: 5.0.1 - remark-directive: 3.0.1 - unified: 11.0.5 - unist-util-visit: 5.0.0 - vfile: 6.0.3 - transitivePeerDependencies: - - supports-color - - '@astrojs/telemetry@3.2.0': - dependencies: - ci-info: 4.2.0 - debug: 4.4.0 - dlv: 1.1.3 - dset: 3.1.4 - is-docker: 3.0.0 - is-wsl: 3.1.0 - which-pm-runs: 1.1.0 - transitivePeerDependencies: - - supports-color - - '@babel/helper-string-parser@7.25.9': {} - - '@babel/helper-validator-identifier@7.25.9': {} - - '@babel/parser@7.26.10': - dependencies: - '@babel/types': 7.26.10 - - '@babel/runtime@7.26.10': - dependencies: - regenerator-runtime: 0.14.1 - - '@babel/types@7.26.10': - dependencies: - '@babel/helper-string-parser': 7.25.9 - '@babel/helper-validator-identifier': 7.25.9 - - '@ctrl/tinycolor@4.1.0': {} - - '@emnapi/runtime@1.3.1': + '@emnapi/runtime@1.4.3': dependencies: tslib: 2.8.1 optional: true - '@esbuild/aix-ppc64@0.25.1': - optional: true - - '@esbuild/android-arm64@0.25.1': - optional: true - - '@esbuild/android-arm@0.25.1': - optional: true - - '@esbuild/android-x64@0.25.1': - optional: true - - '@esbuild/darwin-arm64@0.25.1': - optional: true - - '@esbuild/darwin-x64@0.25.1': - optional: true - - '@esbuild/freebsd-arm64@0.25.1': - optional: true - - '@esbuild/freebsd-x64@0.25.1': - optional: true - - '@esbuild/linux-arm64@0.25.1': - optional: true - - '@esbuild/linux-arm@0.25.1': - optional: true - - '@esbuild/linux-ia32@0.25.1': - optional: true - - '@esbuild/linux-loong64@0.25.1': - optional: true - - '@esbuild/linux-mips64el@0.25.1': - optional: true - - '@esbuild/linux-ppc64@0.25.1': - optional: true - - '@esbuild/linux-riscv64@0.25.1': - optional: true - - '@esbuild/linux-s390x@0.25.1': - optional: true - - '@esbuild/linux-x64@0.25.1': - optional: true - - '@esbuild/netbsd-arm64@0.25.1': - optional: true - - '@esbuild/netbsd-x64@0.25.1': - optional: true - - '@esbuild/openbsd-arm64@0.25.1': - optional: true - - '@esbuild/openbsd-x64@0.25.1': - optional: true - - '@esbuild/sunos-x64@0.25.1': - optional: true - - '@esbuild/win32-arm64@0.25.1': - optional: true - - '@esbuild/win32-ia32@0.25.1': - optional: true - - '@esbuild/win32-x64@0.25.1': - optional: true - - '@expressive-code/core@0.40.2': + '@emnapi/wasi-threads@1.0.2': dependencies: - '@ctrl/tinycolor': 4.1.0 - hast-util-select: 6.0.4 - hast-util-to-html: 9.0.5 - hast-util-to-text: 4.0.2 - hastscript: 9.0.1 - postcss: 8.5.3 - postcss-nested: 6.2.0(postcss@8.5.3) - unist-util-visit: 5.0.0 - unist-util-visit-parents: 6.0.1 + tslib: 2.8.1 + optional: true - '@expressive-code/plugin-frames@0.40.2': + '@esbuild/aix-ppc64@0.25.2': + optional: true + + '@esbuild/android-arm64@0.25.2': + optional: true + + '@esbuild/android-arm@0.25.2': + optional: true + + '@esbuild/android-x64@0.25.2': + optional: true + + '@esbuild/darwin-arm64@0.25.2': + optional: true + + '@esbuild/darwin-x64@0.25.2': + optional: true + + '@esbuild/freebsd-arm64@0.25.2': + optional: true + + '@esbuild/freebsd-x64@0.25.2': + optional: true + + '@esbuild/linux-arm64@0.25.2': + optional: true + + '@esbuild/linux-arm@0.25.2': + optional: true + + '@esbuild/linux-ia32@0.25.2': + optional: true + + '@esbuild/linux-loong64@0.25.2': + optional: true + + '@esbuild/linux-mips64el@0.25.2': + optional: true + + '@esbuild/linux-ppc64@0.25.2': + optional: true + + '@esbuild/linux-riscv64@0.25.2': + optional: true + + '@esbuild/linux-s390x@0.25.2': + optional: true + + '@esbuild/linux-x64@0.25.2': + optional: true + + '@esbuild/netbsd-arm64@0.25.2': + optional: true + + '@esbuild/netbsd-x64@0.25.2': + optional: true + + '@esbuild/openbsd-arm64@0.25.2': + optional: true + + '@esbuild/openbsd-x64@0.25.2': + optional: true + + '@esbuild/sunos-x64@0.25.2': + optional: true + + '@esbuild/win32-arm64@0.25.2': + optional: true + + '@esbuild/win32-ia32@0.25.2': + optional: true + + '@esbuild/win32-x64@0.25.2': + optional: true + + '@eslint-community/eslint-utils@4.6.1(eslint@8.57.1)': dependencies: - '@expressive-code/core': 0.40.2 + eslint: 8.57.1 + eslint-visitor-keys: 3.4.3 - '@expressive-code/plugin-shiki@0.40.2': + '@eslint-community/regexpp@4.12.1': {} + + '@eslint/eslintrc@2.1.4': dependencies: - '@expressive-code/core': 0.40.2 - shiki: 1.29.2 + ajv: 6.12.6 + debug: 4.4.0 + espree: 9.6.1 + globals: 13.24.0 + ignore: 5.3.2 + import-fresh: 3.3.1 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color - '@expressive-code/plugin-text-markers@0.40.2': + '@eslint/js@8.57.1': {} + + '@floating-ui/core@1.6.9': dependencies: - '@expressive-code/core': 0.40.2 + '@floating-ui/utils': 0.2.9 - '@img/sharp-darwin-arm64@0.33.5': - optionalDependencies: - '@img/sharp-libvips-darwin-arm64': 1.0.4 - optional: true - - '@img/sharp-darwin-x64@0.33.5': - optionalDependencies: - '@img/sharp-libvips-darwin-x64': 1.0.4 - optional: true - - '@img/sharp-libvips-darwin-arm64@1.0.4': - optional: true - - '@img/sharp-libvips-darwin-x64@1.0.4': - optional: true - - '@img/sharp-libvips-linux-arm64@1.0.4': - optional: true - - '@img/sharp-libvips-linux-arm@1.0.5': - optional: true - - '@img/sharp-libvips-linux-s390x@1.0.4': - optional: true - - '@img/sharp-libvips-linux-x64@1.0.4': - optional: true - - '@img/sharp-libvips-linuxmusl-arm64@1.0.4': - optional: true - - '@img/sharp-libvips-linuxmusl-x64@1.0.4': - optional: true - - '@img/sharp-linux-arm64@0.33.5': - optionalDependencies: - '@img/sharp-libvips-linux-arm64': 1.0.4 - optional: true - - '@img/sharp-linux-arm@0.33.5': - optionalDependencies: - '@img/sharp-libvips-linux-arm': 1.0.5 - optional: true - - '@img/sharp-linux-s390x@0.33.5': - optionalDependencies: - '@img/sharp-libvips-linux-s390x': 1.0.4 - optional: true - - '@img/sharp-linux-x64@0.33.5': - optionalDependencies: - '@img/sharp-libvips-linux-x64': 1.0.4 - optional: true - - '@img/sharp-linuxmusl-arm64@0.33.5': - optionalDependencies: - '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 - optional: true - - '@img/sharp-linuxmusl-x64@0.33.5': - optionalDependencies: - '@img/sharp-libvips-linuxmusl-x64': 1.0.4 - optional: true - - '@img/sharp-wasm32@0.33.5': + '@floating-ui/dom@1.6.13': dependencies: - '@emnapi/runtime': 1.3.1 + '@floating-ui/core': 1.6.9 + '@floating-ui/utils': 0.2.9 + + '@floating-ui/react-dom@2.1.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@floating-ui/dom': 1.6.13 + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + + '@floating-ui/utils@0.2.9': {} + + '@formatjs/intl-localematcher@0.6.1': + dependencies: + tslib: 2.8.1 + + '@humanwhocodes/config-array@0.13.0': + dependencies: + '@humanwhocodes/object-schema': 2.0.3 + debug: 4.4.0 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/object-schema@2.0.3': {} + + '@img/sharp-darwin-arm64@0.34.1': + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.1.0 optional: true - '@img/sharp-win32-ia32@0.33.5': + '@img/sharp-darwin-x64@0.34.1': + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.1.0 optional: true - '@img/sharp-win32-x64@0.33.5': + '@img/sharp-libvips-darwin-arm64@1.1.0': optional: true - '@jridgewell/sourcemap-codec@1.5.0': {} + '@img/sharp-libvips-darwin-x64@1.1.0': + optional: true + + '@img/sharp-libvips-linux-arm64@1.1.0': + optional: true + + '@img/sharp-libvips-linux-arm@1.1.0': + optional: true + + '@img/sharp-libvips-linux-ppc64@1.1.0': + optional: true + + '@img/sharp-libvips-linux-s390x@1.1.0': + optional: true + + '@img/sharp-libvips-linux-x64@1.1.0': + optional: true + + '@img/sharp-libvips-linuxmusl-arm64@1.1.0': + optional: true + + '@img/sharp-libvips-linuxmusl-x64@1.1.0': + optional: true + + '@img/sharp-linux-arm64@0.34.1': + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.1.0 + optional: true + + '@img/sharp-linux-arm@0.34.1': + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.1.0 + optional: true + + '@img/sharp-linux-s390x@0.34.1': + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.1.0 + optional: true + + '@img/sharp-linux-x64@0.34.1': + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.1.0 + optional: true + + '@img/sharp-linuxmusl-arm64@0.34.1': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.1.0 + optional: true + + '@img/sharp-linuxmusl-x64@0.34.1': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.1.0 + optional: true + + '@img/sharp-wasm32@0.34.1': + dependencies: + '@emnapi/runtime': 1.4.3 + optional: true + + '@img/sharp-win32-ia32@0.34.1': + optional: true + + '@img/sharp-win32-x64@0.34.1': + optional: true '@mdx-js/mdx@3.1.0(acorn@8.14.1)': dependencies: - '@types/estree': 1.0.6 + '@types/estree': 1.0.7 '@types/estree-jsx': 1.0.5 '@types/hast': 3.0.4 '@types/mdx': 2.0.13 @@ -2168,7 +3226,7 @@ snapshots: rehype-recma: 1.0.0 remark-mdx: 3.1.0 remark-parse: 11.0.0 - remark-rehype: 11.1.1 + remark-rehype: 11.1.2 source-map: 0.7.4 unified: 11.0.5 unist-util-position-from-estree: 2.0.0 @@ -2179,130 +3237,529 @@ snapshots: - acorn - supports-color - '@oslojs/encoding@1.1.0': {} - - '@pagefind/darwin-arm64@1.3.0': - optional: true - - '@pagefind/darwin-x64@1.3.0': - optional: true - - '@pagefind/default-ui@1.3.0': {} - - '@pagefind/linux-arm64@1.3.0': - optional: true - - '@pagefind/linux-x64@1.3.0': - optional: true - - '@pagefind/windows-x64@1.3.0': - optional: true - - '@rollup/pluginutils@5.1.4(rollup@4.35.0)': + '@napi-rs/wasm-runtime@0.2.9': dependencies: - '@types/estree': 1.0.6 - estree-walker: 2.0.2 - picomatch: 4.0.2 + '@emnapi/core': 1.4.3 + '@emnapi/runtime': 1.4.3 + '@tybys/wasm-util': 0.9.0 + optional: true + + '@next/env@15.3.0': {} + + '@next/eslint-plugin-next@15.3.0': + dependencies: + fast-glob: 3.3.1 + + '@next/swc-darwin-arm64@15.3.0': + optional: true + + '@next/swc-darwin-x64@15.3.0': + optional: true + + '@next/swc-linux-arm64-gnu@15.3.0': + optional: true + + '@next/swc-linux-arm64-musl@15.3.0': + optional: true + + '@next/swc-linux-x64-gnu@15.3.0': + optional: true + + '@next/swc-linux-x64-musl@15.3.0': + optional: true + + '@next/swc-win32-arm64-msvc@15.3.0': + optional: true + + '@next/swc-win32-x64-msvc@15.3.0': + optional: true + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.19.1 + + '@nolyfill/is-core-module@1.0.39': {} + + '@orama/orama@3.1.6': {} + + '@radix-ui/number@1.1.1': {} + + '@radix-ui/primitive@1.1.2': {} + + '@radix-ui/react-accordion@1.2.4(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-collapsible': 1.1.4(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-collection': 1.1.3(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-primitive': 2.0.3(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-controllable-state': 1.1.1(@types/react@19.1.2)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) optionalDependencies: - rollup: 4.35.0 + '@types/react': 19.1.2 + '@types/react-dom': 19.1.2(@types/react@19.1.2) - '@rollup/rollup-android-arm-eabi@4.35.0': - optional: true - - '@rollup/rollup-android-arm64@4.35.0': - optional: true - - '@rollup/rollup-darwin-arm64@4.35.0': - optional: true - - '@rollup/rollup-darwin-x64@4.35.0': - optional: true - - '@rollup/rollup-freebsd-arm64@4.35.0': - optional: true - - '@rollup/rollup-freebsd-x64@4.35.0': - optional: true - - '@rollup/rollup-linux-arm-gnueabihf@4.35.0': - optional: true - - '@rollup/rollup-linux-arm-musleabihf@4.35.0': - optional: true - - '@rollup/rollup-linux-arm64-gnu@4.35.0': - optional: true - - '@rollup/rollup-linux-arm64-musl@4.35.0': - optional: true - - '@rollup/rollup-linux-loongarch64-gnu@4.35.0': - optional: true - - '@rollup/rollup-linux-powerpc64le-gnu@4.35.0': - optional: true - - '@rollup/rollup-linux-riscv64-gnu@4.35.0': - optional: true - - '@rollup/rollup-linux-s390x-gnu@4.35.0': - optional: true - - '@rollup/rollup-linux-x64-gnu@4.35.0': - optional: true - - '@rollup/rollup-linux-x64-musl@4.35.0': - optional: true - - '@rollup/rollup-win32-arm64-msvc@4.35.0': - optional: true - - '@rollup/rollup-win32-ia32-msvc@4.35.0': - optional: true - - '@rollup/rollup-win32-x64-msvc@4.35.0': - optional: true - - '@shikijs/core@1.29.2': + '@radix-ui/react-arrow@1.1.3(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: - '@shikijs/engine-javascript': 1.29.2 - '@shikijs/engine-oniguruma': 1.29.2 - '@shikijs/types': 1.29.2 + '@radix-ui/react-primitive': 2.0.3(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.2 + '@types/react-dom': 19.1.2(@types/react@19.1.2) + + '@radix-ui/react-collapsible@1.1.4(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-presence': 1.1.3(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-primitive': 2.0.3(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-controllable-state': 1.1.1(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.2)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.2 + '@types/react-dom': 19.1.2(@types/react@19.1.2) + + '@radix-ui/react-collection@1.1.3(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-primitive': 2.0.3(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-slot': 1.2.0(@types/react@19.1.2)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.2 + '@types/react-dom': 19.1.2(@types/react@19.1.2) + + '@radix-ui/react-compose-refs@1.1.2(@types/react@19.1.2)(react@19.1.0)': + dependencies: + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.2 + + '@radix-ui/react-context@1.1.2(@types/react@19.1.2)(react@19.1.0)': + dependencies: + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.2 + + '@radix-ui/react-dialog@1.1.7(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-dismissable-layer': 1.1.6(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-focus-guards': 1.1.2(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-focus-scope': 1.1.3(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-portal': 1.1.5(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-presence': 1.1.3(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-primitive': 2.0.3(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-slot': 1.2.0(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-use-controllable-state': 1.1.1(@types/react@19.1.2)(react@19.1.0) + aria-hidden: 1.2.4 + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + react-remove-scroll: 2.6.3(@types/react@19.1.2)(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.2 + '@types/react-dom': 19.1.2(@types/react@19.1.2) + + '@radix-ui/react-direction@1.1.1(@types/react@19.1.2)(react@19.1.0)': + dependencies: + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.2 + + '@radix-ui/react-dismissable-layer@1.1.6(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-primitive': 2.0.3(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-use-escape-keydown': 1.1.1(@types/react@19.1.2)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.2 + '@types/react-dom': 19.1.2(@types/react@19.1.2) + + '@radix-ui/react-focus-guards@1.1.2(@types/react@19.1.2)(react@19.1.0)': + dependencies: + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.2 + + '@radix-ui/react-focus-scope@1.1.3(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-primitive': 2.0.3(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.2)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.2 + '@types/react-dom': 19.1.2(@types/react@19.1.2) + + '@radix-ui/react-id@1.1.1(@types/react@19.1.2)(react@19.1.0)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.2)(react@19.1.0) + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.2 + + '@radix-ui/react-navigation-menu@1.2.6(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-collection': 1.1.3(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-dismissable-layer': 1.1.6(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-presence': 1.1.3(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-primitive': 2.0.3(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-use-controllable-state': 1.1.1(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-use-previous': 1.1.1(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-visually-hidden': 1.1.3(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.2 + '@types/react-dom': 19.1.2(@types/react@19.1.2) + + '@radix-ui/react-popover@1.1.7(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-dismissable-layer': 1.1.6(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-focus-guards': 1.1.2(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-focus-scope': 1.1.3(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-popper': 1.2.3(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-portal': 1.1.5(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-presence': 1.1.3(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-primitive': 2.0.3(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-slot': 1.2.0(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-use-controllable-state': 1.1.1(@types/react@19.1.2)(react@19.1.0) + aria-hidden: 1.2.4 + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + react-remove-scroll: 2.6.3(@types/react@19.1.2)(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.2 + '@types/react-dom': 19.1.2(@types/react@19.1.2) + + '@radix-ui/react-popper@1.2.3(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@floating-ui/react-dom': 2.1.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-arrow': 1.1.3(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-primitive': 2.0.3(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-use-rect': 1.1.1(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-use-size': 1.1.1(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/rect': 1.1.1 + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.2 + '@types/react-dom': 19.1.2(@types/react@19.1.2) + + '@radix-ui/react-portal@1.1.5(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/react-primitive': 2.0.3(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.2)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.2 + '@types/react-dom': 19.1.2(@types/react@19.1.2) + + '@radix-ui/react-presence@1.1.3(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.2)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.2 + '@types/react-dom': 19.1.2(@types/react@19.1.2) + + '@radix-ui/react-primitive@2.0.3(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/react-slot': 1.2.0(@types/react@19.1.2)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.2 + '@types/react-dom': 19.1.2(@types/react@19.1.2) + + '@radix-ui/react-roving-focus@1.1.3(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-collection': 1.1.3(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-primitive': 2.0.3(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-use-controllable-state': 1.1.1(@types/react@19.1.2)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.2 + '@types/react-dom': 19.1.2(@types/react@19.1.2) + + '@radix-ui/react-scroll-area@1.2.4(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/number': 1.1.1 + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-context': 1.1.2(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-presence': 1.1.3(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-primitive': 2.0.3(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.2)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.2 + '@types/react-dom': 19.1.2(@types/react@19.1.2) + + '@radix-ui/react-slot@1.2.0(@types/react@19.1.2)(react@19.1.0)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.1.2)(react@19.1.0) + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.2 + + '@radix-ui/react-tabs@1.1.4(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/primitive': 1.1.2 + '@radix-ui/react-context': 1.1.2(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-id': 1.1.1(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-presence': 1.1.3(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-primitive': 2.0.3(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-roving-focus': 1.1.3(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-use-controllable-state': 1.1.1(@types/react@19.1.2)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.2 + '@types/react-dom': 19.1.2(@types/react@19.1.2) + + '@radix-ui/react-use-callback-ref@1.1.1(@types/react@19.1.2)(react@19.1.0)': + dependencies: + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.2 + + '@radix-ui/react-use-controllable-state@1.1.1(@types/react@19.1.2)(react@19.1.0)': + dependencies: + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.2)(react@19.1.0) + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.2 + + '@radix-ui/react-use-escape-keydown@1.1.1(@types/react@19.1.2)(react@19.1.0)': + dependencies: + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.1.2)(react@19.1.0) + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.2 + + '@radix-ui/react-use-layout-effect@1.1.1(@types/react@19.1.2)(react@19.1.0)': + dependencies: + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.2 + + '@radix-ui/react-use-previous@1.1.1(@types/react@19.1.2)(react@19.1.0)': + dependencies: + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.2 + + '@radix-ui/react-use-rect@1.1.1(@types/react@19.1.2)(react@19.1.0)': + dependencies: + '@radix-ui/rect': 1.1.1 + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.2 + + '@radix-ui/react-use-size@1.1.1(@types/react@19.1.2)(react@19.1.0)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.1.2)(react@19.1.0) + react: 19.1.0 + optionalDependencies: + '@types/react': 19.1.2 + + '@radix-ui/react-visually-hidden@1.1.3(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@radix-ui/react-primitive': 2.0.3(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.2 + '@types/react-dom': 19.1.2(@types/react@19.1.2) + + '@radix-ui/rect@1.1.1': {} + + '@rtsao/scc@1.1.0': {} + + '@rushstack/eslint-patch@1.11.0': {} + + '@shikijs/core@3.2.2': + dependencies: + '@shikijs/types': 3.2.2 '@shikijs/vscode-textmate': 10.0.2 '@types/hast': 3.0.4 hast-util-to-html: 9.0.5 - '@shikijs/engine-javascript@1.29.2': + '@shikijs/engine-javascript@3.2.2': dependencies: - '@shikijs/types': 1.29.2 + '@shikijs/types': 3.2.2 '@shikijs/vscode-textmate': 10.0.2 - oniguruma-to-es: 2.3.0 + oniguruma-to-es: 4.2.0 - '@shikijs/engine-oniguruma@1.29.2': + '@shikijs/engine-oniguruma@3.2.2': dependencies: - '@shikijs/types': 1.29.2 + '@shikijs/types': 3.2.2 '@shikijs/vscode-textmate': 10.0.2 - '@shikijs/langs@1.29.2': + '@shikijs/langs@3.2.2': dependencies: - '@shikijs/types': 1.29.2 + '@shikijs/types': 3.2.2 - '@shikijs/themes@1.29.2': + '@shikijs/rehype@3.2.2': dependencies: - '@shikijs/types': 1.29.2 + '@shikijs/types': 3.2.2 + '@types/hast': 3.0.4 + hast-util-to-string: 3.0.1 + shiki: 3.2.2 + unified: 11.0.5 + unist-util-visit: 5.0.0 - '@shikijs/types@1.29.2': + '@shikijs/themes@3.2.2': + dependencies: + '@shikijs/types': 3.2.2 + + '@shikijs/transformers@3.2.2': + dependencies: + '@shikijs/core': 3.2.2 + '@shikijs/types': 3.2.2 + + '@shikijs/types@3.2.2': dependencies: '@shikijs/vscode-textmate': 10.0.2 '@types/hast': 3.0.4 '@shikijs/vscode-textmate@10.0.2': {} - '@types/acorn@4.0.6': - dependencies: - '@types/estree': 1.0.6 + '@standard-schema/spec@1.0.0': {} - '@types/cookie@0.6.0': {} + '@swc/counter@0.1.3': {} + + '@swc/helpers@0.5.15': + dependencies: + tslib: 2.8.1 + + '@tailwindcss/node@4.1.4': + dependencies: + enhanced-resolve: 5.18.1 + jiti: 2.4.2 + lightningcss: 1.29.2 + tailwindcss: 4.1.4 + + '@tailwindcss/oxide-android-arm64@4.1.4': + optional: true + + '@tailwindcss/oxide-darwin-arm64@4.1.4': + optional: true + + '@tailwindcss/oxide-darwin-x64@4.1.4': + optional: true + + '@tailwindcss/oxide-freebsd-x64@4.1.4': + optional: true + + '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.4': + optional: true + + '@tailwindcss/oxide-linux-arm64-gnu@4.1.4': + optional: true + + '@tailwindcss/oxide-linux-arm64-musl@4.1.4': + optional: true + + '@tailwindcss/oxide-linux-x64-gnu@4.1.4': + optional: true + + '@tailwindcss/oxide-linux-x64-musl@4.1.4': + optional: true + + '@tailwindcss/oxide-wasm32-wasi@4.1.4': + optional: true + + '@tailwindcss/oxide-win32-arm64-msvc@4.1.4': + optional: true + + '@tailwindcss/oxide-win32-x64-msvc@4.1.4': + optional: true + + '@tailwindcss/oxide@4.1.4': + optionalDependencies: + '@tailwindcss/oxide-android-arm64': 4.1.4 + '@tailwindcss/oxide-darwin-arm64': 4.1.4 + '@tailwindcss/oxide-darwin-x64': 4.1.4 + '@tailwindcss/oxide-freebsd-x64': 4.1.4 + '@tailwindcss/oxide-linux-arm-gnueabihf': 4.1.4 + '@tailwindcss/oxide-linux-arm64-gnu': 4.1.4 + '@tailwindcss/oxide-linux-arm64-musl': 4.1.4 + '@tailwindcss/oxide-linux-x64-gnu': 4.1.4 + '@tailwindcss/oxide-linux-x64-musl': 4.1.4 + '@tailwindcss/oxide-wasm32-wasi': 4.1.4 + '@tailwindcss/oxide-win32-arm64-msvc': 4.1.4 + '@tailwindcss/oxide-win32-x64-msvc': 4.1.4 + + '@tailwindcss/postcss@4.1.4': + dependencies: + '@alloc/quick-lru': 5.2.0 + '@tailwindcss/node': 4.1.4 + '@tailwindcss/oxide': 4.1.4 + postcss: 8.5.3 + tailwindcss: 4.1.4 + + '@tybys/wasm-util@0.9.0': + dependencies: + tslib: 2.8.1 + optional: true '@types/debug@4.1.12': dependencies: @@ -2310,15 +3767,15 @@ snapshots: '@types/estree-jsx@1.0.5': dependencies: - '@types/estree': 1.0.6 + '@types/estree': 1.0.7 - '@types/estree@1.0.6': {} + '@types/estree@1.0.7': {} '@types/hast@3.0.4': dependencies: '@types/unist': 3.0.3 - '@types/js-yaml@4.0.9': {} + '@types/json5@0.0.29': {} '@types/mdast@4.0.4': dependencies: @@ -2328,228 +3785,309 @@ snapshots: '@types/ms@2.1.0': {} - '@types/nlcst@2.0.3': + '@types/node@22.14.0': dependencies: - '@types/unist': 3.0.3 + undici-types: 6.21.0 - '@types/node@17.0.45': {} - - '@types/sax@1.2.7': + '@types/react-dom@19.1.2(@types/react@19.1.2)': dependencies: - '@types/node': 17.0.45 + '@types/react': 19.1.2 + + '@types/react@19.1.2': + dependencies: + csstype: 3.1.3 '@types/unist@2.0.11': {} '@types/unist@3.0.3': {} + '@typescript-eslint/eslint-plugin@8.30.1(@typescript-eslint/parser@8.30.1(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1)(typescript@5.8.3)': + dependencies: + '@eslint-community/regexpp': 4.12.1 + '@typescript-eslint/parser': 8.30.1(eslint@8.57.1)(typescript@5.8.3) + '@typescript-eslint/scope-manager': 8.30.1 + '@typescript-eslint/type-utils': 8.30.1(eslint@8.57.1)(typescript@5.8.3) + '@typescript-eslint/utils': 8.30.1(eslint@8.57.1)(typescript@5.8.3) + '@typescript-eslint/visitor-keys': 8.30.1 + eslint: 8.57.1 + graphemer: 1.4.0 + ignore: 5.3.2 + natural-compare: 1.4.0 + ts-api-utils: 2.1.0(typescript@5.8.3) + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@8.30.1(eslint@8.57.1)(typescript@5.8.3)': + dependencies: + '@typescript-eslint/scope-manager': 8.30.1 + '@typescript-eslint/types': 8.30.1 + '@typescript-eslint/typescript-estree': 8.30.1(typescript@5.8.3) + '@typescript-eslint/visitor-keys': 8.30.1 + debug: 4.4.0 + eslint: 8.57.1 + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@8.30.1': + dependencies: + '@typescript-eslint/types': 8.30.1 + '@typescript-eslint/visitor-keys': 8.30.1 + + '@typescript-eslint/type-utils@8.30.1(eslint@8.57.1)(typescript@5.8.3)': + dependencies: + '@typescript-eslint/typescript-estree': 8.30.1(typescript@5.8.3) + '@typescript-eslint/utils': 8.30.1(eslint@8.57.1)(typescript@5.8.3) + debug: 4.4.0 + eslint: 8.57.1 + ts-api-utils: 2.1.0(typescript@5.8.3) + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/types@8.30.1': {} + + '@typescript-eslint/typescript-estree@8.30.1(typescript@5.8.3)': + dependencies: + '@typescript-eslint/types': 8.30.1 + '@typescript-eslint/visitor-keys': 8.30.1 + debug: 4.4.0 + fast-glob: 3.3.3 + is-glob: 4.0.3 + minimatch: 9.0.5 + semver: 7.7.1 + ts-api-utils: 2.1.0(typescript@5.8.3) + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@8.30.1(eslint@8.57.1)(typescript@5.8.3)': + dependencies: + '@eslint-community/eslint-utils': 4.6.1(eslint@8.57.1) + '@typescript-eslint/scope-manager': 8.30.1 + '@typescript-eslint/types': 8.30.1 + '@typescript-eslint/typescript-estree': 8.30.1(typescript@5.8.3) + eslint: 8.57.1 + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/visitor-keys@8.30.1': + dependencies: + '@typescript-eslint/types': 8.30.1 + eslint-visitor-keys: 4.2.0 + '@ungap/structured-clone@1.3.0': {} + '@unrs/resolver-binding-darwin-arm64@1.5.0': + optional: true + + '@unrs/resolver-binding-darwin-x64@1.5.0': + optional: true + + '@unrs/resolver-binding-freebsd-x64@1.5.0': + optional: true + + '@unrs/resolver-binding-linux-arm-gnueabihf@1.5.0': + optional: true + + '@unrs/resolver-binding-linux-arm-musleabihf@1.5.0': + optional: true + + '@unrs/resolver-binding-linux-arm64-gnu@1.5.0': + optional: true + + '@unrs/resolver-binding-linux-arm64-musl@1.5.0': + optional: true + + '@unrs/resolver-binding-linux-ppc64-gnu@1.5.0': + optional: true + + '@unrs/resolver-binding-linux-riscv64-gnu@1.5.0': + optional: true + + '@unrs/resolver-binding-linux-s390x-gnu@1.5.0': + optional: true + + '@unrs/resolver-binding-linux-x64-gnu@1.5.0': + optional: true + + '@unrs/resolver-binding-linux-x64-musl@1.5.0': + optional: true + + '@unrs/resolver-binding-wasm32-wasi@1.5.0': + dependencies: + '@napi-rs/wasm-runtime': 0.2.9 + optional: true + + '@unrs/resolver-binding-win32-arm64-msvc@1.5.0': + optional: true + + '@unrs/resolver-binding-win32-ia32-msvc@1.5.0': + optional: true + + '@unrs/resolver-binding-win32-x64-msvc@1.5.0': + optional: true + acorn-jsx@5.3.2(acorn@8.14.1): dependencies: acorn: 8.14.1 acorn@8.14.1: {} - ansi-align@3.0.1: + ajv@6.12.6: dependencies: - string-width: 4.2.3 + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 ansi-regex@5.0.1: {} - ansi-regex@6.1.0: {} - - ansi-styles@6.2.1: {} - - anymatch@3.1.3: + ansi-styles@4.3.0: dependencies: - normalize-path: 3.0.0 - picomatch: 2.3.1 + color-convert: 2.0.1 - arg@5.0.2: {} + argparse@1.0.10: + dependencies: + sprintf-js: 1.0.3 argparse@2.0.1: {} + aria-hidden@1.2.4: + dependencies: + tslib: 2.8.1 + aria-query@5.3.2: {} - array-iterate@2.0.1: {} + array-buffer-byte-length@1.0.2: + dependencies: + call-bound: 1.0.4 + is-array-buffer: 3.0.5 + + array-includes@3.1.8: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + is-string: 1.1.1 + + array.prototype.findlast@1.2.5: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + es-shim-unscopables: 1.1.0 + + array.prototype.findlastindex@1.2.6: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + es-shim-unscopables: 1.1.0 + + array.prototype.flat@1.3.3: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-shim-unscopables: 1.1.0 + + array.prototype.flatmap@1.3.3: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-shim-unscopables: 1.1.0 + + array.prototype.tosorted@1.1.4: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-errors: 1.3.0 + es-shim-unscopables: 1.1.0 + + arraybuffer.prototype.slice@1.0.4: + dependencies: + array-buffer-byte-length: 1.0.2 + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + is-array-buffer: 3.0.5 + + ast-types-flow@0.0.8: {} astring@1.9.0: {} - astro-expressive-code@0.40.2(astro@5.5.2(rollup@4.35.0)(typescript@5.8.2)): - dependencies: - astro: 5.5.2(rollup@4.35.0)(typescript@5.8.2) - rehype-expressive-code: 0.40.2 + async-function@1.0.0: {} - astro@5.5.2(rollup@4.35.0)(typescript@5.8.2): + available-typed-arrays@1.0.7: dependencies: - '@astrojs/compiler': 2.11.0 - '@astrojs/internal-helpers': 0.6.1 - '@astrojs/markdown-remark': 6.3.0 - '@astrojs/telemetry': 3.2.0 - '@oslojs/encoding': 1.1.0 - '@rollup/pluginutils': 5.1.4(rollup@4.35.0) - '@types/cookie': 0.6.0 - acorn: 8.14.1 - aria-query: 5.3.2 - axobject-query: 4.1.0 - boxen: 8.0.1 - ci-info: 4.2.0 - clsx: 2.1.1 - common-ancestor-path: 1.0.1 - cookie: 0.7.2 - cssesc: 3.0.0 - debug: 4.4.0 - deterministic-object-hash: 2.0.2 - devalue: 5.1.1 - diff: 5.2.0 - dlv: 1.1.3 - dset: 3.1.4 - es-module-lexer: 1.6.0 - esbuild: 0.25.1 - estree-walker: 3.0.3 - flattie: 1.1.1 - github-slugger: 2.0.0 - html-escaper: 3.0.3 - http-cache-semantics: 4.1.1 - js-yaml: 4.1.0 - kleur: 4.1.5 - magic-string: 0.30.17 - magicast: 0.3.5 - mrmime: 2.0.1 - neotraverse: 0.6.18 - p-limit: 6.2.0 - p-queue: 8.1.0 - package-manager-detector: 1.0.0 - picomatch: 4.0.2 - prompts: 2.4.2 - rehype: 13.0.2 - semver: 7.7.1 - shiki: 1.29.2 - tinyexec: 0.3.2 - tinyglobby: 0.2.12 - tsconfck: 3.1.5(typescript@5.8.2) - ultrahtml: 1.5.3 - unist-util-visit: 5.0.0 - unstorage: 1.15.0 - vfile: 6.0.3 - vite: 6.2.2 - vitefu: 1.0.6(vite@6.2.2) - xxhash-wasm: 1.1.0 - yargs-parser: 21.1.1 - yocto-spinner: 0.2.1 - zod: 3.24.2 - zod-to-json-schema: 3.24.3(zod@3.24.2) - zod-to-ts: 1.2.0(typescript@5.8.2)(zod@3.24.2) - optionalDependencies: - sharp: 0.33.5 - transitivePeerDependencies: - - '@azure/app-configuration' - - '@azure/cosmos' - - '@azure/data-tables' - - '@azure/identity' - - '@azure/keyvault-secrets' - - '@azure/storage-blob' - - '@capacitor/preferences' - - '@deno/kv' - - '@netlify/blobs' - - '@planetscale/database' - - '@types/node' - - '@upstash/redis' - - '@vercel/blob' - - '@vercel/kv' - - aws4fetch - - db0 - - idb-keyval - - ioredis - - jiti - - less - - lightningcss - - rollup - - sass - - sass-embedded - - stylus - - sugarss - - supports-color - - terser - - tsx - - typescript - - uploadthing - - yaml + possible-typed-array-names: 1.1.0 + + axe-core@4.10.3: {} axobject-query@4.1.0: {} - b4a@1.6.7: {} - bail@2.0.2: {} - bare-events@2.5.4: - optional: true + balanced-match@1.0.2: {} - bare-fs@4.0.1: + brace-expansion@1.1.11: dependencies: - bare-events: 2.5.4 - bare-path: 3.0.0 - bare-stream: 2.6.5(bare-events@2.5.4) - transitivePeerDependencies: - - bare-buffer - optional: true + balanced-match: 1.0.2 + concat-map: 0.0.1 - bare-os@3.6.0: - optional: true - - bare-path@3.0.0: + brace-expansion@2.0.1: dependencies: - bare-os: 3.6.0 - optional: true + balanced-match: 1.0.2 - bare-stream@2.6.5(bare-events@2.5.4): + braces@3.0.3: dependencies: - streamx: 2.22.0 - optionalDependencies: - bare-events: 2.5.4 - optional: true + fill-range: 7.1.1 - base-64@1.0.0: {} - - base64-js@1.5.1: {} - - bcp-47-match@2.0.3: {} - - bcp-47@2.1.0: + busboy@1.6.0: dependencies: - is-alphabetical: 2.0.1 - is-alphanumerical: 2.0.1 - is-decimal: 2.0.1 + streamsearch: 1.1.0 - bl@4.1.0: + call-bind-apply-helpers@1.0.2: dependencies: - buffer: 5.7.1 - inherits: 2.0.4 - readable-stream: 3.6.2 + es-errors: 1.3.0 + function-bind: 1.1.2 - boolbase@1.0.0: {} - - boxen@8.0.1: + call-bind@1.0.8: dependencies: - ansi-align: 3.0.1 - camelcase: 8.0.0 - chalk: 5.4.1 - cli-boxes: 3.0.0 - string-width: 7.2.0 - type-fest: 4.37.0 - widest-line: 5.0.0 - wrap-ansi: 9.0.0 + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + get-intrinsic: 1.3.0 + set-function-length: 1.2.2 - buffer@5.7.1: + call-bound@1.0.4: dependencies: - base64-js: 1.5.1 - ieee754: 1.2.1 + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 - camelcase@8.0.0: {} + callsites@3.1.0: {} + + caniuse-lite@1.0.30001714: {} ccount@2.0.1: {} - chalk@5.4.1: {} + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 character-entities-html4@2.1.0: {} @@ -2563,11 +4101,11 @@ snapshots: dependencies: readdirp: 4.1.2 - chownr@1.1.4: {} + class-variance-authority@0.7.1: + dependencies: + clsx: 2.1.1 - ci-info@4.2.0: {} - - cli-boxes@3.0.0: {} + client-only@0.0.1: {} clsx@2.1.1: {} @@ -2583,28 +4121,54 @@ snapshots: dependencies: color-name: 1.1.4 simple-swizzle: 0.2.2 + optional: true color@4.2.3: dependencies: color-convert: 2.0.1 color-string: 1.9.1 + optional: true comma-separated-tokens@2.0.3: {} - common-ancestor-path@1.0.1: {} + compute-scroll-into-view@3.1.1: {} - cookie-es@1.2.2: {} + concat-map@0.0.1: {} - cookie@0.7.2: {} - - crossws@0.3.4: + cross-spawn@7.0.6: dependencies: - uncrypto: 0.1.3 - - css-selector-parser@3.0.5: {} + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 cssesc@3.0.0: {} + csstype@3.1.3: {} + + damerau-levenshtein@1.0.8: {} + + data-view-buffer@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + data-view-byte-length@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + data-view-byte-offset@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + debug@3.2.7: + dependencies: + ms: 2.1.3 + debug@4.4.0: dependencies: ms: 2.1.3 @@ -2613,51 +4177,150 @@ snapshots: dependencies: character-entities: 2.0.2 - decompress-response@6.0.0: + deep-is@0.1.4: {} + + define-data-property@1.1.4: dependencies: - mimic-response: 3.1.0 + es-define-property: 1.0.1 + es-errors: 1.3.0 + gopd: 1.2.0 - deep-extend@0.6.0: {} - - defu@6.1.4: {} + define-properties@1.2.1: + dependencies: + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 + object-keys: 1.1.1 dequal@2.0.3: {} - destr@2.0.3: {} - detect-libc@2.0.3: {} - deterministic-object-hash@2.0.2: - dependencies: - base-64: 1.0.0 - - devalue@5.1.1: {} + detect-node-es@1.1.0: {} devlop@1.1.0: dependencies: dequal: 2.0.3 - diff@5.2.0: {} + doctrine@2.1.0: + dependencies: + esutils: 2.0.3 - direction@2.0.1: {} + doctrine@3.0.0: + dependencies: + esutils: 2.0.3 - dlv@1.1.3: {} - - dset@3.1.4: {} + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 emoji-regex-xs@1.0.0: {} - emoji-regex@10.4.0: {} + emoji-regex@9.2.2: {} - emoji-regex@8.0.0: {} - - end-of-stream@1.4.4: + enhanced-resolve@5.18.1: dependencies: - once: 1.4.0 + graceful-fs: 4.2.11 + tapable: 2.2.1 - entities@4.5.0: {} + es-abstract@1.23.9: + dependencies: + array-buffer-byte-length: 1.0.2 + arraybuffer.prototype.slice: 1.0.4 + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + call-bound: 1.0.4 + data-view-buffer: 1.0.2 + data-view-byte-length: 1.0.2 + data-view-byte-offset: 1.0.1 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + es-set-tostringtag: 2.1.0 + es-to-primitive: 1.3.0 + function.prototype.name: 1.1.8 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + get-symbol-description: 1.1.0 + globalthis: 1.0.4 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + has-proto: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + internal-slot: 1.1.0 + is-array-buffer: 3.0.5 + is-callable: 1.2.7 + is-data-view: 1.0.2 + is-regex: 1.2.1 + is-shared-array-buffer: 1.0.4 + is-string: 1.1.1 + is-typed-array: 1.1.15 + is-weakref: 1.1.1 + math-intrinsics: 1.1.0 + object-inspect: 1.13.4 + object-keys: 1.1.1 + object.assign: 4.1.7 + own-keys: 1.0.1 + regexp.prototype.flags: 1.5.4 + safe-array-concat: 1.1.3 + safe-push-apply: 1.0.0 + safe-regex-test: 1.1.0 + set-proto: 1.0.0 + string.prototype.trim: 1.2.10 + string.prototype.trimend: 1.0.9 + string.prototype.trimstart: 1.0.8 + typed-array-buffer: 1.0.3 + typed-array-byte-length: 1.0.3 + typed-array-byte-offset: 1.0.4 + typed-array-length: 1.0.7 + unbox-primitive: 1.1.0 + which-typed-array: 1.1.19 - es-module-lexer@1.6.0: {} + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-iterator-helpers@1.2.1: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-errors: 1.3.0 + es-set-tostringtag: 2.1.0 + function-bind: 1.1.2 + get-intrinsic: 1.3.0 + globalthis: 1.0.4 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + has-proto: 1.2.0 + has-symbols: 1.1.0 + internal-slot: 1.1.0 + iterator.prototype: 1.1.5 + safe-array-concat: 1.1.3 + + es-object-atoms@1.1.1: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.1.0: + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + es-shim-unscopables@1.1.0: + dependencies: + hasown: 2.0.2 + + es-to-primitive@1.3.0: + dependencies: + is-callable: 1.2.7 + is-date-object: 1.1.0 + is-symbol: 1.1.1 esast-util-from-estree@2.0.0: dependencies: @@ -2673,39 +4336,239 @@ snapshots: esast-util-from-estree: 2.0.0 vfile-message: 4.0.2 - esbuild@0.25.1: + esbuild@0.25.2: optionalDependencies: - '@esbuild/aix-ppc64': 0.25.1 - '@esbuild/android-arm': 0.25.1 - '@esbuild/android-arm64': 0.25.1 - '@esbuild/android-x64': 0.25.1 - '@esbuild/darwin-arm64': 0.25.1 - '@esbuild/darwin-x64': 0.25.1 - '@esbuild/freebsd-arm64': 0.25.1 - '@esbuild/freebsd-x64': 0.25.1 - '@esbuild/linux-arm': 0.25.1 - '@esbuild/linux-arm64': 0.25.1 - '@esbuild/linux-ia32': 0.25.1 - '@esbuild/linux-loong64': 0.25.1 - '@esbuild/linux-mips64el': 0.25.1 - '@esbuild/linux-ppc64': 0.25.1 - '@esbuild/linux-riscv64': 0.25.1 - '@esbuild/linux-s390x': 0.25.1 - '@esbuild/linux-x64': 0.25.1 - '@esbuild/netbsd-arm64': 0.25.1 - '@esbuild/netbsd-x64': 0.25.1 - '@esbuild/openbsd-arm64': 0.25.1 - '@esbuild/openbsd-x64': 0.25.1 - '@esbuild/sunos-x64': 0.25.1 - '@esbuild/win32-arm64': 0.25.1 - '@esbuild/win32-ia32': 0.25.1 - '@esbuild/win32-x64': 0.25.1 + '@esbuild/aix-ppc64': 0.25.2 + '@esbuild/android-arm': 0.25.2 + '@esbuild/android-arm64': 0.25.2 + '@esbuild/android-x64': 0.25.2 + '@esbuild/darwin-arm64': 0.25.2 + '@esbuild/darwin-x64': 0.25.2 + '@esbuild/freebsd-arm64': 0.25.2 + '@esbuild/freebsd-x64': 0.25.2 + '@esbuild/linux-arm': 0.25.2 + '@esbuild/linux-arm64': 0.25.2 + '@esbuild/linux-ia32': 0.25.2 + '@esbuild/linux-loong64': 0.25.2 + '@esbuild/linux-mips64el': 0.25.2 + '@esbuild/linux-ppc64': 0.25.2 + '@esbuild/linux-riscv64': 0.25.2 + '@esbuild/linux-s390x': 0.25.2 + '@esbuild/linux-x64': 0.25.2 + '@esbuild/netbsd-arm64': 0.25.2 + '@esbuild/netbsd-x64': 0.25.2 + '@esbuild/openbsd-arm64': 0.25.2 + '@esbuild/openbsd-x64': 0.25.2 + '@esbuild/sunos-x64': 0.25.2 + '@esbuild/win32-arm64': 0.25.2 + '@esbuild/win32-ia32': 0.25.2 + '@esbuild/win32-x64': 0.25.2 + + escape-string-regexp@4.0.0: {} escape-string-regexp@5.0.0: {} + eslint-config-next@15.3.0(eslint@8.57.1)(typescript@5.8.3): + dependencies: + '@next/eslint-plugin-next': 15.3.0 + '@rushstack/eslint-patch': 1.11.0 + '@typescript-eslint/eslint-plugin': 8.30.1(@typescript-eslint/parser@8.30.1(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1)(typescript@5.8.3) + '@typescript-eslint/parser': 8.30.1(eslint@8.57.1)(typescript@5.8.3) + eslint: 8.57.1 + eslint-import-resolver-node: 0.3.9 + eslint-import-resolver-typescript: 3.10.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.30.1(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1))(eslint@8.57.1) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.30.1(eslint@8.57.1)(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.30.1(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) + eslint-plugin-jsx-a11y: 6.10.2(eslint@8.57.1) + eslint-plugin-react: 7.37.5(eslint@8.57.1) + eslint-plugin-react-hooks: 5.2.0(eslint@8.57.1) + optionalDependencies: + typescript: 5.8.3 + transitivePeerDependencies: + - eslint-import-resolver-webpack + - eslint-plugin-import-x + - supports-color + + eslint-import-resolver-node@0.3.9: + dependencies: + debug: 3.2.7 + is-core-module: 2.16.1 + resolve: 1.22.10 + transitivePeerDependencies: + - supports-color + + eslint-import-resolver-typescript@3.10.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.30.1(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1))(eslint@8.57.1): + dependencies: + '@nolyfill/is-core-module': 1.0.39 + debug: 4.4.0 + eslint: 8.57.1 + get-tsconfig: 4.10.0 + is-bun-module: 2.0.0 + stable-hash: 0.0.5 + tinyglobby: 0.2.12 + unrs-resolver: 1.5.0 + optionalDependencies: + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.30.1(eslint@8.57.1)(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.30.1(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) + transitivePeerDependencies: + - supports-color + + eslint-module-utils@2.12.0(@typescript-eslint/parser@8.30.1(eslint@8.57.1)(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.30.1(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1): + dependencies: + debug: 3.2.7 + optionalDependencies: + '@typescript-eslint/parser': 8.30.1(eslint@8.57.1)(typescript@5.8.3) + eslint: 8.57.1 + eslint-import-resolver-node: 0.3.9 + eslint-import-resolver-typescript: 3.10.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.30.1(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1))(eslint@8.57.1) + transitivePeerDependencies: + - supports-color + + eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.30.1(eslint@8.57.1)(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.30.1(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1): + dependencies: + '@rtsao/scc': 1.1.0 + array-includes: 3.1.8 + array.prototype.findlastindex: 1.2.6 + array.prototype.flat: 1.3.3 + array.prototype.flatmap: 1.3.3 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 8.57.1 + eslint-import-resolver-node: 0.3.9 + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.30.1(eslint@8.57.1)(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.30.1(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) + hasown: 2.0.2 + is-core-module: 2.16.1 + is-glob: 4.0.3 + minimatch: 3.1.2 + object.fromentries: 2.0.8 + object.groupby: 1.0.3 + object.values: 1.2.1 + semver: 6.3.1 + string.prototype.trimend: 1.0.9 + tsconfig-paths: 3.15.0 + optionalDependencies: + '@typescript-eslint/parser': 8.30.1(eslint@8.57.1)(typescript@5.8.3) + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + + eslint-plugin-jsx-a11y@6.10.2(eslint@8.57.1): + dependencies: + aria-query: 5.3.2 + array-includes: 3.1.8 + array.prototype.flatmap: 1.3.3 + ast-types-flow: 0.0.8 + axe-core: 4.10.3 + axobject-query: 4.1.0 + damerau-levenshtein: 1.0.8 + emoji-regex: 9.2.2 + eslint: 8.57.1 + hasown: 2.0.2 + jsx-ast-utils: 3.3.5 + language-tags: 1.0.9 + minimatch: 3.1.2 + object.fromentries: 2.0.8 + safe-regex-test: 1.1.0 + string.prototype.includes: 2.0.1 + + eslint-plugin-react-hooks@5.2.0(eslint@8.57.1): + dependencies: + eslint: 8.57.1 + + eslint-plugin-react@7.37.5(eslint@8.57.1): + dependencies: + array-includes: 3.1.8 + array.prototype.findlast: 1.2.5 + array.prototype.flatmap: 1.3.3 + array.prototype.tosorted: 1.1.4 + doctrine: 2.1.0 + es-iterator-helpers: 1.2.1 + eslint: 8.57.1 + estraverse: 5.3.0 + hasown: 2.0.2 + jsx-ast-utils: 3.3.5 + minimatch: 3.1.2 + object.entries: 1.1.9 + object.fromentries: 2.0.8 + object.values: 1.2.1 + prop-types: 15.8.1 + resolve: 2.0.0-next.5 + semver: 6.3.1 + string.prototype.matchall: 4.0.12 + string.prototype.repeat: 1.0.0 + + eslint-scope@7.2.2: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-visitor-keys@3.4.3: {} + + eslint-visitor-keys@4.2.0: {} + + eslint@8.57.1: + dependencies: + '@eslint-community/eslint-utils': 4.6.1(eslint@8.57.1) + '@eslint-community/regexpp': 4.12.1 + '@eslint/eslintrc': 2.1.4 + '@eslint/js': 8.57.1 + '@humanwhocodes/config-array': 0.13.0 + '@humanwhocodes/module-importer': 1.0.1 + '@nodelib/fs.walk': 1.2.8 + '@ungap/structured-clone': 1.3.0 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.4.0 + doctrine: 3.0.0 + escape-string-regexp: 4.0.0 + eslint-scope: 7.2.2 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + esquery: 1.6.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 6.0.1 + find-up: 5.0.0 + glob-parent: 6.0.2 + globals: 13.24.0 + graphemer: 1.4.0 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + is-path-inside: 3.0.3 + js-yaml: 4.1.0 + json-stable-stringify-without-jsonify: 1.0.1 + levn: 0.4.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.4 + strip-ansi: 6.0.1 + text-table: 0.2.0 + transitivePeerDependencies: + - supports-color + + espree@9.6.1: + dependencies: + acorn: 8.14.1 + acorn-jsx: 5.3.2(acorn@8.14.1) + eslint-visitor-keys: 3.4.3 + + esprima@4.0.1: {} + + esquery@1.6.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@5.3.0: {} + estree-util-attach-comments@3.0.0: dependencies: - '@types/estree': 1.0.6 + '@types/estree': 1.0.7 estree-util-build-jsx@3.0.1: dependencies: @@ -2718,7 +4581,7 @@ snapshots: estree-util-scope@1.0.0: dependencies: - '@types/estree': 1.0.6 + '@types/estree': 1.0.7 devlop: 1.1.0 estree-util-to-js@2.0.0: @@ -2727,165 +4590,278 @@ snapshots: astring: 1.9.0 source-map: 0.7.4 + estree-util-value-to-estree@3.3.3: + dependencies: + '@types/estree': 1.0.7 + estree-util-visit@2.0.0: dependencies: '@types/estree-jsx': 1.0.5 '@types/unist': 3.0.3 - estree-walker@2.0.2: {} - estree-walker@3.0.3: dependencies: - '@types/estree': 1.0.6 + '@types/estree': 1.0.7 - eventemitter3@5.0.1: {} + esutils@2.0.3: {} - expand-template@2.0.3: {} - - expressive-code@0.40.2: + extend-shallow@2.0.1: dependencies: - '@expressive-code/core': 0.40.2 - '@expressive-code/plugin-frames': 0.40.2 - '@expressive-code/plugin-shiki': 0.40.2 - '@expressive-code/plugin-text-markers': 0.40.2 + is-extendable: 0.1.1 extend@3.0.2: {} - fast-fifo@1.3.2: {} + fast-deep-equal@3.1.3: {} + + fast-glob@3.3.1: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-glob@3.3.3: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + + fastq@1.19.1: + dependencies: + reusify: 1.1.0 fdir@6.4.3(picomatch@4.0.2): optionalDependencies: picomatch: 4.0.2 - flattie@1.1.1: {} + file-entry-cache@6.0.1: + dependencies: + flat-cache: 3.2.0 - fs-constants@1.0.0: {} + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 - fsevents@2.3.3: - optional: true + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 - get-east-asian-width@1.3.0: {} + flat-cache@3.2.0: + dependencies: + flatted: 3.3.3 + keyv: 4.5.4 + rimraf: 3.0.2 - github-from-package@0.0.0: {} + flatted@3.3.3: {} + + for-each@0.3.5: + dependencies: + is-callable: 1.2.7 + + framer-motion@12.9.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0): + dependencies: + motion-dom: 12.9.1 + motion-utils: 12.8.3 + tslib: 2.8.1 + optionalDependencies: + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + + fs.realpath@1.0.0: {} + + fumadocs-core@15.2.7(@types/react@19.1.2)(next@15.3.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0): + dependencies: + '@formatjs/intl-localematcher': 0.6.1 + '@orama/orama': 3.1.6 + '@shikijs/rehype': 3.2.2 + '@shikijs/transformers': 3.2.2 + github-slugger: 2.0.0 + hast-util-to-estree: 3.1.3 + hast-util-to-jsx-runtime: 2.3.6 + image-size: 2.0.2 + negotiator: 1.0.0 + react-remove-scroll: 2.6.3(@types/react@19.1.2)(react@19.1.0) + remark: 15.0.1 + remark-gfm: 4.0.1 + scroll-into-view-if-needed: 3.1.0 + shiki: 3.2.2 + unist-util-visit: 5.0.0 + optionalDependencies: + next: 15.3.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + transitivePeerDependencies: + - '@types/react' + - supports-color + + fumadocs-mdx@11.6.0(acorn@8.14.1)(fumadocs-core@15.2.7(@types/react@19.1.2)(next@15.3.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(next@15.3.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0)): + dependencies: + '@mdx-js/mdx': 3.1.0(acorn@8.14.1) + '@standard-schema/spec': 1.0.0 + chokidar: 4.0.3 + cross-spawn: 7.0.6 + esbuild: 0.25.2 + estree-util-value-to-estree: 3.3.3 + fast-glob: 3.3.3 + fumadocs-core: 15.2.7(@types/react@19.1.2)(next@15.3.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + gray-matter: 4.0.3 + lru-cache: 11.1.0 + next: 15.3.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + picocolors: 1.1.1 + unist-util-visit: 5.0.0 + zod: 3.24.2 + transitivePeerDependencies: + - acorn + - supports-color + + fumadocs-ui@15.2.7(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(next@15.3.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(tailwindcss@4.1.4): + dependencies: + '@radix-ui/react-accordion': 1.2.4(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-collapsible': 1.1.4(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-dialog': 1.1.7(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-direction': 1.1.1(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-navigation-menu': 1.2.6(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-popover': 1.1.7(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-scroll-area': 1.2.4(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@radix-ui/react-slot': 1.2.0(@types/react@19.1.2)(react@19.1.0) + '@radix-ui/react-tabs': 1.1.4(@types/react-dom@19.1.2(@types/react@19.1.2))(@types/react@19.1.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + class-variance-authority: 0.7.1 + fumadocs-core: 15.2.7(@types/react@19.1.2)(next@15.3.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + lodash.merge: 4.6.2 + lucide-react: 0.487.0(react@19.1.0) + next: 15.3.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + next-themes: 0.4.6(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + postcss-selector-parser: 7.1.0 + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + react-medium-image-zoom: 5.2.14(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + tailwind-merge: 3.2.0 + optionalDependencies: + tailwindcss: 4.1.4 + transitivePeerDependencies: + - '@oramacloud/client' + - '@types/react' + - '@types/react-dom' + - algoliasearch + - supports-color + + function-bind@1.1.2: {} + + function.prototype.name@1.1.8: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + functions-have-names: 1.2.3 + hasown: 2.0.2 + is-callable: 1.2.7 + + functions-have-names@1.2.3: {} + + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + math-intrinsics: 1.1.0 + + get-nonce@1.0.1: {} + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + + get-symbol-description@1.1.0: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + + get-tsconfig@4.10.0: + dependencies: + resolve-pkg-maps: 1.0.0 github-slugger@2.0.0: {} - h3@1.15.1: + glob-parent@5.1.2: dependencies: - cookie-es: 1.2.2 - crossws: 0.3.4 - defu: 6.1.4 - destr: 2.0.3 - iron-webcrypto: 1.2.1 - node-mock-http: 1.0.0 - radix3: 1.1.2 - ufo: 1.5.4 - uncrypto: 0.1.3 + is-glob: 4.0.3 - hast-util-embedded@3.0.0: + glob-parent@6.0.2: dependencies: - '@types/hast': 3.0.4 - hast-util-is-element: 3.0.0 + is-glob: 4.0.3 - hast-util-format@1.1.0: + glob@7.2.3: dependencies: - '@types/hast': 3.0.4 - hast-util-embedded: 3.0.0 - hast-util-minify-whitespace: 1.0.1 - hast-util-phrasing: 3.0.1 - hast-util-whitespace: 3.0.0 - html-whitespace-sensitive-tag-names: 3.0.1 - unist-util-visit-parents: 6.0.1 + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 - hast-util-from-html@2.0.3: + globals@13.24.0: dependencies: - '@types/hast': 3.0.4 - devlop: 1.1.0 - hast-util-from-parse5: 8.0.3 - parse5: 7.2.1 - vfile: 6.0.3 - vfile-message: 4.0.2 + type-fest: 0.20.2 - hast-util-from-parse5@8.0.3: + globalthis@1.0.4: dependencies: - '@types/hast': 3.0.4 - '@types/unist': 3.0.3 - devlop: 1.1.0 - hastscript: 9.0.1 - property-information: 7.0.0 - vfile: 6.0.3 - vfile-location: 5.0.3 - web-namespaces: 2.0.1 + define-properties: 1.2.1 + gopd: 1.2.0 - hast-util-has-property@3.0.0: - dependencies: - '@types/hast': 3.0.4 + gopd@1.2.0: {} - hast-util-is-body-ok-link@3.0.1: - dependencies: - '@types/hast': 3.0.4 + graceful-fs@4.2.11: {} - hast-util-is-element@3.0.0: - dependencies: - '@types/hast': 3.0.4 + graphemer@1.4.0: {} - hast-util-minify-whitespace@1.0.1: + gray-matter@4.0.3: dependencies: - '@types/hast': 3.0.4 - hast-util-embedded: 3.0.0 - hast-util-is-element: 3.0.0 - hast-util-whitespace: 3.0.0 - unist-util-is: 6.0.0 + js-yaml: 3.14.1 + kind-of: 6.0.3 + section-matter: 1.0.0 + strip-bom-string: 1.0.0 - hast-util-parse-selector@4.0.0: - dependencies: - '@types/hast': 3.0.4 + has-bigints@1.1.0: {} - hast-util-phrasing@3.0.1: - dependencies: - '@types/hast': 3.0.4 - hast-util-embedded: 3.0.0 - hast-util-has-property: 3.0.0 - hast-util-is-body-ok-link: 3.0.1 - hast-util-is-element: 3.0.0 + has-flag@4.0.0: {} - hast-util-raw@9.1.0: + has-property-descriptors@1.0.2: dependencies: - '@types/hast': 3.0.4 - '@types/unist': 3.0.3 - '@ungap/structured-clone': 1.3.0 - hast-util-from-parse5: 8.0.3 - hast-util-to-parse5: 8.0.0 - html-void-elements: 3.0.0 - mdast-util-to-hast: 13.2.0 - parse5: 7.2.1 - unist-util-position: 5.0.0 - unist-util-visit: 5.0.0 - vfile: 6.0.3 - web-namespaces: 2.0.1 - zwitch: 2.0.4 + es-define-property: 1.0.1 - hast-util-select@6.0.4: + has-proto@1.2.0: dependencies: - '@types/hast': 3.0.4 - '@types/unist': 3.0.3 - bcp-47-match: 2.0.3 - comma-separated-tokens: 2.0.3 - css-selector-parser: 3.0.5 - devlop: 1.1.0 - direction: 2.0.1 - hast-util-has-property: 3.0.0 - hast-util-to-string: 3.0.1 - hast-util-whitespace: 3.0.0 - nth-check: 2.1.1 - property-information: 7.0.0 - space-separated-tokens: 2.0.2 - unist-util-visit: 5.0.0 - zwitch: 2.0.4 + dunder-proto: 1.0.1 + + has-symbols@1.1.0: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 hast-util-to-estree@3.1.3: dependencies: - '@types/estree': 1.0.6 + '@types/estree': 1.0.7 '@types/estree-jsx': 1.0.5 '@types/hast': 3.0.4 comma-separated-tokens: 2.0.3 @@ -2920,7 +4896,7 @@ snapshots: hast-util-to-jsx-runtime@2.3.6: dependencies: - '@types/estree': 1.0.6 + '@types/estree': 1.0.7 '@types/hast': 3.0.4 '@types/unist': 3.0.3 comma-separated-tokens: 2.0.3 @@ -2938,62 +4914,41 @@ snapshots: transitivePeerDependencies: - supports-color - hast-util-to-parse5@8.0.0: - dependencies: - '@types/hast': 3.0.4 - comma-separated-tokens: 2.0.3 - devlop: 1.1.0 - property-information: 6.5.0 - space-separated-tokens: 2.0.2 - web-namespaces: 2.0.1 - zwitch: 2.0.4 - hast-util-to-string@3.0.1: dependencies: '@types/hast': 3.0.4 - hast-util-to-text@4.0.2: - dependencies: - '@types/hast': 3.0.4 - '@types/unist': 3.0.3 - hast-util-is-element: 3.0.0 - unist-util-find-after: 5.0.0 - hast-util-whitespace@3.0.0: dependencies: '@types/hast': 3.0.4 - hastscript@9.0.1: - dependencies: - '@types/hast': 3.0.4 - comma-separated-tokens: 2.0.3 - hast-util-parse-selector: 4.0.0 - property-information: 7.0.0 - space-separated-tokens: 2.0.2 - - html-escaper@3.0.3: {} - html-void-elements@3.0.0: {} - html-whitespace-sensitive-tag-names@3.0.1: {} + ignore@5.3.2: {} - http-cache-semantics@4.1.1: {} + image-size@2.0.2: {} - i18next@23.16.8: + import-fresh@3.3.1: dependencies: - '@babel/runtime': 7.26.10 + parent-module: 1.0.1 + resolve-from: 4.0.0 - ieee754@1.2.1: {} + imurmurhash@0.1.4: {} - import-meta-resolve@4.1.0: {} + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 inherits@2.0.4: {} - ini@1.3.8: {} - inline-style-parser@0.2.4: {} - iron-webcrypto@1.2.1: {} + internal-slot@1.1.0: + dependencies: + es-errors: 1.3.0 + hasown: 2.0.2 + side-channel: 1.1.0 is-alphabetical@2.0.1: {} @@ -3002,73 +4957,260 @@ snapshots: is-alphabetical: 2.0.1 is-decimal: 2.0.1 - is-arrayish@0.3.2: {} + is-array-buffer@3.0.5: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + + is-arrayish@0.3.2: + optional: true + + is-async-function@2.1.1: + dependencies: + async-function: 1.0.0 + call-bound: 1.0.4 + get-proto: 1.0.1 + has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 + + is-bigint@1.1.0: + dependencies: + has-bigints: 1.1.0 + + is-boolean-object@1.2.2: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-bun-module@2.0.0: + dependencies: + semver: 7.7.1 + + is-callable@1.2.7: {} + + is-core-module@2.16.1: + dependencies: + hasown: 2.0.2 + + is-data-view@1.0.2: + dependencies: + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + is-typed-array: 1.1.15 + + is-date-object@1.1.0: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 is-decimal@2.0.1: {} - is-docker@3.0.0: {} + is-extendable@0.1.1: {} - is-fullwidth-code-point@3.0.0: {} + is-extglob@2.1.1: {} + + is-finalizationregistry@1.1.1: + dependencies: + call-bound: 1.0.4 + + is-generator-function@1.1.0: + dependencies: + call-bound: 1.0.4 + get-proto: 1.0.1 + has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 is-hexadecimal@2.0.1: {} - is-inside-container@1.0.0: + is-map@2.0.3: {} + + is-number-object@1.1.1: dependencies: - is-docker: 3.0.0 + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-number@7.0.0: {} + + is-path-inside@3.0.3: {} is-plain-obj@4.1.0: {} - is-wsl@3.1.0: + is-regex@1.2.1: dependencies: - is-inside-container: 1.0.0 + call-bound: 1.0.4 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + is-set@2.0.3: {} + + is-shared-array-buffer@1.0.4: + dependencies: + call-bound: 1.0.4 + + is-string@1.1.1: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-symbol@1.1.1: + dependencies: + call-bound: 1.0.4 + has-symbols: 1.1.0 + safe-regex-test: 1.1.0 + + is-typed-array@1.1.15: + dependencies: + which-typed-array: 1.1.19 + + is-weakmap@2.0.2: {} + + is-weakref@1.1.1: + dependencies: + call-bound: 1.0.4 + + is-weakset@2.0.4: + dependencies: + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + + isarray@2.0.5: {} + + isexe@2.0.0: {} + + iterator.prototype@1.1.5: + dependencies: + define-data-property: 1.1.4 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + has-symbols: 1.1.0 + set-function-name: 2.0.2 + + jiti@2.4.2: {} + + js-tokens@4.0.0: {} + + js-yaml@3.14.1: + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 js-yaml@4.1.0: dependencies: argparse: 2.0.1 - kleur@3.0.3: {} + json-buffer@3.0.1: {} - kleur@4.1.5: {} + json-schema-traverse@0.4.1: {} - klona@2.0.6: {} + json-stable-stringify-without-jsonify@1.0.1: {} + + json5@1.0.2: + dependencies: + minimist: 1.2.8 + + jsx-ast-utils@3.3.5: + dependencies: + array-includes: 3.1.8 + array.prototype.flat: 1.3.3 + object.assign: 4.1.7 + object.values: 1.2.1 + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + kind-of@6.0.3: {} + + language-subtag-registry@0.3.23: {} + + language-tags@1.0.9: + dependencies: + language-subtag-registry: 0.3.23 + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + lightningcss-darwin-arm64@1.29.2: + optional: true + + lightningcss-darwin-x64@1.29.2: + optional: true + + lightningcss-freebsd-x64@1.29.2: + optional: true + + lightningcss-linux-arm-gnueabihf@1.29.2: + optional: true + + lightningcss-linux-arm64-gnu@1.29.2: + optional: true + + lightningcss-linux-arm64-musl@1.29.2: + optional: true + + lightningcss-linux-x64-gnu@1.29.2: + optional: true + + lightningcss-linux-x64-musl@1.29.2: + optional: true + + lightningcss-win32-arm64-msvc@1.29.2: + optional: true + + lightningcss-win32-x64-msvc@1.29.2: + optional: true + + lightningcss@1.29.2: + dependencies: + detect-libc: 2.0.3 + optionalDependencies: + lightningcss-darwin-arm64: 1.29.2 + lightningcss-darwin-x64: 1.29.2 + lightningcss-freebsd-x64: 1.29.2 + lightningcss-linux-arm-gnueabihf: 1.29.2 + lightningcss-linux-arm64-gnu: 1.29.2 + lightningcss-linux-arm64-musl: 1.29.2 + lightningcss-linux-x64-gnu: 1.29.2 + lightningcss-linux-x64-musl: 1.29.2 + lightningcss-win32-arm64-msvc: 1.29.2 + lightningcss-win32-x64-msvc: 1.29.2 + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lodash.merge@4.6.2: {} longest-streak@3.1.0: {} - lru-cache@10.4.3: {} - - magic-string@0.30.17: + loose-envify@1.4.0: dependencies: - '@jridgewell/sourcemap-codec': 1.5.0 + js-tokens: 4.0.0 - magicast@0.3.5: + lru-cache@11.1.0: {} + + lucide-react@0.487.0(react@19.1.0): dependencies: - '@babel/parser': 7.26.10 - '@babel/types': 7.26.10 - source-map-js: 1.2.1 + react: 19.1.0 + + lucide-react@0.488.0(react@19.1.0): + dependencies: + react: 19.1.0 markdown-extensions@2.0.0: {} markdown-table@3.0.4: {} - mdast-util-definitions@6.0.0: - dependencies: - '@types/mdast': 4.0.4 - '@types/unist': 3.0.3 - unist-util-visit: 5.0.0 - - mdast-util-directive@3.1.0: - dependencies: - '@types/mdast': 4.0.4 - '@types/unist': 3.0.3 - ccount: 2.0.1 - devlop: 1.1.0 - mdast-util-from-markdown: 2.0.2 - mdast-util-to-markdown: 2.1.2 - parse-entities: 4.0.2 - stringify-entities: 4.0.4 - unist-util-visit-parents: 6.0.1 - transitivePeerDependencies: - - supports-color + math-intrinsics@1.1.0: {} mdast-util-find-and-replace@3.0.2: dependencies: @@ -3233,6 +5375,8 @@ snapshots: dependencies: '@types/mdast': 4.0.4 + merge2@1.4.1: {} + micromark-core-commonmark@2.0.3: dependencies: decode-named-character-reference: 1.1.0 @@ -3252,16 +5396,6 @@ snapshots: micromark-util-symbol: 2.0.1 micromark-util-types: 2.0.2 - micromark-extension-directive@3.0.2: - dependencies: - devlop: 1.1.0 - micromark-factory-space: 2.0.1 - micromark-factory-whitespace: 2.0.1 - micromark-util-character: 2.1.1 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 - parse-entities: 4.0.2 - micromark-extension-gfm-autolink-literal@2.1.0: dependencies: micromark-util-character: 2.1.1 @@ -3320,27 +5454,26 @@ snapshots: micromark-util-combine-extensions: 2.0.1 micromark-util-types: 2.0.2 - micromark-extension-mdx-expression@3.0.0: + micromark-extension-mdx-expression@3.0.1: dependencies: - '@types/estree': 1.0.6 + '@types/estree': 1.0.7 devlop: 1.1.0 - micromark-factory-mdx-expression: 2.0.2 + micromark-factory-mdx-expression: 2.0.3 micromark-factory-space: 2.0.1 micromark-util-character: 2.1.1 - micromark-util-events-to-acorn: 2.0.2 + micromark-util-events-to-acorn: 2.0.3 micromark-util-symbol: 2.0.1 micromark-util-types: 2.0.2 - micromark-extension-mdx-jsx@3.0.1: + micromark-extension-mdx-jsx@3.0.2: dependencies: - '@types/acorn': 4.0.6 - '@types/estree': 1.0.6 + '@types/estree': 1.0.7 devlop: 1.1.0 estree-util-is-identifier-name: 3.0.0 - micromark-factory-mdx-expression: 2.0.2 + micromark-factory-mdx-expression: 2.0.3 micromark-factory-space: 2.0.1 micromark-util-character: 2.1.1 - micromark-util-events-to-acorn: 2.0.2 + micromark-util-events-to-acorn: 2.0.3 micromark-util-symbol: 2.0.1 micromark-util-types: 2.0.2 vfile-message: 4.0.2 @@ -3351,11 +5484,11 @@ snapshots: micromark-extension-mdxjs-esm@3.0.0: dependencies: - '@types/estree': 1.0.6 + '@types/estree': 1.0.7 devlop: 1.1.0 micromark-core-commonmark: 2.0.3 micromark-util-character: 2.1.1 - micromark-util-events-to-acorn: 2.0.2 + micromark-util-events-to-acorn: 2.0.3 micromark-util-symbol: 2.0.1 micromark-util-types: 2.0.2 unist-util-position-from-estree: 2.0.0 @@ -3365,8 +5498,8 @@ snapshots: dependencies: acorn: 8.14.1 acorn-jsx: 5.3.2(acorn@8.14.1) - micromark-extension-mdx-expression: 3.0.0 - micromark-extension-mdx-jsx: 3.0.1 + micromark-extension-mdx-expression: 3.0.1 + micromark-extension-mdx-jsx: 3.0.2 micromark-extension-mdx-md: 2.0.0 micromark-extension-mdxjs-esm: 3.0.0 micromark-util-combine-extensions: 2.0.1 @@ -3385,13 +5518,13 @@ snapshots: micromark-util-symbol: 2.0.1 micromark-util-types: 2.0.2 - micromark-factory-mdx-expression@2.0.2: + micromark-factory-mdx-expression@2.0.3: dependencies: - '@types/estree': 1.0.6 + '@types/estree': 1.0.7 devlop: 1.1.0 micromark-factory-space: 2.0.1 micromark-util-character: 2.1.1 - micromark-util-events-to-acorn: 2.0.2 + micromark-util-events-to-acorn: 2.0.3 micromark-util-symbol: 2.0.1 micromark-util-types: 2.0.2 unist-util-position-from-estree: 2.0.0 @@ -3449,10 +5582,9 @@ snapshots: micromark-util-encode@2.0.1: {} - micromark-util-events-to-acorn@2.0.2: + micromark-util-events-to-acorn@2.0.3: dependencies: - '@types/acorn': 4.0.6 - '@types/estree': 1.0.6 + '@types/estree': 1.0.7 '@types/unist': 3.0.3 devlop: 1.1.0 estree-util-visit: 2.0.0 @@ -3509,78 +5641,154 @@ snapshots: transitivePeerDependencies: - supports-color - mimic-response@3.1.0: {} + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.11 + + minimatch@9.0.5: + dependencies: + brace-expansion: 2.0.1 minimist@1.2.8: {} - mkdirp-classic@0.5.3: {} + motion-dom@12.9.1: + dependencies: + motion-utils: 12.8.3 - mrmime@2.0.1: {} + motion-utils@12.8.3: {} + + motion@12.9.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0): + dependencies: + framer-motion: 12.9.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + tslib: 2.8.1 + optionalDependencies: + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) ms@2.1.3: {} - nanoid@3.3.9: {} + nanoid@3.3.11: {} - napi-build-utils@2.0.0: {} + natural-compare@1.4.0: {} - neotraverse@0.6.18: {} + negotiator@1.0.0: {} - nlcst-to-string@4.0.0: + next-themes@0.4.6(react-dom@19.1.0(react@19.1.0))(react@19.1.0): dependencies: - '@types/nlcst': 2.0.3 + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) - node-abi@3.74.0: + next@15.3.0(react-dom@19.1.0(react@19.1.0))(react@19.1.0): dependencies: - semver: 7.7.1 + '@next/env': 15.3.0 + '@swc/counter': 0.1.3 + '@swc/helpers': 0.5.15 + busboy: 1.6.0 + caniuse-lite: 1.0.30001714 + postcss: 8.4.31 + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + styled-jsx: 5.1.6(react@19.1.0) + optionalDependencies: + '@next/swc-darwin-arm64': 15.3.0 + '@next/swc-darwin-x64': 15.3.0 + '@next/swc-linux-arm64-gnu': 15.3.0 + '@next/swc-linux-arm64-musl': 15.3.0 + '@next/swc-linux-x64-gnu': 15.3.0 + '@next/swc-linux-x64-musl': 15.3.0 + '@next/swc-win32-arm64-msvc': 15.3.0 + '@next/swc-win32-x64-msvc': 15.3.0 + sharp: 0.34.1 + transitivePeerDependencies: + - '@babel/core' + - babel-plugin-macros - node-addon-api@6.1.0: {} + object-assign@4.1.1: {} - node-fetch-native@1.6.6: {} + object-inspect@1.13.4: {} - node-mock-http@1.0.0: {} + object-keys@1.1.1: {} - normalize-path@3.0.0: {} - - nth-check@2.1.1: + object.assign@4.1.7: dependencies: - boolbase: 1.0.0 + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + has-symbols: 1.1.0 + object-keys: 1.1.1 - ofetch@1.4.1: + object.entries@1.1.9: dependencies: - destr: 2.0.3 - node-fetch-native: 1.6.6 - ufo: 1.5.4 + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + + object.fromentries@2.0.8: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-object-atoms: 1.1.1 + + object.groupby@1.0.3: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + + object.values@1.2.1: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 once@1.4.0: dependencies: wrappy: 1.0.2 - oniguruma-to-es@2.3.0: + oniguruma-parser@0.11.2: {} + + oniguruma-to-es@4.2.0: dependencies: emoji-regex-xs: 1.0.0 - regex: 5.1.1 - regex-recursion: 5.1.1 + oniguruma-parser: 0.11.2 + regex: 6.0.1 + regex-recursion: 6.0.2 - p-limit@6.2.0: + optionator@0.9.4: dependencies: - yocto-queue: 1.2.0 + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 - p-queue@8.1.0: + own-keys@1.0.1: dependencies: - eventemitter3: 5.0.1 - p-timeout: 6.1.4 + get-intrinsic: 1.3.0 + object-keys: 1.1.1 + safe-push-apply: 1.0.0 - p-timeout@6.1.4: {} + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 - package-manager-detector@1.0.0: {} + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 - pagefind@1.3.0: - optionalDependencies: - '@pagefind/darwin-arm64': 1.3.0 - '@pagefind/darwin-x64': 1.3.0 - '@pagefind/linux-arm64': 1.3.0 - '@pagefind/linux-x64': 1.3.0 - '@pagefind/windows-x64': 1.3.0 + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 parse-entities@4.0.2: dependencies: @@ -3592,18 +5800,13 @@ snapshots: is-decimal: 2.0.1 is-hexadecimal: 2.0.1 - parse-latin@7.0.0: - dependencies: - '@types/nlcst': 2.0.3 - '@types/unist': 3.0.3 - nlcst-to-string: 4.0.0 - unist-util-modify-children: 4.0.0 - unist-util-visit-children: 3.0.0 - vfile: 6.0.3 + path-exists@4.0.0: {} - parse5@7.2.1: - dependencies: - entities: 4.5.0 + path-is-absolute@1.0.1: {} + + path-key@3.1.1: {} + + path-parse@1.0.7: {} picocolors@1.1.1: {} @@ -3611,73 +5814,85 @@ snapshots: picomatch@4.0.2: {} - postcss-nested@6.2.0(postcss@8.5.3): - dependencies: - postcss: 8.5.3 - postcss-selector-parser: 6.1.2 + possible-typed-array-names@1.1.0: {} - postcss-selector-parser@6.1.2: + postcss-selector-parser@7.1.0: dependencies: cssesc: 3.0.0 util-deprecate: 1.0.2 - postcss@8.5.3: + postcss@8.4.31: dependencies: - nanoid: 3.3.9 + nanoid: 3.3.11 picocolors: 1.1.1 source-map-js: 1.2.1 - prebuild-install@7.1.3: + postcss@8.5.3: dependencies: - detect-libc: 2.0.3 - expand-template: 2.0.3 - github-from-package: 0.0.0 - minimist: 1.2.8 - mkdirp-classic: 0.5.3 - napi-build-utils: 2.0.0 - node-abi: 3.74.0 - pump: 3.0.2 - rc: 1.2.8 - simple-get: 4.0.1 - tar-fs: 2.1.2 - tunnel-agent: 0.6.0 + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 - prismjs@1.30.0: {} + prelude-ls@1.2.1: {} - prompts@2.4.2: + prop-types@15.8.1: dependencies: - kleur: 3.0.3 - sisteransi: 1.0.5 - - property-information@6.5.0: {} + loose-envify: 1.4.0 + object-assign: 4.1.1 + react-is: 16.13.1 property-information@7.0.0: {} - pump@3.0.2: - dependencies: - end-of-stream: 1.4.4 - once: 1.4.0 + punycode@2.3.1: {} - radix3@1.1.2: {} + queue-microtask@1.2.3: {} - rc@1.2.8: + react-dom@19.1.0(react@19.1.0): dependencies: - deep-extend: 0.6.0 - ini: 1.3.8 - minimist: 1.2.8 - strip-json-comments: 2.0.1 + react: 19.1.0 + scheduler: 0.26.0 - readable-stream@3.6.2: + react-is@16.13.1: {} + + react-medium-image-zoom@5.2.14(react-dom@19.1.0(react@19.1.0))(react@19.1.0): dependencies: - inherits: 2.0.4 - string_decoder: 1.3.0 - util-deprecate: 1.0.2 + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + + react-remove-scroll-bar@2.3.8(@types/react@19.1.2)(react@19.1.0): + dependencies: + react: 19.1.0 + react-style-singleton: 2.2.3(@types/react@19.1.2)(react@19.1.0) + tslib: 2.8.1 + optionalDependencies: + '@types/react': 19.1.2 + + react-remove-scroll@2.6.3(@types/react@19.1.2)(react@19.1.0): + dependencies: + react: 19.1.0 + react-remove-scroll-bar: 2.3.8(@types/react@19.1.2)(react@19.1.0) + react-style-singleton: 2.2.3(@types/react@19.1.2)(react@19.1.0) + tslib: 2.8.1 + use-callback-ref: 1.3.3(@types/react@19.1.2)(react@19.1.0) + use-sidecar: 1.1.3(@types/react@19.1.2)(react@19.1.0) + optionalDependencies: + '@types/react': 19.1.2 + + react-style-singleton@2.2.3(@types/react@19.1.2)(react@19.1.0): + dependencies: + get-nonce: 1.0.1 + react: 19.1.0 + tslib: 2.8.1 + optionalDependencies: + '@types/react': 19.1.2 + + react@19.1.0: {} readdirp@4.1.2: {} recma-build-jsx@1.0.0: dependencies: - '@types/estree': 1.0.6 + '@types/estree': 1.0.7 estree-util-build-jsx: 3.0.1 vfile: 6.0.3 @@ -3693,82 +5908,56 @@ snapshots: recma-parse@1.0.0: dependencies: - '@types/estree': 1.0.6 + '@types/estree': 1.0.7 esast-util-from-js: 2.0.1 unified: 11.0.5 vfile: 6.0.3 recma-stringify@1.0.0: dependencies: - '@types/estree': 1.0.6 + '@types/estree': 1.0.7 estree-util-to-js: 2.0.0 unified: 11.0.5 vfile: 6.0.3 - regenerator-runtime@0.14.1: {} - - regex-recursion@5.1.1: + reflect.getprototypeof@1.0.10: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + which-builtin-type: 1.2.1 + + regex-recursion@6.0.2: dependencies: - regex: 5.1.1 regex-utilities: 2.3.0 regex-utilities@2.3.0: {} - regex@5.1.1: + regex@6.0.1: dependencies: regex-utilities: 2.3.0 - rehype-expressive-code@0.40.2: + regexp.prototype.flags@1.5.4: dependencies: - expressive-code: 0.40.2 - - rehype-format@5.0.1: - dependencies: - '@types/hast': 3.0.4 - hast-util-format: 1.1.0 - - rehype-parse@9.0.1: - dependencies: - '@types/hast': 3.0.4 - hast-util-from-html: 2.0.3 - unified: 11.0.5 - - rehype-raw@7.0.0: - dependencies: - '@types/hast': 3.0.4 - hast-util-raw: 9.1.0 - vfile: 6.0.3 + call-bind: 1.0.8 + define-properties: 1.2.1 + es-errors: 1.3.0 + get-proto: 1.0.1 + gopd: 1.2.0 + set-function-name: 2.0.2 rehype-recma@1.0.0: dependencies: - '@types/estree': 1.0.6 + '@types/estree': 1.0.7 '@types/hast': 3.0.4 hast-util-to-estree: 3.1.3 transitivePeerDependencies: - supports-color - rehype-stringify@10.0.1: - dependencies: - '@types/hast': 3.0.4 - hast-util-to-html: 9.0.5 - unified: 11.0.5 - - rehype@13.0.2: - dependencies: - '@types/hast': 3.0.4 - rehype-parse: 9.0.1 - rehype-stringify: 10.0.1 - unified: 11.0.5 - - remark-directive@3.0.1: - dependencies: - '@types/mdast': 4.0.4 - mdast-util-directive: 3.1.0 - micromark-extension-directive: 3.0.2 - unified: 11.0.5 - transitivePeerDependencies: - - supports-color - remark-gfm@4.0.1: dependencies: '@types/mdast': 4.0.4 @@ -3796,7 +5985,7 @@ snapshots: transitivePeerDependencies: - supports-color - remark-rehype@11.1.1: + remark-rehype@11.1.2: dependencies: '@types/hast': 3.0.4 '@types/mdast': 4.0.4 @@ -3804,148 +5993,180 @@ snapshots: unified: 11.0.5 vfile: 6.0.3 - remark-smartypants@3.0.2: - dependencies: - retext: 9.0.0 - retext-smartypants: 6.2.0 - unified: 11.0.5 - unist-util-visit: 5.0.0 - remark-stringify@11.0.0: dependencies: '@types/mdast': 4.0.4 mdast-util-to-markdown: 2.1.2 unified: 11.0.5 - retext-latin@4.0.0: + remark@15.0.1: dependencies: - '@types/nlcst': 2.0.3 - parse-latin: 7.0.0 + '@types/mdast': 4.0.4 + remark-parse: 11.0.0 + remark-stringify: 11.0.0 unified: 11.0.5 + transitivePeerDependencies: + - supports-color - retext-smartypants@6.2.0: + resolve-from@4.0.0: {} + + resolve-pkg-maps@1.0.0: {} + + resolve@1.22.10: dependencies: - '@types/nlcst': 2.0.3 - nlcst-to-string: 4.0.0 - unist-util-visit: 5.0.0 + is-core-module: 2.16.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 - retext-stringify@4.0.0: + resolve@2.0.0-next.5: dependencies: - '@types/nlcst': 2.0.3 - nlcst-to-string: 4.0.0 - unified: 11.0.5 + is-core-module: 2.16.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 - retext@9.0.0: + reusify@1.1.0: {} + + rimraf@3.0.2: dependencies: - '@types/nlcst': 2.0.3 - retext-latin: 4.0.0 - retext-stringify: 4.0.0 - unified: 11.0.5 + glob: 7.2.3 - rollup@4.35.0: + run-parallel@1.2.0: dependencies: - '@types/estree': 1.0.6 - optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.35.0 - '@rollup/rollup-android-arm64': 4.35.0 - '@rollup/rollup-darwin-arm64': 4.35.0 - '@rollup/rollup-darwin-x64': 4.35.0 - '@rollup/rollup-freebsd-arm64': 4.35.0 - '@rollup/rollup-freebsd-x64': 4.35.0 - '@rollup/rollup-linux-arm-gnueabihf': 4.35.0 - '@rollup/rollup-linux-arm-musleabihf': 4.35.0 - '@rollup/rollup-linux-arm64-gnu': 4.35.0 - '@rollup/rollup-linux-arm64-musl': 4.35.0 - '@rollup/rollup-linux-loongarch64-gnu': 4.35.0 - '@rollup/rollup-linux-powerpc64le-gnu': 4.35.0 - '@rollup/rollup-linux-riscv64-gnu': 4.35.0 - '@rollup/rollup-linux-s390x-gnu': 4.35.0 - '@rollup/rollup-linux-x64-gnu': 4.35.0 - '@rollup/rollup-linux-x64-musl': 4.35.0 - '@rollup/rollup-win32-arm64-msvc': 4.35.0 - '@rollup/rollup-win32-ia32-msvc': 4.35.0 - '@rollup/rollup-win32-x64-msvc': 4.35.0 - fsevents: 2.3.3 + queue-microtask: 1.2.3 - safe-buffer@5.2.1: {} + safe-array-concat@1.1.3: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + has-symbols: 1.1.0 + isarray: 2.0.5 - sax@1.4.1: {} + safe-push-apply@1.0.0: + dependencies: + es-errors: 1.3.0 + isarray: 2.0.5 + + safe-regex-test@1.1.0: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-regex: 1.2.1 + + scheduler@0.26.0: {} + + scroll-into-view-if-needed@3.1.0: + dependencies: + compute-scroll-into-view: 3.1.1 + + section-matter@1.0.0: + dependencies: + extend-shallow: 2.0.1 + kind-of: 6.0.3 + + semver@6.3.1: {} semver@7.7.1: {} - sharp@0.32.6: + set-function-length@1.2.2: dependencies: - color: 4.2.3 - detect-libc: 2.0.3 - node-addon-api: 6.1.0 - prebuild-install: 7.1.3 - semver: 7.7.1 - simple-get: 4.0.1 - tar-fs: 3.0.8 - tunnel-agent: 0.6.0 - transitivePeerDependencies: - - bare-buffer + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.3.0 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 - sharp@0.33.5: + set-function-name@2.0.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.2 + + set-proto@1.0.0: + dependencies: + dunder-proto: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + + sharp@0.34.1: dependencies: color: 4.2.3 detect-libc: 2.0.3 semver: 7.7.1 optionalDependencies: - '@img/sharp-darwin-arm64': 0.33.5 - '@img/sharp-darwin-x64': 0.33.5 - '@img/sharp-libvips-darwin-arm64': 1.0.4 - '@img/sharp-libvips-darwin-x64': 1.0.4 - '@img/sharp-libvips-linux-arm': 1.0.5 - '@img/sharp-libvips-linux-arm64': 1.0.4 - '@img/sharp-libvips-linux-s390x': 1.0.4 - '@img/sharp-libvips-linux-x64': 1.0.4 - '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 - '@img/sharp-libvips-linuxmusl-x64': 1.0.4 - '@img/sharp-linux-arm': 0.33.5 - '@img/sharp-linux-arm64': 0.33.5 - '@img/sharp-linux-s390x': 0.33.5 - '@img/sharp-linux-x64': 0.33.5 - '@img/sharp-linuxmusl-arm64': 0.33.5 - '@img/sharp-linuxmusl-x64': 0.33.5 - '@img/sharp-wasm32': 0.33.5 - '@img/sharp-win32-ia32': 0.33.5 - '@img/sharp-win32-x64': 0.33.5 + '@img/sharp-darwin-arm64': 0.34.1 + '@img/sharp-darwin-x64': 0.34.1 + '@img/sharp-libvips-darwin-arm64': 1.1.0 + '@img/sharp-libvips-darwin-x64': 1.1.0 + '@img/sharp-libvips-linux-arm': 1.1.0 + '@img/sharp-libvips-linux-arm64': 1.1.0 + '@img/sharp-libvips-linux-ppc64': 1.1.0 + '@img/sharp-libvips-linux-s390x': 1.1.0 + '@img/sharp-libvips-linux-x64': 1.1.0 + '@img/sharp-libvips-linuxmusl-arm64': 1.1.0 + '@img/sharp-libvips-linuxmusl-x64': 1.1.0 + '@img/sharp-linux-arm': 0.34.1 + '@img/sharp-linux-arm64': 0.34.1 + '@img/sharp-linux-s390x': 0.34.1 + '@img/sharp-linux-x64': 0.34.1 + '@img/sharp-linuxmusl-arm64': 0.34.1 + '@img/sharp-linuxmusl-x64': 0.34.1 + '@img/sharp-wasm32': 0.34.1 + '@img/sharp-win32-ia32': 0.34.1 + '@img/sharp-win32-x64': 0.34.1 optional: true - shiki@1.29.2: + shebang-command@2.0.0: dependencies: - '@shikijs/core': 1.29.2 - '@shikijs/engine-javascript': 1.29.2 - '@shikijs/engine-oniguruma': 1.29.2 - '@shikijs/langs': 1.29.2 - '@shikijs/themes': 1.29.2 - '@shikijs/types': 1.29.2 + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + shiki@3.2.2: + dependencies: + '@shikijs/core': 3.2.2 + '@shikijs/engine-javascript': 3.2.2 + '@shikijs/engine-oniguruma': 3.2.2 + '@shikijs/langs': 3.2.2 + '@shikijs/themes': 3.2.2 + '@shikijs/types': 3.2.2 '@shikijs/vscode-textmate': 10.0.2 '@types/hast': 3.0.4 - simple-concat@1.0.1: {} - - simple-get@4.0.1: + side-channel-list@1.0.0: dependencies: - decompress-response: 6.0.0 - once: 1.4.0 - simple-concat: 1.0.1 + es-errors: 1.3.0 + object-inspect: 1.13.4 + + side-channel-map@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + + side-channel-weakmap@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + + side-channel@1.1.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.0 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 simple-swizzle@0.2.2: dependencies: is-arrayish: 0.3.2 - - sisteransi@1.0.5: {} - - sitemap@8.0.0: - dependencies: - '@types/node': 17.0.45 - '@types/sax': 1.2.7 - arg: 5.0.2 - sax: 1.4.1 - - smol-toml@1.3.1: {} + optional: true source-map-js@1.2.1: {} @@ -3953,30 +6174,61 @@ snapshots: space-separated-tokens@2.0.2: {} - stream-replace-string@2.0.0: {} + sprintf-js@1.0.3: {} - streamx@2.22.0: - dependencies: - fast-fifo: 1.3.2 - text-decoder: 1.2.3 - optionalDependencies: - bare-events: 2.5.4 + stable-hash@0.0.5: {} - string-width@4.2.3: - dependencies: - emoji-regex: 8.0.0 - is-fullwidth-code-point: 3.0.0 - strip-ansi: 6.0.1 + streamsearch@1.1.0: {} - string-width@7.2.0: + string.prototype.includes@2.0.1: dependencies: - emoji-regex: 10.4.0 - get-east-asian-width: 1.3.0 - strip-ansi: 7.1.0 + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 - string_decoder@1.3.0: + string.prototype.matchall@4.0.12: dependencies: - safe-buffer: 5.2.1 + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + gopd: 1.2.0 + has-symbols: 1.1.0 + internal-slot: 1.1.0 + regexp.prototype.flags: 1.5.4 + set-function-name: 2.0.2 + side-channel: 1.1.0 + + string.prototype.repeat@1.0.0: + dependencies: + define-properties: 1.2.1 + es-abstract: 1.23.9 + + string.prototype.trim@1.2.10: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-data-property: 1.1.4 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-object-atoms: 1.1.1 + has-property-descriptors: 1.0.2 + + string.prototype.trimend@1.0.9: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + + string.prototype.trimstart@1.0.8: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 stringify-entities@4.0.4: dependencies: @@ -3987,11 +6239,11 @@ snapshots: dependencies: ansi-regex: 5.0.1 - strip-ansi@7.1.0: - dependencies: - ansi-regex: 6.1.0 + strip-bom-string@1.0.0: {} - strip-json-comments@2.0.1: {} + strip-bom@3.0.0: {} + + strip-json-comments@3.1.1: {} style-to-js@1.1.16: dependencies: @@ -4001,72 +6253,102 @@ snapshots: dependencies: inline-style-parser: 0.2.4 - tar-fs@2.1.2: + styled-jsx@5.1.6(react@19.1.0): dependencies: - chownr: 1.1.4 - mkdirp-classic: 0.5.3 - pump: 3.0.2 - tar-stream: 2.2.0 + client-only: 0.0.1 + react: 19.1.0 - tar-fs@3.0.8: + supports-color@7.2.0: dependencies: - pump: 3.0.2 - tar-stream: 3.1.7 - optionalDependencies: - bare-fs: 4.0.1 - bare-path: 3.0.0 - transitivePeerDependencies: - - bare-buffer + has-flag: 4.0.0 - tar-stream@2.2.0: - dependencies: - bl: 4.1.0 - end-of-stream: 1.4.4 - fs-constants: 1.0.0 - inherits: 2.0.4 - readable-stream: 3.6.2 + supports-preserve-symlinks-flag@1.0.0: {} - tar-stream@3.1.7: - dependencies: - b4a: 1.6.7 - fast-fifo: 1.3.2 - streamx: 2.22.0 + tailwind-merge@3.2.0: {} - text-decoder@1.2.3: - dependencies: - b4a: 1.6.7 + tailwindcss@4.1.4: {} - tinyexec@0.3.2: {} + tapable@2.2.1: {} + + text-table@0.2.0: {} tinyglobby@0.2.12: dependencies: fdir: 6.4.3(picomatch@4.0.2) picomatch: 4.0.2 + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + trim-lines@3.0.1: {} trough@2.2.0: {} - tsconfck@3.1.5(typescript@5.8.2): - optionalDependencies: - typescript: 5.8.2 - - tslib@2.8.1: - optional: true - - tunnel-agent@0.6.0: + ts-api-utils@2.1.0(typescript@5.8.3): dependencies: - safe-buffer: 5.2.1 + typescript: 5.8.3 - type-fest@4.37.0: {} + tsconfig-paths@3.15.0: + dependencies: + '@types/json5': 0.0.29 + json5: 1.0.2 + minimist: 1.2.8 + strip-bom: 3.0.0 - typescript@5.8.2: {} + tslib@2.8.1: {} - ufo@1.5.4: {} + tw-animate-css@1.2.8: {} - ultrahtml@1.5.3: {} + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 - uncrypto@0.1.3: {} + type-fest@0.20.2: {} + + typed-array-buffer@1.0.3: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-typed-array: 1.1.15 + + typed-array-byte-length@1.0.3: + dependencies: + call-bind: 1.0.8 + for-each: 0.3.5 + gopd: 1.2.0 + has-proto: 1.2.0 + is-typed-array: 1.1.15 + + typed-array-byte-offset@1.0.4: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + for-each: 0.3.5 + gopd: 1.2.0 + has-proto: 1.2.0 + is-typed-array: 1.1.15 + reflect.getprototypeof: 1.0.10 + + typed-array-length@1.0.7: + dependencies: + call-bind: 1.0.8 + for-each: 0.3.5 + gopd: 1.2.0 + is-typed-array: 1.1.15 + possible-typed-array-names: 1.1.0 + reflect.getprototypeof: 1.0.10 + + typescript@5.8.3: {} + + unbox-primitive@1.1.0: + dependencies: + call-bound: 1.0.4 + has-bigints: 1.1.0 + has-symbols: 1.1.0 + which-boxed-primitive: 1.1.1 + + undici-types@6.21.0: {} unified@11.0.5: dependencies: @@ -4078,20 +6360,10 @@ snapshots: trough: 2.2.0 vfile: 6.0.3 - unist-util-find-after@5.0.0: - dependencies: - '@types/unist': 3.0.3 - unist-util-is: 6.0.0 - unist-util-is@6.0.0: dependencies: '@types/unist': 3.0.3 - unist-util-modify-children@4.0.0: - dependencies: - '@types/unist': 3.0.3 - array-iterate: 2.0.1 - unist-util-position-from-estree@2.0.0: dependencies: '@types/unist': 3.0.3 @@ -4100,19 +6372,10 @@ snapshots: dependencies: '@types/unist': 3.0.3 - unist-util-remove-position@5.0.0: - dependencies: - '@types/unist': 3.0.3 - unist-util-visit: 5.0.0 - unist-util-stringify-position@4.0.0: dependencies: '@types/unist': 3.0.3 - unist-util-visit-children@3.0.0: - dependencies: - '@types/unist': 3.0.3 - unist-util-visit-parents@6.0.1: dependencies: '@types/unist': 3.0.3 @@ -4124,24 +6387,46 @@ snapshots: unist-util-is: 6.0.0 unist-util-visit-parents: 6.0.1 - unstorage@1.15.0: + unrs-resolver@1.5.0: + optionalDependencies: + '@unrs/resolver-binding-darwin-arm64': 1.5.0 + '@unrs/resolver-binding-darwin-x64': 1.5.0 + '@unrs/resolver-binding-freebsd-x64': 1.5.0 + '@unrs/resolver-binding-linux-arm-gnueabihf': 1.5.0 + '@unrs/resolver-binding-linux-arm-musleabihf': 1.5.0 + '@unrs/resolver-binding-linux-arm64-gnu': 1.5.0 + '@unrs/resolver-binding-linux-arm64-musl': 1.5.0 + '@unrs/resolver-binding-linux-ppc64-gnu': 1.5.0 + '@unrs/resolver-binding-linux-riscv64-gnu': 1.5.0 + '@unrs/resolver-binding-linux-s390x-gnu': 1.5.0 + '@unrs/resolver-binding-linux-x64-gnu': 1.5.0 + '@unrs/resolver-binding-linux-x64-musl': 1.5.0 + '@unrs/resolver-binding-wasm32-wasi': 1.5.0 + '@unrs/resolver-binding-win32-arm64-msvc': 1.5.0 + '@unrs/resolver-binding-win32-ia32-msvc': 1.5.0 + '@unrs/resolver-binding-win32-x64-msvc': 1.5.0 + + uri-js@4.4.1: dependencies: - anymatch: 3.1.3 - chokidar: 4.0.3 - destr: 2.0.3 - h3: 1.15.1 - lru-cache: 10.4.3 - node-fetch-native: 1.6.6 - ofetch: 1.4.1 - ufo: 1.5.4 + punycode: 2.3.1 + + use-callback-ref@1.3.3(@types/react@19.1.2)(react@19.1.0): + dependencies: + react: 19.1.0 + tslib: 2.8.1 + optionalDependencies: + '@types/react': 19.1.2 + + use-sidecar@1.1.3(@types/react@19.1.2)(react@19.1.0): + dependencies: + detect-node-es: 1.1.0 + react: 19.1.0 + tslib: 2.8.1 + optionalDependencies: + '@types/react': 19.1.2 util-deprecate@1.0.2: {} - vfile-location@5.0.3: - dependencies: - '@types/unist': 3.0.3 - vfile: 6.0.3 - vfile-message@4.0.2: dependencies: '@types/unist': 3.0.3 @@ -4152,54 +6437,56 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.2 - vite@6.2.2: + which-boxed-primitive@1.1.1: dependencies: - esbuild: 0.25.1 - postcss: 8.5.3 - rollup: 4.35.0 - optionalDependencies: - fsevents: 2.3.3 + is-bigint: 1.1.0 + is-boolean-object: 1.2.2 + is-number-object: 1.1.1 + is-string: 1.1.1 + is-symbol: 1.1.1 - vitefu@1.0.6(vite@6.2.2): - optionalDependencies: - vite: 6.2.2 - - web-namespaces@2.0.1: {} - - which-pm-runs@1.1.0: {} - - widest-line@5.0.0: + which-builtin-type@1.2.1: dependencies: - string-width: 7.2.0 + call-bound: 1.0.4 + function.prototype.name: 1.1.8 + has-tostringtag: 1.0.2 + is-async-function: 2.1.1 + is-date-object: 1.1.0 + is-finalizationregistry: 1.1.1 + is-generator-function: 1.1.0 + is-regex: 1.2.1 + is-weakref: 1.1.1 + isarray: 2.0.5 + which-boxed-primitive: 1.1.1 + which-collection: 1.0.2 + which-typed-array: 1.1.19 - wrap-ansi@9.0.0: + which-collection@1.0.2: dependencies: - ansi-styles: 6.2.1 - string-width: 7.2.0 - strip-ansi: 7.1.0 + is-map: 2.0.3 + is-set: 2.0.3 + is-weakmap: 2.0.2 + is-weakset: 2.0.4 + + which-typed-array@1.1.19: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + call-bound: 1.0.4 + for-each: 0.3.5 + get-proto: 1.0.1 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + word-wrap@1.2.5: {} wrappy@1.0.2: {} - xxhash-wasm@1.1.0: {} - - yargs-parser@21.1.1: {} - - yocto-queue@1.2.0: {} - - yocto-spinner@0.2.1: - dependencies: - yoctocolors: 2.1.1 - - yoctocolors@2.1.1: {} - - zod-to-json-schema@3.24.3(zod@3.24.2): - dependencies: - zod: 3.24.2 - - zod-to-ts@1.2.0(typescript@5.8.2)(zod@3.24.2): - dependencies: - typescript: 5.8.2 - zod: 3.24.2 + yocto-queue@0.1.0: {} zod@3.24.2: {} diff --git a/apps/docs/postcss.config.mjs b/apps/docs/postcss.config.mjs new file mode 100644 index 0000000..a34a3d5 --- /dev/null +++ b/apps/docs/postcss.config.mjs @@ -0,0 +1,5 @@ +export default { + plugins: { + '@tailwindcss/postcss': {}, + }, +}; diff --git a/apps/docs/public/api-docs/scalar.png b/apps/docs/public/assets/v1/api-docs/scalar.png similarity index 100% rename from apps/docs/public/api-docs/scalar.png rename to apps/docs/public/assets/v1/api-docs/scalar.png diff --git a/apps/docs/public/api-docs/swagger.png b/apps/docs/public/assets/v1/api-docs/swagger.png similarity index 100% rename from apps/docs/public/api-docs/swagger.png rename to apps/docs/public/assets/v1/api-docs/swagger.png diff --git a/apps/docs/public/developers/issues-tab.png b/apps/docs/public/assets/v1/developers/issues-tab.png similarity index 100% rename from apps/docs/public/developers/issues-tab.png rename to apps/docs/public/assets/v1/developers/issues-tab.png diff --git a/apps/docs/public/developers/new-issue-btn.png b/apps/docs/public/assets/v1/developers/new-issue-btn.png similarity index 100% rename from apps/docs/public/developers/new-issue-btn.png rename to apps/docs/public/assets/v1/developers/new-issue-btn.png diff --git a/apps/docs/public/developers/new-issue-form.png b/apps/docs/public/assets/v1/developers/new-issue-form.png similarity index 100% rename from apps/docs/public/developers/new-issue-form.png rename to apps/docs/public/assets/v1/developers/new-issue-form.png diff --git a/apps/docs/public/general/architecture.png b/apps/docs/public/assets/v1/general/architecture.png similarity index 100% rename from apps/docs/public/general/architecture.png rename to apps/docs/public/assets/v1/general/architecture.png diff --git a/apps/docs/public/general/banner.png b/apps/docs/public/assets/v1/general/banner.png similarity index 100% rename from apps/docs/public/general/banner.png rename to apps/docs/public/assets/v1/general/banner.png diff --git a/apps/docs/public/general/lp.png b/apps/docs/public/assets/v1/general/lp.png similarity index 100% rename from apps/docs/public/general/lp.png rename to apps/docs/public/assets/v1/general/lp.png diff --git a/apps/docs/public/main/files/actions-dropdown.png b/apps/docs/public/assets/v1/main/files/actions-dropdown.png similarity index 100% rename from apps/docs/public/main/files/actions-dropdown.png rename to apps/docs/public/assets/v1/main/files/actions-dropdown.png diff --git a/apps/docs/public/main/files/edit-modal.png b/apps/docs/public/assets/v1/main/files/edit-modal.png similarity index 100% rename from apps/docs/public/main/files/edit-modal.png rename to apps/docs/public/assets/v1/main/files/edit-modal.png diff --git a/apps/docs/public/main/files/my-files-card.png b/apps/docs/public/assets/v1/main/files/my-files-card.png similarity index 100% rename from apps/docs/public/main/files/my-files-card.png rename to apps/docs/public/assets/v1/main/files/my-files-card.png diff --git a/apps/docs/public/main/files/my-files-page.png b/apps/docs/public/assets/v1/main/files/my-files-page.png similarity index 100% rename from apps/docs/public/main/files/my-files-page.png rename to apps/docs/public/assets/v1/main/files/my-files-page.png diff --git a/apps/docs/public/main/language/language-selector.png b/apps/docs/public/assets/v1/main/language/language-selector.png similarity index 100% rename from apps/docs/public/main/language/language-selector.png rename to apps/docs/public/assets/v1/main/language/language-selector.png diff --git a/apps/docs/public/main/shares/actions-column.png b/apps/docs/public/assets/v1/main/shares/actions-column.png similarity index 100% rename from apps/docs/public/main/shares/actions-column.png rename to apps/docs/public/assets/v1/main/shares/actions-column.png diff --git a/apps/docs/public/main/shares/copy-link-modal.png b/apps/docs/public/assets/v1/main/shares/copy-link-modal.png similarity index 100% rename from apps/docs/public/main/shares/copy-link-modal.png rename to apps/docs/public/assets/v1/main/shares/copy-link-modal.png diff --git a/apps/docs/public/main/shares/create-first-share.png b/apps/docs/public/assets/v1/main/shares/create-first-share.png similarity index 100% rename from apps/docs/public/main/shares/create-first-share.png rename to apps/docs/public/assets/v1/main/shares/create-first-share.png diff --git a/apps/docs/public/main/shares/create-share-modal.png b/apps/docs/public/assets/v1/main/shares/create-share-modal.png similarity index 100% rename from apps/docs/public/main/shares/create-share-modal.png rename to apps/docs/public/assets/v1/main/shares/create-share-modal.png diff --git a/apps/docs/public/main/shares/delete-share-modal.png b/apps/docs/public/assets/v1/main/shares/delete-share-modal.png similarity index 100% rename from apps/docs/public/main/shares/delete-share-modal.png rename to apps/docs/public/assets/v1/main/shares/delete-share-modal.png diff --git a/apps/docs/public/main/shares/dropdown-with-copy.png b/apps/docs/public/assets/v1/main/shares/dropdown-with-copy.png similarity index 100% rename from apps/docs/public/main/shares/dropdown-with-copy.png rename to apps/docs/public/assets/v1/main/shares/dropdown-with-copy.png diff --git a/apps/docs/public/main/shares/edit-share-modal.png b/apps/docs/public/assets/v1/main/shares/edit-share-modal.png similarity index 100% rename from apps/docs/public/main/shares/edit-share-modal.png rename to apps/docs/public/assets/v1/main/shares/edit-share-modal.png diff --git a/apps/docs/public/main/shares/generate-share-link-modal.png b/apps/docs/public/assets/v1/main/shares/generate-share-link-modal.png similarity index 100% rename from apps/docs/public/main/shares/generate-share-link-modal.png rename to apps/docs/public/assets/v1/main/shares/generate-share-link-modal.png diff --git a/apps/docs/public/main/shares/manage-files-modal.png b/apps/docs/public/assets/v1/main/shares/manage-files-modal.png similarity index 100% rename from apps/docs/public/main/shares/manage-files-modal.png rename to apps/docs/public/assets/v1/main/shares/manage-files-modal.png diff --git a/apps/docs/public/main/shares/manage-recipients-modal.png b/apps/docs/public/assets/v1/main/shares/manage-recipients-modal.png similarity index 100% rename from apps/docs/public/main/shares/manage-recipients-modal.png rename to apps/docs/public/assets/v1/main/shares/manage-recipients-modal.png diff --git a/apps/docs/public/main/shares/my-shares-card.png b/apps/docs/public/assets/v1/main/shares/my-shares-card.png similarity index 100% rename from apps/docs/public/main/shares/my-shares-card.png rename to apps/docs/public/assets/v1/main/shares/my-shares-card.png diff --git a/apps/docs/public/main/shares/my-shares-page.png b/apps/docs/public/assets/v1/main/shares/my-shares-page.png similarity index 100% rename from apps/docs/public/main/shares/my-shares-page.png rename to apps/docs/public/assets/v1/main/shares/my-shares-page.png diff --git a/apps/docs/public/main/shares/new-share-btn.png b/apps/docs/public/assets/v1/main/shares/new-share-btn.png similarity index 100% rename from apps/docs/public/main/shares/new-share-btn.png rename to apps/docs/public/assets/v1/main/shares/new-share-btn.png diff --git a/apps/docs/public/main/shares/recent-shares-filled.png b/apps/docs/public/assets/v1/main/shares/recent-shares-filled.png similarity index 100% rename from apps/docs/public/main/shares/recent-shares-filled.png rename to apps/docs/public/assets/v1/main/shares/recent-shares-filled.png diff --git a/apps/docs/public/main/shares/share-details-modal.png b/apps/docs/public/assets/v1/main/shares/share-details-modal.png similarity index 100% rename from apps/docs/public/main/shares/share-details-modal.png rename to apps/docs/public/assets/v1/main/shares/share-details-modal.png diff --git a/apps/docs/public/main/shares/share-screen.png b/apps/docs/public/assets/v1/main/shares/share-screen.png similarity index 100% rename from apps/docs/public/main/shares/share-screen.png rename to apps/docs/public/assets/v1/main/shares/share-screen.png diff --git a/apps/docs/public/main/shares/share-section.png b/apps/docs/public/assets/v1/main/shares/share-section.png similarity index 100% rename from apps/docs/public/main/shares/share-section.png rename to apps/docs/public/assets/v1/main/shares/share-section.png diff --git a/apps/docs/public/main/shares/shares-table.png b/apps/docs/public/assets/v1/main/shares/shares-table.png similarity index 100% rename from apps/docs/public/main/shares/shares-table.png rename to apps/docs/public/assets/v1/main/shares/shares-table.png diff --git a/apps/docs/public/main/shares/view-all-button.png b/apps/docs/public/assets/v1/main/shares/view-all-button.png similarity index 100% rename from apps/docs/public/main/shares/view-all-button.png rename to apps/docs/public/assets/v1/main/shares/view-all-button.png diff --git a/apps/docs/public/main/smtp/closed-card.png b/apps/docs/public/assets/v1/main/smtp/closed-card.png similarity index 100% rename from apps/docs/public/main/smtp/closed-card.png rename to apps/docs/public/assets/v1/main/smtp/closed-card.png diff --git a/apps/docs/public/main/smtp/dropdown-menu.png b/apps/docs/public/assets/v1/main/smtp/dropdown-menu.png similarity index 100% rename from apps/docs/public/main/smtp/dropdown-menu.png rename to apps/docs/public/assets/v1/main/smtp/dropdown-menu.png diff --git a/apps/docs/public/main/smtp/opened-card.png b/apps/docs/public/assets/v1/main/smtp/opened-card.png similarity index 100% rename from apps/docs/public/main/smtp/opened-card.png rename to apps/docs/public/assets/v1/main/smtp/opened-card.png diff --git a/apps/docs/public/main/smtp/smtp-enabled.png b/apps/docs/public/assets/v1/main/smtp/smtp-enabled.png similarity index 100% rename from apps/docs/public/main/smtp/smtp-enabled.png rename to apps/docs/public/assets/v1/main/smtp/smtp-enabled.png diff --git a/apps/docs/public/main/upload/new-upload-button.png b/apps/docs/public/assets/v1/main/upload/new-upload-button.png similarity index 100% rename from apps/docs/public/main/upload/new-upload-button.png rename to apps/docs/public/assets/v1/main/upload/new-upload-button.png diff --git a/apps/docs/public/main/upload/preview-example.png b/apps/docs/public/assets/v1/main/upload/preview-example.png similarity index 100% rename from apps/docs/public/main/upload/preview-example.png rename to apps/docs/public/assets/v1/main/upload/preview-example.png diff --git a/apps/docs/public/main/upload/recent-uploads-filled.png b/apps/docs/public/assets/v1/main/upload/recent-uploads-filled.png similarity index 100% rename from apps/docs/public/main/upload/recent-uploads-filled.png rename to apps/docs/public/assets/v1/main/upload/recent-uploads-filled.png diff --git a/apps/docs/public/main/upload/recent-uploads.png b/apps/docs/public/assets/v1/main/upload/recent-uploads.png similarity index 100% rename from apps/docs/public/main/upload/recent-uploads.png rename to apps/docs/public/assets/v1/main/upload/recent-uploads.png diff --git a/apps/docs/public/main/upload/upload-cancel-buttons.png b/apps/docs/public/assets/v1/main/upload/upload-cancel-buttons.png similarity index 100% rename from apps/docs/public/main/upload/upload-cancel-buttons.png rename to apps/docs/public/assets/v1/main/upload/upload-cancel-buttons.png diff --git a/apps/docs/public/main/upload/upload-file-button.png b/apps/docs/public/assets/v1/main/upload/upload-file-button.png similarity index 100% rename from apps/docs/public/main/upload/upload-file-button.png rename to apps/docs/public/assets/v1/main/upload/upload-file-button.png diff --git a/apps/docs/public/main/upload/view-all-button.png b/apps/docs/public/assets/v1/main/upload/view-all-button.png similarity index 100% rename from apps/docs/public/main/upload/view-all-button.png rename to apps/docs/public/assets/v1/main/upload/view-all-button.png diff --git a/apps/docs/public/main/users/add-user-actions-dropdown.png b/apps/docs/public/assets/v1/main/users/add-user-actions-dropdown.png similarity index 100% rename from apps/docs/public/main/users/add-user-actions-dropdown.png rename to apps/docs/public/assets/v1/main/users/add-user-actions-dropdown.png diff --git a/apps/docs/public/main/users/add-user-modal.png b/apps/docs/public/assets/v1/main/users/add-user-modal.png similarity index 100% rename from apps/docs/public/main/users/add-user-modal.png rename to apps/docs/public/assets/v1/main/users/add-user-modal.png diff --git a/apps/docs/public/main/users/add-users-btn.png b/apps/docs/public/assets/v1/main/users/add-users-btn.png similarity index 100% rename from apps/docs/public/main/users/add-users-btn.png rename to apps/docs/public/assets/v1/main/users/add-users-btn.png diff --git a/apps/docs/public/main/users/edit-user-modal.png b/apps/docs/public/assets/v1/main/users/edit-user-modal.png similarity index 100% rename from apps/docs/public/main/users/edit-user-modal.png rename to apps/docs/public/assets/v1/main/users/edit-user-modal.png diff --git a/apps/docs/public/main/users/new-user-table.png b/apps/docs/public/assets/v1/main/users/new-user-table.png similarity index 100% rename from apps/docs/public/main/users/new-user-table.png rename to apps/docs/public/assets/v1/main/users/new-user-table.png diff --git a/apps/docs/public/main/users/users-management.png b/apps/docs/public/assets/v1/main/users/users-management.png similarity index 100% rename from apps/docs/public/main/users/users-management.png rename to apps/docs/public/assets/v1/main/users/users-management.png diff --git a/apps/docs/public/sponsor/sponsor-btn.png b/apps/docs/public/assets/v1/sponsor/sponsor-btn.png similarity index 100% rename from apps/docs/public/sponsor/sponsor-btn.png rename to apps/docs/public/assets/v1/sponsor/sponsor-btn.png diff --git a/apps/docs/public/sponsor/sponsor-page.png b/apps/docs/public/assets/v1/sponsor/sponsor-page.png similarity index 100% rename from apps/docs/public/sponsor/sponsor-page.png rename to apps/docs/public/assets/v1/sponsor/sponsor-page.png diff --git a/apps/docs/public/sponsor/star-btn.png b/apps/docs/public/assets/v1/sponsor/star-btn.png similarity index 100% rename from apps/docs/public/sponsor/star-btn.png rename to apps/docs/public/assets/v1/sponsor/star-btn.png diff --git a/apps/docs/public/sponsor/starred-button.png b/apps/docs/public/assets/v1/sponsor/starred-button.png similarity index 100% rename from apps/docs/public/sponsor/starred-button.png rename to apps/docs/public/assets/v1/sponsor/starred-button.png diff --git a/apps/docs/public/ui/dashboard.png b/apps/docs/public/assets/v1/ui/dashboard.png similarity index 100% rename from apps/docs/public/ui/dashboard.png rename to apps/docs/public/assets/v1/ui/dashboard.png diff --git a/apps/docs/public/ui/login.png b/apps/docs/public/assets/v1/ui/login.png similarity index 100% rename from apps/docs/public/ui/login.png rename to apps/docs/public/assets/v1/ui/login.png diff --git a/apps/docs/public/ui/menu.png b/apps/docs/public/assets/v1/ui/menu.png similarity index 100% rename from apps/docs/public/ui/menu.png rename to apps/docs/public/assets/v1/ui/menu.png diff --git a/apps/docs/public/ui/profile.png b/apps/docs/public/assets/v1/ui/profile.png similarity index 100% rename from apps/docs/public/ui/profile.png rename to apps/docs/public/assets/v1/ui/profile.png diff --git a/apps/docs/public/ui/profile_picture.png b/apps/docs/public/assets/v1/ui/profile_picture.png similarity index 100% rename from apps/docs/public/ui/profile_picture.png rename to apps/docs/public/assets/v1/ui/profile_picture.png diff --git a/apps/docs/public/assets/v2/api-docs/scalar.png b/apps/docs/public/assets/v2/api-docs/scalar.png new file mode 100644 index 0000000000000000000000000000000000000000..7d1313a1c18c64b2352b19066d8ab391505dd706 GIT binary patch literal 227725 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 z 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%0DCn=5Hm?uSmM1t)Rf;+0I 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 V_PY^c!0B3Q?| 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 - - - - - - - - - diff --git a/apps/docs/source.config.ts b/apps/docs/source.config.ts new file mode 100644 index 0000000..3f2bbfd --- /dev/null +++ b/apps/docs/source.config.ts @@ -0,0 +1,12 @@ +import { defineDocs, defineConfig } from 'fumadocs-mdx/config'; + +// Options: https://fumadocs.vercel.app/docs/mdx/collections#define-docs +export const docs = defineDocs({ + dir: 'content/docs', +}); + +export default defineConfig({ + mdxOptions: { + // MDX options + }, +}); diff --git a/apps/docs/src/app/(home)/layout.tsx b/apps/docs/src/app/(home)/layout.tsx new file mode 100644 index 0000000..b6c789f --- /dev/null +++ b/apps/docs/src/app/(home)/layout.tsx @@ -0,0 +1,13 @@ +import type { ReactNode } from "react"; +import { HomeLayout } from "fumadocs-ui/layouts/home"; +import { baseOptions } from "@/app/layout.config"; +import { Particles } from "@/components/magicui/particles"; + +export default function Layout({ children }: { children: ReactNode }) { + return ( + + + {children} + + ); +} diff --git a/apps/docs/src/app/(home)/page.tsx b/apps/docs/src/app/(home)/page.tsx new file mode 100644 index 0000000..edce249 --- /dev/null +++ b/apps/docs/src/app/(home)/page.tsx @@ -0,0 +1,370 @@ +import { + type LucideIcon, + MousePointer, + UploadIcon, + Share2Icon, + GithubIcon, + BookOpenText, +} from "lucide-react"; +import { + BatteryChargingIcon, + KeyboardIcon, + LayoutIcon, + PersonStandingIcon, + RocketIcon, + SearchIcon, + TimerIcon, +} from "lucide-react"; + +import Link from "next/link"; +import type { ReactNode } from "react"; +import { ThreeDMarquee } from "@/components/ui/3d-marquee"; +import { AnimatedGridPattern } from "@/components/magicui/animated-grid-pattern"; +import { TypingAnimation } from "@/components/magicui/typing-animation"; +import { TextHoverEffect } from "@/components/ui/text-hover-effect"; +import { PulsatingButton } from "@/components/magicui/pulsating-button"; +import { RippleButton } from "@/components/magicui/ripple-button"; +import { WordRotate } from "@/components/magicui/word-rotate"; + +const images = [ + "https://res.cloudinary.com/technical-intelligence/image/upload/v1745546004/Palmr./dash_wt_kqtzxi.png", + "https://res.cloudinary.com/technical-intelligence/image/upload/v1745546004/Palmr./login_xtlnif.png", + "https://res.cloudinary.com/technical-intelligence/image/upload/v1745546005/Palmr./poase_wt_plhgwc.png", + "https://res.cloudinary.com/technical-intelligence/image/upload/v1745546005/Palmr./profile_wt_fnj3rz.png", + "https://res.cloudinary.com/technical-intelligence/image/upload/v1745546005/Palmr./settigngs_open_hjkomr.png", + "https://res.cloudinary.com/technical-intelligence/image/upload/v1745546005/Palmr./Screenshot_j0csjm.png", + "https://res.cloudinary.com/technical-intelligence/image/upload/v1745546004/Palmr./dash_cndhwr.png", + "https://res.cloudinary.com/technical-intelligence/image/upload/v1745546005/Palmr./profile_mizwvg.png", + "https://res.cloudinary.com/technical-intelligence/image/upload/v1745546005/Palmr./profile_wt_fnj3rz.png", + "https://res.cloudinary.com/technical-intelligence/image/upload/v1745546005/Palmr./poase_wt_plhgwc.png", + "https://res.cloudinary.com/technical-intelligence/image/upload/v1745546004/Palmr./dash_wt_kqtzxi.png", + "https://res.cloudinary.com/technical-intelligence/image/upload/v1745546004/Palmr./dash_cndhwr.png", + "https://res.cloudinary.com/technical-intelligence/image/upload/v1745546004/Palmr./login_xtlnif.png", + "https://res.cloudinary.com/technical-intelligence/image/upload/v1745546005/Palmr./poase_wt_plhgwc.png", + "https://res.cloudinary.com/technical-intelligence/image/upload/v1745546005/Palmr./settigngs_open_hjkomr.png", + "https://res.cloudinary.com/technical-intelligence/image/upload/v1745546005/Palmr./Screenshot_j0csjm.png", + "https://res.cloudinary.com/technical-intelligence/image/upload/v1745546004/Palmr./dash_cndhwr.png", + "https://res.cloudinary.com/technical-intelligence/image/upload/v1745546004/Palmr./login_xtlnif.png", + "https://res.cloudinary.com/technical-intelligence/image/upload/v1745546005/Palmr./profile_mizwvg.png", + "https://res.cloudinary.com/technical-intelligence/image/upload/v1745546004/Palmr./dash_wt_kqtzxi.png", + "https://res.cloudinary.com/technical-intelligence/image/upload/v1745546005/Palmr./profile_wt_fnj3rz.png", + "https://res.cloudinary.com/technical-intelligence/image/upload/v1745546005/Palmr./profile_mizwvg.png", + "https://res.cloudinary.com/technical-intelligence/image/upload/v1745546004/Palmr./dash_wt_kqtzxi.png", + "https://res.cloudinary.com/technical-intelligence/image/upload/v1745546004/Palmr./login_xtlnif.png", + "https://res.cloudinary.com/technical-intelligence/image/upload/v1745546005/Palmr./poase_wt_plhgwc.png", + "https://res.cloudinary.com/technical-intelligence/image/upload/v1745546005/Palmr./settigngs_open_hjkomr.png", + "https://res.cloudinary.com/technical-intelligence/image/upload/v1745546005/Palmr./Screenshot_j0csjm.png", + "https://res.cloudinary.com/technical-intelligence/image/upload/v1745546004/Palmr./dash_cndhwr.png", + "https://res.cloudinary.com/technical-intelligence/image/upload/v1745546005/Palmr./profile_mizwvg.png", +]; + +const docsLink = "/docs/2.0.0-beta"; + +export default function HomePage() { + return ( + <> +

+
+ + + + + + + + +
+
+ + + ); +} + +function Hero() { + return ( +
+

🌴 Palmr. v2.0.0-beta

+

+ Modern & efficient file sharing +

+

+ Palmr is a fast and secure platform for sharing files, built with + performance and privacy in mind. +

+
+ +
+
+
+ ); +} + +function LogoShowcase() { + return ( +
+ +
+ ); +} + +function Feedback() { + return ( +
+

+ A modern way to share files + +

+
+ ); +} + +export function Introduction() { + return ( +
+
+
+
+ +
+

Upload.

+
+

+ Send your files quickly and safely. +

+
+
+
+
+ +
+

Share.

+
+

Easily share with anyone.

+
+
+ ); +} + +function Architecture() { + return ( +
+
+

+ Carefully Built +

+

+ A complete solution for file sharing. +

+

+ From the upload to the link generation, everything is designed to be + fast, reliable, and privacy-friendly. +
+
+ Every feature was crafted to deliver the best possible experience. +

+
+
+ ); +} + +function FileSection() { + return ( +
+

+ File Sharing + + Free & Open Source + +

+ +
+ ); +} + +function Highlights() { + const features = [ + { + icon: TimerIcon, + title: "Fast & Efficient", + text: "Optimized upload and download speeds.", + }, + { + icon: LayoutIcon, + title: "Intuitive UI", + text: "Clean, modern, and easy to use.", + }, + { + icon: RocketIcon, + title: "Modern Stack", + text: "Powered by Next.js, Fastify, MinIO, Postgres and the latest tech.", + }, + { + icon: SearchIcon, + title: "Smart Search", + text: "Find shared files quickly.", + }, + { + icon: KeyboardIcon, + title: "Open API", + text: "REST API endpoinds available for any integrations.", + }, + { + icon: PersonStandingIcon, + title: "Customizable", + text: "Full control over all the system and configurations.", + }, + ]; + + return ( +
+
+

+ Highlights +

+ +
+ {features.map(({ icon, title, text }, i) => ( + + {text} + + ))} +
+ ); +} + +function Highlight({ + icon: Icon, + heading, + children, +}: { + icon: LucideIcon; + heading: ReactNode; + children: ReactNode; +}) { + return ( +
+
+ +

{heading}

+
+ {children} +
+ ); +} + +function End() { + return ( +
+
+

+ Start Using Now. 🌴 +

+
    + + Get up and running in minutes. + + + Take full control of your file sharing infrastructure. + +
+
+ +
+ + Documentation +
+
+ + + + GitHub + + +
+
+
+ ); +} + +function ListItem({ + icon: Icon, + title, + children, +}: { + icon: LucideIcon; + title: string; + children: ReactNode; +}) { + return ( +
  • + + + {title} + + + {children} + +
  • + ); +} + +function FullWidthFooter() { + return ( +
    +
    + Powered by + + Kyantech Solutions © + +
    +
    + ); +} diff --git a/apps/docs/src/app/api/search/route.ts b/apps/docs/src/app/api/search/route.ts new file mode 100644 index 0000000..278a9da --- /dev/null +++ b/apps/docs/src/app/api/search/route.ts @@ -0,0 +1,16 @@ +import { source } from '@/lib/source'; +import { createFromSource } from 'fumadocs-core/search/server'; + +export const { GET } = createFromSource(source, (page) => { + // Log the page URL for debugging + console.log('Page URL:', page.url); + + return { + title: page.data.title, + description: page.data.description, + url: page.url, + id: page.url, + structuredData: page.data.structuredData, + tag: page.url.startsWith('/docs/2.0.0-beta') ? 'v2.0.0-beta' : 'v1.1.7-beta' + }; +}); diff --git a/apps/docs/src/app/docs/[[...slug]]/page.tsx b/apps/docs/src/app/docs/[[...slug]]/page.tsx new file mode 100644 index 0000000..23c004a --- /dev/null +++ b/apps/docs/src/app/docs/[[...slug]]/page.tsx @@ -0,0 +1,62 @@ +import { source } from "@/lib/source"; +import { + DocsPage, + DocsBody, + DocsDescription, + DocsTitle, +} from "fumadocs-ui/page"; +import { notFound } from "next/navigation"; +import { createRelativeLink } from "fumadocs-ui/mdx"; +import { getMDXComponents } from "@/mdx-components"; +import { Footer } from "../components/footer"; +import { Sponsor } from "../components/sponsor"; + +export default async function Page(props: { + params: Promise<{ slug?: string[] }>; +}) { + const params = await props.params; + const page = source.getPage(params.slug); + if (!page) notFound(); + + const MDXContent = page.data.body; + + return ( + }} + tableOfContent={{ + style: "clerk", + footer: + }} + > + {page.data.title} +
    + {page.data.description} + + + +
    + ); +} + +export async function generateStaticParams() { + return source.generateParams(); +} + +export async function generateMetadata(props: { + params: Promise<{ slug?: string[] }>; +}) { + const params = await props.params; + const page = source.getPage(params.slug); + if (!page) notFound(); + + return { + title: page.data.title + " | 🌴 Palmr. Docs", + description: page.data.description, + }; +} diff --git a/apps/docs/src/app/docs/components/footer.tsx b/apps/docs/src/app/docs/components/footer.tsx new file mode 100644 index 0000000..0042738 --- /dev/null +++ b/apps/docs/src/app/docs/components/footer.tsx @@ -0,0 +1,19 @@ +import Link from 'fumadocs-core/link'; + +export function Footer() { + return ( +
    +
    + Powered by + + Kyantech Solutions © + +
    +
    + ); +} \ No newline at end of file diff --git a/apps/docs/src/app/docs/components/sponsor.tsx b/apps/docs/src/app/docs/components/sponsor.tsx new file mode 100644 index 0000000..a1dce57 --- /dev/null +++ b/apps/docs/src/app/docs/components/sponsor.tsx @@ -0,0 +1,17 @@ +import { Coffee } from "lucide-react"; + +export function Sponsor() { + return ( + + ); +} diff --git a/apps/docs/src/app/docs/layout.tsx b/apps/docs/src/app/docs/layout.tsx new file mode 100644 index 0000000..668b556 --- /dev/null +++ b/apps/docs/src/app/docs/layout.tsx @@ -0,0 +1,12 @@ +import { DocsLayout } from 'fumadocs-ui/layouts/docs'; +import type { ReactNode } from 'react'; +import { baseOptions } from '@/app/layout.config'; +import { source } from '@/lib/source'; + +export default function Layout({ children }: { children: ReactNode }) { + return ( + + {children} + + ); +} diff --git a/apps/docs/src/app/global.css b/apps/docs/src/app/global.css new file mode 100644 index 0000000..5efd5c6 --- /dev/null +++ b/apps/docs/src/app/global.css @@ -0,0 +1,196 @@ +@import "tailwindcss"; +@import "fumadocs-ui/css/neutral.css"; +@import "fumadocs-ui/css/preset.css"; +@import "tw-animate-css"; + +@custom-variant dark (&:is(.dark *)); +/* @import 'fumadocs-ui/css/black.css'; */ + +@source '../../node_modules/fumadocs-ui/dist/**/*.js'; + +code { + color: #eb5757; +} + +h4 { + margin-bottom: 1rem; + margin-top: 3rem; + font-size: 1.1rem; +} + +.prose h3 { + font-size: 1.25rem; +} + +@theme inline { + --radius-sm: calc(var(--radius) - 4px); + --radius-md: calc(var(--radius) - 2px); + --radius-lg: var(--radius); + --radius-xl: calc(var(--radius) + 4px); + --color-background: var(--background); + --color-foreground: var(--foreground); + --color-card: var(--card); + --color-card-foreground: var(--card-foreground); + --color-popover: var(--popover); + --color-popover-foreground: var(--popover-foreground); + --color-primary: var(--primary); + --color-primary-foreground: var(--primary-foreground); + --color-secondary: var(--secondary); + --color-secondary-foreground: var(--secondary-foreground); + --color-muted: var(--muted); + --color-muted-foreground: var(--muted-foreground); + --color-accent: var(--accent); + --color-accent-foreground: var(--accent-foreground); + --color-destructive: var(--destructive); + --color-border: var(--border); + --color-input: var(--input); + --color-ring: var(--ring); + --color-chart-1: var(--chart-1); + --color-chart-2: var(--chart-2); + --color-chart-3: var(--chart-3); + --color-chart-4: var(--chart-4); + --color-chart-5: var(--chart-5); + --color-sidebar: var(--sidebar); + --color-sidebar-foreground: var(--sidebar-foreground); + --color-sidebar-primary: var(--sidebar-primary); + --color-sidebar-primary-foreground: var(--sidebar-primary-foreground); + --color-sidebar-accent: var(--sidebar-accent); + --color-sidebar-accent-foreground: var(--sidebar-accent-foreground); + --color-sidebar-border: var(--sidebar-border); + --color-sidebar-ring: var(--sidebar-ring); + --animate-ripple: ripple var(--duration,2s) ease calc(var(--i, 0)*.2s) infinite; + @keyframes ripple { + 0%, 100% { + transform: translate(-50%, -50%) scale(1); + } + 50% { + transform: translate(-50%, -50%) scale(0.9); + } + } + --animate-pulse: pulse var(--duration) ease-out infinite +; + @keyframes pulse { + 0%, 100% { + boxShadow: 0 0 0 0 var(--pulse-color); + } + 50% { + boxShadow: 0 0 0 8px var(--pulse-color); + } + } + --animate-rippling: rippling var(--duration) ease-out; + @keyframes rippling { + 0% { + opacity: 1; + } + 100% { + transform: scale(2); + opacity: 0; + } + }} + +:root { + --radius: 0.625rem; + --background: oklch(1 0 0); + --foreground: oklch(0.145 0 0); + --card: oklch(1 0 0); + --card-foreground: oklch(0.145 0 0); + --popover: oklch(1 0 0); + --popover-foreground: oklch(0.145 0 0); + --primary: oklch(0.205 0 0); + --primary-foreground: oklch(0.985 0 0); + --secondary: oklch(0.97 0 0); + --secondary-foreground: oklch(0.205 0 0); + --muted: oklch(0.97 0 0); + --muted-foreground: oklch(0.556 0 0); + --accent: oklch(0.97 0 0); + --accent-foreground: oklch(0.205 0 0); + --destructive: oklch(0.577 0.245 27.325); + --border: oklch(0.922 0 0); + --input: oklch(0.922 0 0); + --ring: oklch(0.708 0 0); + --chart-1: oklch(0.646 0.222 41.116); + --chart-2: oklch(0.6 0.118 184.704); + --chart-3: oklch(0.398 0.07 227.392); + --chart-4: oklch(0.828 0.189 84.429); + --chart-5: oklch(0.769 0.188 70.08); + --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 { + --background: oklch(0.145 0 0); + --foreground: oklch(0.985 0 0); + --card: oklch(0.205 0 0); + --card-foreground: oklch(0.985 0 0); + --popover: oklch(0.205 0 0); + --popover-foreground: oklch(0.985 0 0); + --primary: oklch(0.922 0 0); + --primary-foreground: oklch(0.205 0 0); + --secondary: oklch(0.269 0 0); + --secondary-foreground: oklch(0.985 0 0); + --muted: oklch(0.269 0 0); + --muted-foreground: oklch(0.708 0 0); + --accent: oklch(0.269 0 0); + --accent-foreground: oklch(0.985 0 0); + --destructive: oklch(0.704 0.191 22.216); + --border: oklch(1 0 0 / 10%); + --input: oklch(1 0 0 / 15%); + --ring: oklch(0.556 0 0); + --chart-1: oklch(0.488 0.243 264.376); + --chart-2: oklch(0.696 0.17 162.48); + --chart-3: oklch(0.769 0.188 70.08); + --chart-4: oklch(0.627 0.265 303.9); + --chart-5: oklch(0.645 0.246 16.439); + --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.556 0 0); +} + +@layer base { + * { + @apply border-border outline-ring/50; + } + body { + @apply bg-background text-foreground; + } +} + +@theme inline { + --animate-pulse: pulse var(--duration) ease-out infinite; + + @keyframes pulse { + 0%, + 100% { + box-shadow: 0 0 0 0 var(--pulse-color); + } + 50% { + box-shadow: 0 0 0 8px var(--pulse-color); + } + } +} + + +@theme inline { + --animate-rippling: rippling var(--duration) ease-out; + + @keyframes rippling { + 0% { + opacity: 1; + } + 100% { + transform: scale(2); + opacity: 0; + } + } +} \ No newline at end of file diff --git a/apps/docs/src/app/layout.config.tsx b/apps/docs/src/app/layout.config.tsx new file mode 100644 index 0000000..2544361 --- /dev/null +++ b/apps/docs/src/app/layout.config.tsx @@ -0,0 +1,25 @@ +import type { BaseLayoutProps } from "fumadocs-ui/layouts/shared"; +import { Github } from "lucide-react"; + +export const baseOptions: BaseLayoutProps = { + nav: { + title: "🌴 Palmr.", + }, + links: [ + { + text: "Docs", + url: "/docs/2.0.0-beta", + active: "nested-url", + }, + { + text: "Github", + url: "https://github.com/kyantech/Palmr", + active: "nested-url", + icon: ( + <> + + + ), + } + ], +}; diff --git a/apps/docs/src/app/layout.tsx b/apps/docs/src/app/layout.tsx new file mode 100644 index 0000000..0087922 --- /dev/null +++ b/apps/docs/src/app/layout.tsx @@ -0,0 +1,51 @@ +import { Banner } from "fumadocs-ui/components/banner"; +import "./global.css"; +import { RootProvider } from "fumadocs-ui/provider"; +import { Inter } from "next/font/google"; +import type { ReactNode } from "react"; +import Link from "fumadocs-core/link"; + +const inter = Inter({ + subsets: ["latin"], +}); + +export const metadata = { + title: "🌴 Palmr. | Official Website", + description: "Palmr. is a fast, simple and powerful document sharing platform.", +}; + +export default function Layout({ children }: { children: ReactNode }) { + return ( + + + + + {children} + + + + ); +} diff --git a/apps/docs/src/components/magicui/animated-grid-pattern.tsx b/apps/docs/src/components/magicui/animated-grid-pattern.tsx new file mode 100644 index 0000000..14cf70d --- /dev/null +++ b/apps/docs/src/components/magicui/animated-grid-pattern.tsx @@ -0,0 +1,154 @@ +"use client"; + +import { motion } from "motion/react"; +import { + ComponentPropsWithoutRef, + useEffect, + useId, + useRef, + useState, +} from "react"; + +import { cn } from "@/lib/utils"; + +export interface AnimatedGridPatternProps + extends ComponentPropsWithoutRef<"svg"> { + width?: number; + height?: number; + x?: number; + y?: number; + strokeDasharray?: any; + numSquares?: number; + maxOpacity?: number; + duration?: number; + repeatDelay?: number; +} + +export function AnimatedGridPattern({ + width = 40, + height = 40, + x = -1, + y = -1, + strokeDasharray = 0, + numSquares = 50, + className, + maxOpacity = 0.5, + duration = 4, + repeatDelay = 0.5, + ...props +}: AnimatedGridPatternProps) { + const id = useId(); + const containerRef = useRef(null); + const [dimensions, setDimensions] = useState({ width: 0, height: 0 }); + const [squares, setSquares] = useState(() => generateSquares(numSquares)); + + function getPos() { + return [ + Math.floor((Math.random() * dimensions.width) / width), + Math.floor((Math.random() * dimensions.height) / height), + ]; + } + + // Adjust the generateSquares function to return objects with an id, x, and y + function generateSquares(count: number) { + return Array.from({ length: count }, (_, i) => ({ + id: i, + pos: getPos(), + })); + } + + // Function to update a single square's position + const updateSquarePosition = (id: number) => { + setSquares((currentSquares) => + currentSquares.map((sq) => + sq.id === id + ? { + ...sq, + pos: getPos(), + } + : sq, + ), + ); + }; + + // Update squares to animate in + useEffect(() => { + if (dimensions.width && dimensions.height) { + setSquares(generateSquares(numSquares)); + } + }, [dimensions, numSquares]); + + // Resize observer to update container dimensions + useEffect(() => { + const resizeObserver = new ResizeObserver((entries) => { + for (let entry of entries) { + setDimensions({ + width: entry.contentRect.width, + height: entry.contentRect.height, + }); + } + }); + + if (containerRef.current) { + resizeObserver.observe(containerRef.current); + } + + return () => { + if (containerRef.current) { + resizeObserver.unobserve(containerRef.current); + } + }; + }, [containerRef]); + + return ( + + ); +} diff --git a/apps/docs/src/components/magicui/particles.tsx b/apps/docs/src/components/magicui/particles.tsx new file mode 100644 index 0000000..ffba741 --- /dev/null +++ b/apps/docs/src/components/magicui/particles.tsx @@ -0,0 +1,313 @@ +"use client"; + +import { cn } from "@/lib/utils"; +import React, { + ComponentPropsWithoutRef, + useEffect, + useRef, + useState, +} from "react"; + +interface MousePosition { + x: number; + y: number; +} + +function MousePosition(): MousePosition { + const [mousePosition, setMousePosition] = useState({ + x: 0, + y: 0, + }); + + useEffect(() => { + const handleMouseMove = (event: MouseEvent) => { + setMousePosition({ x: event.clientX, y: event.clientY }); + }; + + window.addEventListener("mousemove", handleMouseMove); + + return () => { + window.removeEventListener("mousemove", handleMouseMove); + }; + }, []); + + return mousePosition; +} + +interface ParticlesProps extends ComponentPropsWithoutRef<"div"> { + className?: string; + quantity?: number; + staticity?: number; + ease?: number; + size?: number; + refresh?: boolean; + color?: string; + vx?: number; + vy?: number; +} + +function hexToRgb(hex: string): number[] { + hex = hex.replace("#", ""); + + if (hex.length === 3) { + hex = hex + .split("") + .map((char) => char + char) + .join(""); + } + + const hexInt = parseInt(hex, 16); + const red = (hexInt >> 16) & 255; + const green = (hexInt >> 8) & 255; + const blue = hexInt & 255; + return [red, green, blue]; +} + +type Circle = { + x: number; + y: number; + translateX: number; + translateY: number; + size: number; + alpha: number; + targetAlpha: number; + dx: number; + dy: number; + magnetism: number; +}; + +export const Particles: React.FC = ({ + className = "", + quantity = 100, + staticity = 50, + ease = 50, + size = 0.4, + refresh = false, + color = "#ffffff", + vx = 0, + vy = 0, + ...props +}) => { + const canvasRef = useRef(null); + const canvasContainerRef = useRef(null); + const context = useRef(null); + const circles = useRef([]); + const mousePosition = MousePosition(); + const mouse = useRef<{ x: number; y: number }>({ x: 0, y: 0 }); + const canvasSize = useRef<{ w: number; h: number }>({ w: 0, h: 0 }); + const dpr = typeof window !== "undefined" ? window.devicePixelRatio : 1; + const rafID = useRef(null); + const resizeTimeout = useRef(null); + + useEffect(() => { + if (canvasRef.current) { + context.current = canvasRef.current.getContext("2d"); + } + initCanvas(); + animate(); + + const handleResize = () => { + if (resizeTimeout.current) { + clearTimeout(resizeTimeout.current); + } + resizeTimeout.current = setTimeout(() => { + initCanvas(); + }, 200); + }; + + window.addEventListener("resize", handleResize); + + return () => { + if (rafID.current != null) { + window.cancelAnimationFrame(rafID.current); + } + if (resizeTimeout.current) { + clearTimeout(resizeTimeout.current); + } + window.removeEventListener("resize", handleResize); + }; + }, [color]); + + useEffect(() => { + onMouseMove(); + }, [mousePosition.x, mousePosition.y]); + + useEffect(() => { + initCanvas(); + }, [refresh]); + + const initCanvas = () => { + resizeCanvas(); + drawParticles(); + }; + + const onMouseMove = () => { + if (canvasRef.current) { + const rect = canvasRef.current.getBoundingClientRect(); + const { w, h } = canvasSize.current; + const x = mousePosition.x - rect.left - w / 2; + const y = mousePosition.y - rect.top - h / 2; + const inside = x < w / 2 && x > -w / 2 && y < h / 2 && y > -h / 2; + if (inside) { + mouse.current.x = x; + mouse.current.y = y; + } + } + }; + + const resizeCanvas = () => { + if (canvasContainerRef.current && canvasRef.current && context.current) { + canvasSize.current.w = canvasContainerRef.current.offsetWidth; + canvasSize.current.h = canvasContainerRef.current.offsetHeight; + + canvasRef.current.width = canvasSize.current.w * dpr; + canvasRef.current.height = canvasSize.current.h * dpr; + canvasRef.current.style.width = `${canvasSize.current.w}px`; + canvasRef.current.style.height = `${canvasSize.current.h}px`; + context.current.scale(dpr, dpr); + + // Clear existing particles and create new ones with exact quantity + circles.current = []; + for (let i = 0; i < quantity; i++) { + const circle = circleParams(); + drawCircle(circle); + } + } + }; + + const circleParams = (): Circle => { + const x = Math.floor(Math.random() * canvasSize.current.w); + const y = Math.floor(Math.random() * canvasSize.current.h); + const translateX = 0; + const translateY = 0; + const pSize = Math.floor(Math.random() * 2) + size; + const alpha = 0; + const targetAlpha = parseFloat((Math.random() * 0.6 + 0.1).toFixed(1)); + const dx = (Math.random() - 0.5) * 0.1; + const dy = (Math.random() - 0.5) * 0.1; + const magnetism = 0.1 + Math.random() * 4; + return { + x, + y, + translateX, + translateY, + size: pSize, + alpha, + targetAlpha, + dx, + dy, + magnetism, + }; + }; + + const rgb = hexToRgb(color); + + const drawCircle = (circle: Circle, update = false) => { + if (context.current) { + const { x, y, translateX, translateY, size, alpha } = circle; + context.current.translate(translateX, translateY); + context.current.beginPath(); + context.current.arc(x, y, size, 0, 2 * Math.PI); + context.current.fillStyle = `rgba(${rgb.join(", ")}, ${alpha})`; + context.current.fill(); + context.current.setTransform(dpr, 0, 0, dpr, 0, 0); + + if (!update) { + circles.current.push(circle); + } + } + }; + + const clearContext = () => { + if (context.current) { + context.current.clearRect( + 0, + 0, + canvasSize.current.w, + canvasSize.current.h, + ); + } + }; + + const drawParticles = () => { + clearContext(); + const particleCount = quantity; + for (let i = 0; i < particleCount; i++) { + const circle = circleParams(); + drawCircle(circle); + } + }; + + const remapValue = ( + value: number, + start1: number, + end1: number, + start2: number, + end2: number, + ): number => { + const remapped = + ((value - start1) * (end2 - start2)) / (end1 - start1) + start2; + return remapped > 0 ? remapped : 0; + }; + + const animate = () => { + clearContext(); + circles.current.forEach((circle: Circle, i: number) => { + // Handle the alpha value + const edge = [ + circle.x + circle.translateX - circle.size, // distance from left edge + canvasSize.current.w - circle.x - circle.translateX - circle.size, // distance from right edge + circle.y + circle.translateY - circle.size, // distance from top edge + canvasSize.current.h - circle.y - circle.translateY - circle.size, // distance from bottom edge + ]; + const closestEdge = edge.reduce((a, b) => Math.min(a, b)); + const remapClosestEdge = parseFloat( + remapValue(closestEdge, 0, 20, 0, 1).toFixed(2), + ); + if (remapClosestEdge > 1) { + circle.alpha += 0.02; + if (circle.alpha > circle.targetAlpha) { + circle.alpha = circle.targetAlpha; + } + } else { + circle.alpha = circle.targetAlpha * remapClosestEdge; + } + circle.x += circle.dx + vx; + circle.y += circle.dy + vy; + circle.translateX += + (mouse.current.x / (staticity / circle.magnetism) - circle.translateX) / + ease; + circle.translateY += + (mouse.current.y / (staticity / circle.magnetism) - circle.translateY) / + ease; + + drawCircle(circle, true); + + // circle gets out of the canvas + if ( + circle.x < -circle.size || + circle.x > canvasSize.current.w + circle.size || + circle.y < -circle.size || + circle.y > canvasSize.current.h + circle.size + ) { + // remove the circle from the array + circles.current.splice(i, 1); + // create a new circle + const newCircle = circleParams(); + drawCircle(newCircle); + } + }); + rafID.current = window.requestAnimationFrame(animate); + }; + + return ( + + ); +}; diff --git a/apps/docs/src/components/magicui/pulsating-button.tsx b/apps/docs/src/components/magicui/pulsating-button.tsx new file mode 100644 index 0000000..78d36ad --- /dev/null +++ b/apps/docs/src/components/magicui/pulsating-button.tsx @@ -0,0 +1,46 @@ +import React from "react"; +import { cn } from "@/lib/utils"; + +interface PulsatingButtonProps + extends React.ButtonHTMLAttributes { + pulseColor?: string; + duration?: string; +} + +export const PulsatingButton = React.forwardRef< + HTMLButtonElement, + PulsatingButtonProps +>( + ( + { + className, + children, + pulseColor = "#808080", + duration = "1.5s", + ...props + }, + ref, + ) => { + return ( + + ); + }, +); + +PulsatingButton.displayName = "PulsatingButton"; diff --git a/apps/docs/src/components/magicui/ripple-button.tsx b/apps/docs/src/components/magicui/ripple-button.tsx new file mode 100644 index 0000000..458551d --- /dev/null +++ b/apps/docs/src/components/magicui/ripple-button.tsx @@ -0,0 +1,91 @@ +"use client"; + +import { cn } from "@/lib/utils"; +import React, { MouseEvent, useEffect, useState } from "react"; + +interface RippleButtonProps + extends React.ButtonHTMLAttributes { + rippleColor?: string; + duration?: string; +} + +export const RippleButton = React.forwardRef< + HTMLButtonElement, + RippleButtonProps +>( + ( + { + className, + children, + rippleColor = "#ffffff", + duration = "600ms", + onClick, + ...props + }, + ref, + ) => { + const [buttonRipples, setButtonRipples] = useState< + Array<{ x: number; y: number; size: number; key: number }> + >([]); + + const handleClick = (event: MouseEvent) => { + createRipple(event); + onClick?.(event); + }; + + const createRipple = (event: MouseEvent) => { + const button = event.currentTarget; + const rect = button.getBoundingClientRect(); + const size = Math.max(rect.width, rect.height); + const x = event.clientX - rect.left - size / 2; + const y = event.clientY - rect.top - size / 2; + + const newRipple = { x, y, size, key: Date.now() }; + setButtonRipples((prevRipples) => [...prevRipples, newRipple]); + }; + + useEffect(() => { + if (buttonRipples.length > 0) { + const lastRipple = buttonRipples[buttonRipples.length - 1]; + const timeout = setTimeout(() => { + setButtonRipples((prevRipples) => + prevRipples.filter((ripple) => ripple.key !== lastRipple.key), + ); + }, parseInt(duration)); + return () => clearTimeout(timeout); + } + }, [buttonRipples, duration]); + + return ( + + ); + }, +); + +RippleButton.displayName = "RippleButton"; diff --git a/apps/docs/src/components/magicui/typing-animation.tsx b/apps/docs/src/components/magicui/typing-animation.tsx new file mode 100644 index 0000000..62ce90a --- /dev/null +++ b/apps/docs/src/components/magicui/typing-animation.tsx @@ -0,0 +1,90 @@ +"use client"; + +import { cn } from "@/lib/utils"; +import { motion, MotionProps } from "motion/react"; +import { useEffect, useRef, useState } from "react"; + +interface TypingAnimationProps extends MotionProps { + children: string; + className?: string; + duration?: number; + delay?: number; + as?: React.ElementType; + startOnView?: boolean; +} + +export function TypingAnimation({ + children, + className, + duration = 100, + delay = 0, + as: Component = "div", + startOnView = false, + ...props +}: TypingAnimationProps) { + const MotionComponent = motion.create(Component, { + forwardMotionProps: true, + }); + + const [displayedText, setDisplayedText] = useState(""); + const [started, setStarted] = useState(false); + const elementRef = useRef(null); + + useEffect(() => { + if (!startOnView) { + const startTimeout = setTimeout(() => { + setStarted(true); + }, delay); + return () => clearTimeout(startTimeout); + } + + const observer = new IntersectionObserver( + ([entry]) => { + if (entry.isIntersecting) { + setTimeout(() => { + setStarted(true); + }, delay); + observer.disconnect(); + } + }, + { threshold: 0.1 }, + ); + + if (elementRef.current) { + observer.observe(elementRef.current); + } + + return () => observer.disconnect(); + }, [delay, startOnView]); + + useEffect(() => { + if (!started) return; + + let i = 0; + const typingEffect = setInterval(() => { + if (i < children.length) { + setDisplayedText(children.substring(0, i + 1)); + i++; + } else { + clearInterval(typingEffect); + } + }, duration); + + return () => { + clearInterval(typingEffect); + }; + }, [children, duration, started]); + + return ( + + {displayedText} + + ); +} diff --git a/apps/docs/src/components/magicui/word-rotate.tsx b/apps/docs/src/components/magicui/word-rotate.tsx new file mode 100644 index 0000000..17be594 --- /dev/null +++ b/apps/docs/src/components/magicui/word-rotate.tsx @@ -0,0 +1,50 @@ +"use client"; + +import { AnimatePresence, motion, MotionProps } from "motion/react"; +import { useEffect, useState } from "react"; + +import { cn } from "@/lib/utils"; + +interface WordRotateProps { + words: string[]; + duration?: number; + motionProps?: MotionProps; + className?: string; +} + +export function WordRotate({ + words, + duration = 2500, + motionProps = { + initial: { opacity: 0, y: -50 }, + animate: { opacity: 1, y: 0 }, + exit: { opacity: 0, y: 50 }, + transition: { duration: 0.25, ease: "easeOut" }, + }, + className, +}: WordRotateProps) { + const [index, setIndex] = useState(0); + + useEffect(() => { + const interval = setInterval(() => { + setIndex((prevIndex) => (prevIndex + 1) % words.length); + }, duration); + + // Clean up interval on unmount + return () => clearInterval(interval); + }, [words, duration]); + + return ( +
    + + + {words[index]} + + +
    + ); +} diff --git a/apps/docs/src/components/ui/3d-marquee.tsx b/apps/docs/src/components/ui/3d-marquee.tsx new file mode 100644 index 0000000..2913aee --- /dev/null +++ b/apps/docs/src/components/ui/3d-marquee.tsx @@ -0,0 +1,142 @@ +"use client"; + +import { motion } from "motion/react"; +import { cn } from "@/lib/utils"; +export const ThreeDMarquee = ({ + images, + className, +}: { + images: string[]; + className?: string; +}) => { + // Split the images array into 4 equal parts + const chunkSize = Math.ceil(images.length / 4); + const chunks = Array.from({ length: 4 }, (_, colIndex) => { + const start = colIndex * chunkSize; + return images.slice(start, start + chunkSize); + }); + return ( +
    +
    +
    +
    + {chunks.map((subarray, colIndex) => ( + + + {subarray.map((image, imageIndex) => ( +
    + + +
    + ))} +
    + ))} +
    +
    +
    +
    + ); +}; + +const GridLineHorizontal = ({ + className, + offset, +}: { + className?: string; + offset?: string; +}) => { + return ( +
    + ); +}; + +const GridLineVertical = ({ + className, + offset, +}: { + className?: string; + offset?: string; +}) => { + return ( +
    + ); +}; diff --git a/apps/docs/src/components/ui/text-hover-effect.tsx b/apps/docs/src/components/ui/text-hover-effect.tsx new file mode 100644 index 0000000..632de03 --- /dev/null +++ b/apps/docs/src/components/ui/text-hover-effect.tsx @@ -0,0 +1,134 @@ +"use client"; +import React, { useRef, useEffect, useState } from "react"; +import { motion } from "motion/react"; + +export const TextHoverEffect = ({ + text, + duration, +}: { + text: string; + duration?: number; + automatic?: boolean; +}) => { + const svgRef = useRef(null); + const [cursor, setCursor] = useState({ x: 0, y: 0 }); + const [hovered, setHovered] = useState(false); + const [maskPosition, setMaskPosition] = useState({ cx: "50%", cy: "50%" }); + + useEffect(() => { + if (svgRef.current && cursor.x !== null && cursor.y !== null) { + const svgRect = svgRef.current.getBoundingClientRect(); + const cxPercentage = ((cursor.x - svgRect.left) / svgRect.width) * 100; + const cyPercentage = ((cursor.y - svgRect.top) / svgRect.height) * 100; + setMaskPosition({ + cx: `${cxPercentage}%`, + cy: `${cyPercentage}%`, + }); + } + }, [cursor]); + + return ( + setHovered(true)} + onMouseLeave={() => setHovered(false)} + onMouseMove={(e) => setCursor({ x: e.clientX, y: e.clientY })} + className="select-none" + > + + + {hovered && ( + <> + + + + + + + )} + + + + + + + + + + + + {text} + + + {text} + + + {text} + + + ); +}; diff --git a/apps/docs/src/content.config.ts b/apps/docs/src/content.config.ts deleted file mode 100644 index d9ee8c9..0000000 --- a/apps/docs/src/content.config.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { defineCollection } from 'astro:content'; -import { docsLoader } from '@astrojs/starlight/loaders'; -import { docsSchema } from '@astrojs/starlight/schema'; - -export const collections = { - docs: defineCollection({ loader: docsLoader(), schema: docsSchema() }), -}; diff --git a/apps/docs/src/lib/source.ts b/apps/docs/src/lib/source.ts new file mode 100644 index 0000000..dedc4be --- /dev/null +++ b/apps/docs/src/lib/source.ts @@ -0,0 +1,9 @@ +import { docs } from '@/.source'; +import { loader } from 'fumadocs-core/source'; + +// See https://fumadocs.vercel.app/docs/headless/source-api for more info +export const source = loader({ + // it assigns a URL to your pages + baseUrl: '/docs', + source: docs.toFumadocsSource(), +}); diff --git a/apps/docs/src/lib/utils.ts b/apps/docs/src/lib/utils.ts new file mode 100644 index 0000000..bd0c391 --- /dev/null +++ b/apps/docs/src/lib/utils.ts @@ -0,0 +1,6 @@ +import { clsx, type ClassValue } from "clsx" +import { twMerge } from "tailwind-merge" + +export function cn(...inputs: ClassValue[]) { + return twMerge(clsx(inputs)) +} diff --git a/apps/docs/src/mdx-components.tsx b/apps/docs/src/mdx-components.tsx new file mode 100644 index 0000000..d3fbb13 --- /dev/null +++ b/apps/docs/src/mdx-components.tsx @@ -0,0 +1,10 @@ +import defaultMdxComponents from 'fumadocs-ui/mdx'; +import type { MDXComponents } from 'mdx/types'; + +// use this function to get MDX components, you will need it for rendering MDX +export function getMDXComponents(components?: MDXComponents): MDXComponents { + return { + ...defaultMdxComponents, + ...components, + }; +} diff --git a/apps/docs/src/styles/custom.css b/apps/docs/src/styles/custom.css deleted file mode 100644 index f4dc98f..0000000 --- a/apps/docs/src/styles/custom.css +++ /dev/null @@ -1,162 +0,0 @@ -/* Tema escuro (padrão) */ -[data-theme='dark'] { - --sl-color-accent-low: #022c1f; - --sl-color-accent: #16a34a; - --sl-color-accent-high: #dcfce7; - --sl-color-bg: #0a0a0a; - --sl-color-bg-sidebar: #0a0a0a; - --sl-color-bg-nav: #0f0f0f; - --sl-color-bg-inline-code: #022c1f; - --sl-color-bg-nav-hover: #022c1f; - --sl-color-text: #ffffff; - --sl-color-text-accent: var(--sl-color-accent); - --sl-color-text-invert: var(--sl-color-black); - --sl-color-hairline: #1a1a1a; - --sl-color-border: #262626; - --sl-color-selection-text: #ffffff; - --sl-color-selection-bg: #16a34a; - --sl-color-code-text: #86efac; - --sl-color-code-bg: #052e16; - --sl-color-code-border: #064e3b; -} - -/* Tema claro */ -[data-theme='light'] { - --sl-color-accent-low: #f0fdf4 !important; - --sl-color-accent: #16a34a !important; - --sl-color-accent-high: #052e16 !important; - --sl-color-bg: #ffffff !important; - --sl-color-bg-sidebar: #f8f9fa !important; - --sl-color-bg-nav: #ffffff !important; - --sl-color-bg-inline-code: #f0fdf4 !important; - --sl-color-bg-nav-hover: #f0fdf4 !important; - --sl-color-text: #111827 !important; - --sl-color-text-accent: #16a34a !important; - --sl-color-text-invert: #ffffff !important; - --sl-color-hairline: #e5e7eb !important; - --sl-color-border: #d1d5db !important; - --sl-color-selection-text: #ffffff !important; - --sl-color-selection-bg: #16a34a !important; - --sl-color-code-text: #16a34a !important; - --sl-color-code-bg: #f0fdf4 !important; - --sl-color-code-border: #dcfce7 !important; -} - -/* Estilo para links gerais */ -a { - color: var(--sl-color-accent) !important; -} - -a:hover { - color: #15803d !important; -} - -/* Estilo para botões */ -.button, button[type="button"], button[type="submit"] { - background-color: var(--sl-color-accent) !important; - color: var(--sl-color-text-invert) !important; - border-color: var(--sl-color-accent) !important; -} - -.button:hover, button[type="button"]:hover, button[type="submit"]:hover { - background-color: #15803d !important; - border-color: #15803d !important; -} - -/* Estilos específicos para a sidebar */ -.sidebar-content a { - color: var(--sl-color-text) !important; -} - -.sidebar-content a:hover { - color: var(--sl-color-accent) !important; -} - -.sidebar-content [aria-current="page"] { - color: var(--sl-color-text-invert) !important; - background-color: var(--sl-color-accent) !important; -} - -/* Ajuste para o título da seção na sidebar */ -.sidebar-content .nav-group-title { - color: var(--sl-color-text) !important; - opacity: 0.7; -} - -/* Seleção de texto */ -::selection { - background-color: var(--sl-color-selection-bg) !important; - color: var(--sl-color-selection-text) !important; -} - -/* Blocos de código */ -code, pre { - color: var(--sl-color-code-text) !important; - background-color: var(--sl-color-code-bg) !important; - border-color: var(--sl-color-code-border) !important; -} - -/* Links de paginação e navegação */ -.pagination-links a, .nav-link, .breadcrumb { - color: var(--sl-color-text) !important; -} - -.pagination-links a:hover, .nav-link:hover { - color: var(--sl-color-accent) !important; -} - -/* Cabeçalhos e elementos de destaque */ -h1, h2, h3, h4, h5, h6, p, li, td, th, label, span { - color: var(--sl-color-text) !important; -} - -/* Elementos de entrada e pesquisa */ -input, .search-input { - background-color: var(--sl-color-bg) !important; - border-color: var(--sl-color-border) !important; - color: var(--sl-color-text) !important; -} - -/* Barra de rolagem personalizada */ -::-webkit-scrollbar-thumb { - background-color: var(--sl-color-border) !important; -} - -::-webkit-scrollbar-track { - background-color: var(--sl-color-bg) !important; -} - -/* Elementos de navegação e menu */ -nav, .nav-wrapper, .menu-item { - color: var(--sl-color-text) !important; -} - -/* Elementos de destaque e badges */ -.badge, .tag, .pill { - background-color: var(--sl-color-accent) !important; - color: var(--sl-color-text-invert) !important; -} - -/* Elementos de tabela */ -table { - border-color: var(--sl-color-border) !important; -} - -/* Elementos de formulário */ -select, textarea { - background-color: var(--sl-color-bg) !important; - border-color: var(--sl-color-border) !important; - color: var(--sl-color-text) !important; -} - -/* Elementos de alerta e notificação */ -.alert, .notification { - border-color: var(--sl-color-border) !important; - background-color: var(--sl-color-bg) !important; -} - -/* Right sidebar */ -.right-sidebar { - color: var(--sl-color-text) !important; - border-color: var(--sl-color-border) !important; -} \ No newline at end of file diff --git a/apps/docs/tsconfig.json b/apps/docs/tsconfig.json index 8bf91d3..504b291 100644 --- a/apps/docs/tsconfig.json +++ b/apps/docs/tsconfig.json @@ -1,5 +1,45 @@ { - "extends": "astro/tsconfigs/strict", - "include": [".astro/types.d.ts", "**/*"], - "exclude": ["dist"] -} + "compilerOptions": { + "baseUrl": ".", + "target": "ESNext", + "lib": [ + "dom", + "dom.iterable", + "esnext" + ], + "allowJs": true, + "skipLibCheck": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "bundler", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve", + "incremental": true, + "paths": { + "@/.source": [ + "./.source/index.ts" + ], + "@/*": [ + "./src/*" + ] + }, + "plugins": [ + { + "name": "next" + } + ] + }, + "include": [ + "next-env.d.ts", + "**/*.ts", + "**/*.tsx", + ".next/types/**/*.ts" + ], + "exclude": [ + "node_modules" + ] +} \ No newline at end of file diff --git a/apps/server/.env.example b/apps/server/.env.example index b7c85d7..5dc3ee0 100644 --- a/apps/server/.env.example +++ b/apps/server/.env.example @@ -8,6 +8,6 @@ MINIO_ROOT_USER="palmr" MINIO_ROOT_PASSWORD="palmr123" MINIO_REGION="sa-east-1" MINIO_BUCKET_NAME="files" - PORT=3333 -BASE_URL=http://localhost:3333 +SERVER_IP="localhost" + diff --git a/apps/server/package.json b/apps/server/package.json index 6356d3e..3905537 100644 --- a/apps/server/package.json +++ b/apps/server/package.json @@ -1,6 +1,6 @@ { "name": "palmr-api", - "version": "1.1.5", + "version": "1.1.6", "description": "", "main": "index.js", "scripts": { diff --git a/apps/server/prisma/seed.ts b/apps/server/prisma/seed.ts index 74e5f15..47193da 100644 --- a/apps/server/prisma/seed.ts +++ b/apps/server/prisma/seed.ts @@ -1,5 +1,4 @@ import { prisma } from "../src/shared/prisma"; -import {env} from "../src/env" import bcrypt from "bcryptjs"; import crypto from "node:crypto"; diff --git a/apps/server/src/config/minio.config.local.ts b/apps/server/src/config/minio.config.local.ts index 29f26e4..e54d0a8 100644 --- a/apps/server/src/config/minio.config.local.ts +++ b/apps/server/src/config/minio.config.local.ts @@ -2,7 +2,7 @@ import { env } from "../env"; import { Client } from "minio"; export const minioLocalClient = new Client({ - endPoint: env.MINIO_ENDPOINT === "minio" ? "localhost" : env.MINIO_ENDPOINT, + endPoint: env.MINIO_ENDPOINT === "minio" ? env.SERVER_IP : env.MINIO_ENDPOINT, port: Number(env.MINIO_PORT), useSSL: env.MINIO_USE_SSL === "true", accessKey: env.MINIO_ROOT_USER, diff --git a/apps/server/src/env.ts b/apps/server/src/env.ts index 4149b36..b554749 100644 --- a/apps/server/src/env.ts +++ b/apps/server/src/env.ts @@ -9,10 +9,9 @@ const envSchema = z.object({ MINIO_ROOT_USER: z.string().min(1), MINIO_REGION: z.string().min(1), MINIO_BUCKET_NAME: z.string().min(1), - BASE_URL: z.string().min(1), - PORT: z.string().min(1), DATABASE_URL: z.string().min(1), + SERVER_IP: z.string().min(1), }); export const env = envSchema.parse(process.env); diff --git a/apps/web/.env b/apps/web/.env deleted file mode 100644 index 3d5084c..0000000 --- a/apps/web/.env +++ /dev/null @@ -1 +0,0 @@ -VITE_API_URL=http://localhost:3333 \ No newline at end of file diff --git a/apps/web/.env.example b/apps/web/.env.example index b111bff..98f7f50 100644 --- a/apps/web/.env.example +++ b/apps/web/.env.example @@ -1 +1 @@ -# VITE_API_URL=http://localhost:3333 \ No newline at end of file +API_BASE_URL=http:localhost:3333 \ No newline at end of file diff --git a/apps/web/.eslintignore b/apps/web/.eslintignore deleted file mode 100644 index af6ab76..0000000 --- a/apps/web/.eslintignore +++ /dev/null @@ -1,20 +0,0 @@ -.now/* -*.css -.changeset -dist -esm/* -public/* -tests/* -scripts/* -*.config.js -.DS_Store -node_modules -coverage -.next -build -!.commitlintrc.cjs -!.lintstagedrc.cjs -!jest.config.js -!plopfile.js -!react-shim.js -!tsup.config.ts \ No newline at end of file diff --git a/apps/web/.eslintrc.json b/apps/web/.eslintrc.json deleted file mode 100644 index ad5fa64..0000000 --- a/apps/web/.eslintrc.json +++ /dev/null @@ -1,120 +0,0 @@ -{ - "$schema": "https://json.schemastore.org/eslintrc.json", - "env": { - "browser": false, - "es2021": true, - "node": true - }, - "extends": [ - "plugin:react/recommended", - "plugin:prettier/recommended", - "plugin:react-hooks/recommended", - "plugin:jsx-a11y/recommended" - ], - "plugins": [ - "react", - "unused-imports", - "import", - "@typescript-eslint", - "jsx-a11y", - "prettier" - ], - "parser": "@typescript-eslint/parser", - "parserOptions": { - "ecmaFeatures": { - "jsx": true - }, - "ecmaVersion": 12, - "sourceType": "module" - }, - "settings": { - "react": { - "version": "detect" - } - }, - "rules": { - "no-console": "off", - "react/prop-types": "off", - "react/jsx-uses-react": "off", - "react/react-in-jsx-scope": "off", - "react-hooks/exhaustive-deps": "off", - "jsx-a11y/click-events-have-key-events": "off", - "jsx-a11y/interactive-supports-focus": "off", - "jsx-a11y/no-static-element-interactions": "off", - "prettier/prettier": "warn", - "no-unused-vars": "off", - "unused-imports/no-unused-vars": "off", - "unused-imports/no-unused-imports": "warn", - "@typescript-eslint/no-unused-vars": [ - "warn", - { - "args": "after-used", - "ignoreRestSiblings": false, - "argsIgnorePattern": "^_.*?$" - } - ], - "import/order": [ - "off", - { - "groups": [ - "type", - "builtin", - "object", - "external", - "internal", - "parent", - "sibling", - "index" - ], - "pathGroups": [ - { - "pattern": "~/**", - "group": "external", - "position": "after" - } - ], - "newlines-between": "always" - } - ], - "react/self-closing-comp": "warn", - "react/jsx-sort-props": [ - "warn", - { - "callbacksLast": true, - "shorthandFirst": true, - "noSortAlphabetically": false, - "reservedFirst": true - } - ], - "padding-line-between-statements": [ - "warn", - { - "blankLine": "always", - "prev": "*", - "next": "return" - }, - { - "blankLine": "always", - "prev": [ - "const", - "let", - "var" - ], - "next": "*" - }, - { - "blankLine": "any", - "prev": [ - "const", - "let", - "var" - ], - "next": [ - "const", - "let", - "var" - ] - } - ] - } -} \ No newline at end of file diff --git a/apps/web/.gitignore b/apps/web/.gitignore index 3d27651..e72b4d6 100644 --- a/apps/web/.gitignore +++ b/apps/web/.gitignore @@ -1,30 +1,41 @@ -# Logs -logs -*.log +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.* +.yarn/* +!.yarn/patches +!.yarn/plugins +!.yarn/releases +!.yarn/versions + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug npm-debug.log* yarn-debug.log* yarn-error.log* -pnpm-debug.log* -lerna-debug.log* +.pnpm-debug.log* -node_modules -dist -dist-ssr -*.local +# env files (can opt-in for committing if needed) +.env -# Editor directories and files -.vscode/* -!.vscode/extensions.json -.idea -.DS_Store -*.suo -*.ntvs* -*.njsproj -*.sln -*.sw? +# vercel +.vercel - -pnpm-lock.yaml -yarn.lock -package-lock.json -bun.lockb \ No newline at end of file +# typescript +*.tsbuildinfo +next-env.d.ts diff --git a/apps/web/.npmrc b/apps/web/.npmrc deleted file mode 100644 index f819c90..0000000 --- a/apps/web/.npmrc +++ /dev/null @@ -1,2 +0,0 @@ -public-hoist-pattern[]=*@heroui/* -package-lock=true \ No newline at end of file diff --git a/apps/web/.prettierignore b/apps/web/.prettierignore new file mode 100644 index 0000000..b2dae58 --- /dev/null +++ b/apps/web/.prettierignore @@ -0,0 +1,4 @@ +/node_modules +/.next +/out +/build \ No newline at end of file diff --git a/apps/web/.prettierrc.json b/apps/web/.prettierrc.json index af95e92..0833f31 100644 --- a/apps/web/.prettierrc.json +++ b/apps/web/.prettierrc.json @@ -1,5 +1,14 @@ { - "plugins": ["@trivago/prettier-plugin-sort-imports"], + "importOrder": [ + "^(react/(.*)$)|^(react$)", + "^(next/(.*)$)|^(next$)", + "", + "", + "^@/(.*)$", + "^[./]" + ], + "importOrderParserPlugins": ["typescript", "jsx", "decorators-legacy"], + "plugins": ["@ianvs/prettier-plugin-sort-imports", "prettier-plugin-sort-json"], "printWidth": 120, "singleQuote": false, "tabWidth": 2, diff --git a/apps/web/Dockerfile b/apps/web/Dockerfile index 5f295b0..bb3f6f9 100644 --- a/apps/web/Dockerfile +++ b/apps/web/Dockerfile @@ -1,20 +1,46 @@ -FROM node:18-alpine AS builder +# Use the official Node.js image as the base image -WORKDIR /app/web +FROM node:18-alpine AS base -RUN npm install -g pnpm +# Install dependencies only when needed +FROM base AS deps +RUN apk add --no-cache libc6-compat +WORKDIR /app -COPY package.json . -COPY pnpm-lock.yaml . - -RUN pnpm install +# Install dependencies based on the preferred package manager +COPY package.json pnpm-lock.yaml ./ +RUN corepack enable pnpm && pnpm install --frozen-lockfile +# Rebuild the source code only when needed +FROM base AS builder +WORKDIR /app +COPY --from=deps /app/node_modules ./node_modules COPY . . -RUN pnpm build +ENV NEXT_TELEMETRY_DISABLED=1 +ENV NODE_ENV=production -EXPOSE 4173 +RUN corepack enable pnpm && pnpm run build -ENV VITE_ROUTER_MODE=history +# Production image, copy all the files and run next +FROM base AS runner +WORKDIR /app -CMD ["pnpm", "preview", "--host"] +ENV NODE_ENV=production +ENV NEXT_TELEMETRY_DISABLED=1 + +RUN addgroup --system --gid 1001 nodejs +RUN adduser --system --uid 1001 nextjs + +COPY --from=builder /app/public ./public +COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./ +COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static + +USER nextjs + +EXPOSE 5487 + +ENV PORT=5487 +ENV HOSTNAME="0.0.0.0" + +CMD ["node", "server.js"] \ No newline at end of file diff --git a/apps/web/README.md b/apps/web/README.md deleted file mode 100644 index c1bf328..0000000 --- a/apps/web/README.md +++ /dev/null @@ -1 +0,0 @@ -# 🌴 Palmr diff --git a/apps/web/components.json b/apps/web/components.json new file mode 100644 index 0000000..4fbe5b8 --- /dev/null +++ b/apps/web/components.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://ui.shadcn.com/schema.json", + "aliases": { + "components": "@/components", + "utils": "@/lib/utils", + "ui": "@/components/ui", + "lib": "@/lib", + "hooks": "@/hooks" + }, + "iconLibrary": "lucide", + "rsc": true, + "style": "new-york", + "tailwind": { + "config": "", + "css": "src/app/globals.css", + "baseColor": "neutral", + "cssVariables": true, + "prefix": "" + }, + "tsx": true +} diff --git a/apps/web/docker-compose.yml b/apps/web/docker-compose.yml new file mode 100644 index 0000000..ccaaa0d --- /dev/null +++ b/apps/web/docker-compose.yml @@ -0,0 +1,17 @@ +services: + web: + build: + context: . + dockerfile: Dockerfile + ports: + - "6644:3000" + environment: + - NODE_ENV=production + - NEXT_TELEMETRY_DISABLED=1 + - API_BASE_URL=http://host.docker.internal:3333 + restart: unless-stopped + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:3000"] + interval: 30s + timeout: 10s + retries: 3 diff --git a/apps/web/eslint.config.mjs b/apps/web/eslint.config.mjs new file mode 100644 index 0000000..c08b069 --- /dev/null +++ b/apps/web/eslint.config.mjs @@ -0,0 +1,66 @@ +/* eslint-disable import/no-anonymous-default-export */ +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import { FlatCompat } from "@eslint/eslintrc"; +import js from "@eslint/js"; +import typescriptEslintEslintPlugin from "@typescript-eslint/eslint-plugin"; +import tsParser from "@typescript-eslint/parser"; +import prettier from "eslint-plugin-prettier"; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); +const compat = new FlatCompat({ + baseDirectory: __dirname, + recommendedConfig: js.configs.recommended, + allConfig: js.configs.all, +}); + +export default [ + ...compat.extends("next", "next/core-web-vitals", "prettier"), + { + plugins: { + prettier, + }, + rules: { + "prettier/prettier": "error", + camelcase: "off", + "import/prefer-default-export": "off", + "react/jsx-filename-extension": "off", + "react/jsx-props-no-spreading": "off", + "react/no-unused-prop-types": "off", + "react/require-default-props": "off", + "react/no-unescaped-entities": "off", + "import/extensions": [ + "error", + "ignorePackages", + { + ts: "never", + tsx: "never", + js: "never", + jsx: "never", + }, + ], + }, + }, + ...compat.extends("plugin:@typescript-eslint/recommended", "prettier").map((config) => ({ + ...config, + files: ["**/*.+(ts|tsx)"], + })), + { + files: ["**/*.+(ts|tsx)"], + plugins: { + "@typescript-eslint": typescriptEslintEslintPlugin, + }, + languageOptions: { + parser: tsParser, + }, + rules: { + "@typescript-eslint/explicit-function-return-type": "off", + "@typescript-eslint/explicit-module-boundary-types": "off", + "no-use-before-define": [0], + "@typescript-eslint/no-use-before-define": [1], + "@typescript-eslint/no-explicit-any": "off", + "@typescript-eslint/no-var-requires": "off", + }, + }, +]; diff --git a/apps/web/index.html b/apps/web/index.html deleted file mode 100644 index 4d88819..0000000 --- a/apps/web/index.html +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - Palmr. - - - - - - - - - -
    - - - diff --git a/apps/web/src/locales/ar-SA.json b/apps/web/messages/ar-SA.json similarity index 97% rename from apps/web/src/locales/ar-SA.json rename to apps/web/messages/ar-SA.json index c6aac47..f087921 100644 --- a/apps/web/src/locales/ar-SA.json +++ b/apps/web/messages/ar-SA.json @@ -1,58 +1,4 @@ { - "login": { - "welcome": "مرحبا", - "signInToContinue": "قم بتسجيل الدخول للمتابعة", - "emailLabel": "البريد الإلكتروني", - "emailPlaceholder": "أدخل بريدك الإلكتروني", - "passwordLabel": "كلمة المرور", - "passwordPlaceholder": "أدخل كلمة المرور", - "signIn": "تسجيل الدخول", - "signingIn": "جاري تسجيل الدخول...", - "forgotPassword": "نسيت كلمة المرور؟", - "pageTitle": "تسجيل الدخول" - }, - "errors": { - "invalidCredentials": "بريد إلكتروني أو كلمة مرور غير صحيحة", - "userNotFound": "المستخدم غير موجود", - "accountLocked": "تم قفل الحساب. يرجى المحاولة لاحقًا", - "unexpectedError": "حدث خطأ غير متوقع. يرجى المحاولة مرة أخرى" - }, - "validation": { - "invalidEmail": "عنوان بريد إلكتروني غير صالح", - "passwordMinLength": "يجب أن تحتوي كلمة المرور على 6 أحرف على الأقل", - "firstNameRequired": "الاسم الأول مطلوب", - "lastNameRequired": "اسم العائلة مطلوب", - "usernameLength": "يجب أن يحتوي اسم المستخدم على 3 أحرف على الأقل", - "usernameSpaces": "لا يمكن أن يحتوي اسم المستخدم على فراغات", - "passwordLength": "يجب أن تحتوي كلمة المرور على 8 أحرف على الأقل", - "passwordsMatch": "كلمتا المرور غير متطابقتين" - }, - "fileSelector": { - "availableFiles": "الملفات المتاحة ({{count}})", - "shareFiles": "مشاركة الملفات ({{count}})", - "searchPlaceholder": "ابحث عن الملفات...", - "noMatchingFiles": "لا توجد ملفات مطابقة", - "noAvailableFiles": "لا توجد ملفات متاحة", - "noFilesInShare": "لا توجد ملفات للمشاركة", - "saveChanges": "احفظ التغييرات" - }, - "recipientSelector": { - "emailPlaceholder": "أدخل بريد المستلم الإلكتروني", - "add": "أضف", - "recipients": "المستلمون ({{count}})", - "notifyAll": "أبلغ الجميع", - "noRecipients": "لم يتم إضافة أي مستلمين بعد", - "addSuccess": "تم إضافة المستلم بنجاح", - "addError": "فشل في إضافة المستلم", - "removeSuccess": "تم إزالة المستلم بنجاح", - "removeError": "فشل في إزالة المستلم", - "sendingNotifications": "جاري إرسال الإشعارات...", - "notifySuccess": "تم إعلام المستلمين بنجاح", - "notifyError": "فشل في إعلام المستلمين" - }, - "navigation": { - "dashboard": "لوحة التحكم" - }, "common": { "loading": "جاري التحميل، يرجى الانتظار...", "cancel": "إلغاء", @@ -78,6 +24,22 @@ "success": "تم إنشاء المشاركة بنجاح", "error": "فشل في إنشاء المشاركة" }, + "dashboard": { + "loadError": "فشل في تحميل بيانات لوحة التحكم", + "linkCopied": "تم نسخ الرابط إلى الحافظة", + "pageTitle": "لوحة التحكم", + "breadcrumb": "لوحة التحكم" + }, + "emptyState": { + "noFiles": "لم يتم رفع أي ملفات بعد", + "uploadFile": "رفع ملف" + }, + "errors": { + "invalidCredentials": "بريد إلكتروني أو كلمة مرور غير صحيحة", + "userNotFound": "المستخدم غير موجود", + "accountLocked": "تم قفل الحساب. يرجى المحاولة لاحقًا", + "unexpectedError": "حدث خطأ غير متوقع. يرجى المحاولة مرة أخرى" + }, "fileActions": { "editFile": "تعديل الملف", "nameLabel": "الاسم", @@ -86,9 +48,16 @@ "descriptionLabel": "الوصف", "descriptionPlaceholder": "أدخل وصف الملف", "deleteFile": "حذف الملف", - "deleteConfirmation": "هل أنت متأكد أنك تريد حذف \"{{fileName}}\"؟", + "deleteConfirmation": "هل أنت متأكد أنك تريد حذف ؟", "deleteWarning": "هذا الإجراء لا يمكن التراجع عنه." }, + "fileManager": { + "downloadError": "فشل في تنزيل الملف", + "updateSuccess": "تم تحديث الملف بنجاح", + "updateError": "فشل في تحديث الملف", + "deleteSuccess": "تم حذف الملف بنجاح", + "deleteError": "فشل في حذف الملف" + }, "filePreview": { "loading": "جاري تحميل المعاينة...", "notAvailable": "المعاينة غير متوفرة", @@ -98,68 +67,21 @@ "loadError": "فشل في تحميل المعاينة", "downloadError": "فشل في تنزيل الملف" }, - "generateShareLink": { - "generateTitle": "إنشاء رابط المشاركة", - "updateTitle": "تحديث رابط المشاركة", - "generateDescription": "أنشئ رابطاً لمشاركة ملفاتك", - "updateDescription": "قم بتحديث اللقب لهذا الرابط", - "aliasPlaceholder": "أدخل لقبًا", - "linkReady": "رابط المشاركة جاهز:", - "generateButton": "إنشاء الرابط", - "updateButton": "تحديث الرابط", - "copyButton": "نسخ الرابط", - "success": "تم إنشاء الرابط بنجاح", - "error": "فشل في إنشاء الرابط", - "copied": "تم نسخ الرابط إلى الحافظة" + "fileSelector": { + "availableFiles": "الملفات المتاحة ({{count}})", + "shareFiles": "مشاركة الملفات ({{count}})", + "searchPlaceholder": "ابحث عن الملفات...", + "noMatchingFiles": "لا توجد ملفات مطابقة", + "noAvailableFiles": "لا توجد ملفات متاحة", + "noFilesInShare": "لا توجد ملفات للمشاركة", + "saveChanges": "احفظ التغييرات" }, - "shareActions": { - "deleteTitle": "حذف المشاركة", - "deleteConfirmation": "هل أنت متأكد من رغبتك في حذف هذه المشاركة؟ هذا الإجراء لا يمكن التراجع عنه.", - "editTitle": "تعديل المشاركة", - "nameLabel": "اسم المشاركة", - "expirationLabel": "تاريخ الانتهاء", - "expirationPlaceholder": "MM/DD/YYYY HH:MM", - "maxViewsLabel": "أقصى عدد للمشاهدات", - "maxViewsPlaceholder": "اتركه فارغاً للمحدودية غير المحدودة", - "passwordProtection": "محمي بكلمة المرور", - "passwordLabel": "كلمة المرور", - "passwordPlaceholder": "أدخل كلمة المرور", - "newPasswordLabel": "كلمة مرور جديدة (اتركه فارغاً للاحتفاظ بالحالي)", - "newPasswordPlaceholder": "أدخل كلمة مرور جديدة", - "manageFilesTitle": "إدارة الملفات", - "manageRecipientsTitle": "إدارة المستلمين", - "editSuccess": "تم تحديث المشاركة بنجاح", - "editError": "فشل في تحديث المشاركة" - }, - "shareDetails": { - "title": "تفاصيل المشاركة", - "subtitle": "معلومات مفصلة عن هذه المشاركة", - "basicInfo": "المعلومات الأساسية", - "name": "الاسم", - "untitled": "بدون عنوان", - "views": "المشاهدات", - "dates": "التواريخ", - "created": "تم الإنشاء", - "expires": "تنتهي", - "never": "أبدًا", - "security": "الأمان", - "passwordProtected": "محمي بكلمة المرور", - "publicAccess": "الوصول العام", - "maxViews": "أقصى عدد للمشاهدات: {{count}}", - "files": "الملفات ({{count}})", - "recipients": "المستلمون ({{count}})", - "notAvailable": "غير متوفر", - "invalidDate": "تاريخ غير صالح", - "loadError": "فشل في تحميل تفاصيل المشاركة" - }, - "uploadFile": { - "title": "رفع الملف", - "selectFile": "اضغط لاختيار ملف", - "preview": "المعاينة", - "uploadProgress": "تقدم الرفع", - "upload": "رفع", - "success": "تم رفع الملف بنجاح", - "error": "فشل في رفع الملف" + "files": { + "title": "كل الملفات", + "uploadFile": "رفع ملف", + "loadError": "فشل في تحميل الملفات", + "pageTitle": "ملفاتي", + "breadcrumb": "ملفاتي" }, "filesTable": { "ariaLabel": "جدول الملفات", @@ -179,119 +101,10 @@ "delete": "حذف" } }, - "sharesTable": { - "ariaLabel": "جدول المشاركات", - "never": "أبدًا", - "columns": { - "name": "الاسم", - "createdAt": "تاريخ الإنشاء", - "expiresAt": "تاريخ الانتهاء", - "status": "الحالة", - "security": "الأمان", - "files": "الملفات", - "recipients": "المستلمون", - "actions": "الإجراءات" - }, - "status": { - "neverExpires": "لا تنتهي", - "active": "نشطة", - "expired": "منتهية" - }, - "security": { - "protected": "محمي", - "public": "عام" - }, - "filesCount": "{{count}} ملف", - "recipientsCount": "{{count}} مستلم", - "actions": { - "menu": "قائمة إجراءات المشاركة", - "edit": "تعديل", - "manageFiles": "إدارة الملفات", - "manageRecipients": "إدارة المستلمين", - "viewDetails": "عرض التفاصيل", - "generateLink": "إنشاء الرابط", - "editLink": "تعديل الرابط", - "copyLink": "نسخ الرابط", - "notifyRecipients": "إعلام المستلمين", - "delete": "حذف" - } - }, "footer": { "poweredBy": "مدعوم من", "kyanHomepage": "الصفحة الرئيسية لـ Kyantech" }, - "fileManager": { - "downloadError": "فشل في تنزيل الملف", - "updateSuccess": "تم تحديث الملف بنجاح", - "updateError": "فشل في تحديث الملف", - "deleteSuccess": "تم حذف الملف بنجاح", - "deleteError": "فشل في حذف الملف" - }, - "shareManager": { - "deleteSuccess": "تم حذف المشاركة بنجاح", - "deleteError": "فشل في حذف المشاركة", - "updateSuccess": "تم تحديث المشاركة بنجاح", - "updateError": "فشل في تحديث المشاركة", - "filesUpdateSuccess": "تم تحديث الملفات بنجاح", - "filesUpdateError": "فشل في تحديث الملفات", - "recipientsUpdateSuccess": "تم تحديث المستلمين بنجاح", - "recipientsUpdateError": "فشل في تحديث المستلمين", - "linkGenerateSuccess": "تم إنشاء رابط المشاركة بنجاح", - "linkGenerateError": "فشل في إنشاء رابط المشاركة", - "notifyLoading": "جاري إرسال الإشعارات...", - "notifySuccess": "تم إعلام المستلمين بنجاح", - "notifyError": "فشل في إعلام المستلمين" - }, - "quickAccess": { - "files": { - "title": "ملفاتي", - "description": "الوصول إلى الملفات المرفوعة وإدارتها" - }, - "shares": { - "title": "مشاركاتي", - "description": "عرض وإدارة الملفات المشتركة" - } - }, - "recentFiles": { - "title": "الرفع الأخير", - "viewAll": "عرض الكل", - "uploadFile": "رفع ملف", - "noFiles": "لم يتم رفع أي ملفات بعد" - }, - "recentShares": { - "title": "المشاركات الأخيرة", - "viewAll": "عرض الكل", - "createShare": "إنشاء مشاركة", - "noShares": "لم يتم إنشاء أي مشاركات بعد", - "createFirst": "أنشئ مشاركتك الأولى" - }, - "storageUsage": { - "title": "استخدام التخزين", - "ariaLabel": "شريط تقدم استخدام التخزين", - "used": "المستخدمة: {{size}}", - "available": "المتاحة: {{size}}" - }, - "dashboard": { - "loadError": "فشل في تحميل بيانات لوحة التحكم", - "linkCopied": "تم نسخ الرابط إلى الحافظة", - "pageTitle": "لوحة التحكم", - "breadcrumb": "لوحة التحكم" - }, - "emptyState": { - "noFiles": "لم يتم رفع أي ملفات بعد", - "uploadFile": "رفع ملف" - }, - "files": { - "title": "كل الملفات", - "uploadFile": "رفع ملف", - "loadError": "فشل في تحميل الملفات", - "pageTitle": "ملفاتي", - "breadcrumb": "ملفاتي" - }, - "searchBar": { - "placeholder": "ابحث عن الملفات...", - "results": "تم العثور على {{filtered}} من {{total}} ملف" - }, "forgotPassword": { "emailLabel": "البريد الإلكتروني", "emailPlaceholder": "أدخل بريدك الإلكتروني", @@ -303,6 +116,20 @@ "resetInstructions": "تم إرسال تعليمات إعادة التعيين إلى بريدك الإلكتروني", "pageTitle": "نسيت كلمة المرور" }, + "generateShareLink": { + "generateTitle": "إنشاء رابط المشاركة", + "updateTitle": "تحديث رابط المشاركة", + "generateDescription": "أنشئ رابطاً لمشاركة ملفاتك", + "updateDescription": "قم بتحديث اللقب لهذا الرابط", + "aliasPlaceholder": "أدخل لقبًا", + "linkReady": "رابط المشاركة جاهز:", + "generateButton": "إنشاء الرابط", + "updateButton": "تحديث الرابط", + "copyButton": "نسخ الرابط", + "success": "تم إنشاء الرابط بنجاح", + "error": "فشل في إنشاء الرابط", + "copied": "تم نسخ الرابط إلى الحافظة" + }, "home": { "description": "البديل مفتوح المصدر لـ WeTransfer. شارك ملفاتك بأمان، دون تتبع أو قيود.", "documentation": "التوثيق", @@ -314,6 +141,46 @@ }, "pageTitle": "الصفحة الرئيسية" }, + "login": { + "welcome": "مرحبا بك", + "signInToContinue": "قم بتسجيل الدخول للمتابعة", + "emailLabel": "البريد الإلكتروني", + "emailPlaceholder": "أدخل بريدك الإلكتروني", + "passwordLabel": "كلمة المرور", + "passwordPlaceholder": "أدخل كلمة المرور", + "signIn": "تسجيل الدخول", + "signingIn": "جاري تسجيل الدخول...", + "forgotPassword": "نسيت كلمة المرور؟", + "pageTitle": "تسجيل الدخول" + }, + "logo": { + "labels": { + "appLogo": "شعار التطبيق" + }, + "buttons": { + "upload": "رفع الشعار", + "remove": "حذف الشعار" + }, + "messages": { + "uploadSuccess": "تم رفع الشعار بنجاح", + "removeSuccess": "تم حذف الشعار بنجاح" + }, + "errors": { + "uploadFailed": "فشل في رفع الشعار", + "removeFailed": "فشل في حذف الشعار" + } + }, + "navbar": { + "logoAlt": "شعار التطبيق", + "profileMenu": "قائمة الملف الشخصي", + "profile": "الملف الشخصي", + "settings": "الإعدادات", + "usersManagement": "إدارة المستخدمين", + "logout": "تسجيل الخروج" + }, + "navigation": { + "dashboard": "لوحة التحكم" + }, "profile": { "password": { "title": "تغيير كلمة المرور", @@ -356,6 +223,43 @@ }, "pageTitle": "الملف الشخصي" }, + "quickAccess": { + "files": { + "title": "ملفاتي", + "description": "الوصول إلى الملفات المرفوعة وإدارتها" + }, + "shares": { + "title": "مشاركاتي", + "description": "عرض وإدارة الملفات المشتركة" + } + }, + "recentFiles": { + "title": "الرفع الأخير", + "viewAll": "عرض الكل", + "uploadFile": "رفع ملف", + "noFiles": "لم يتم رفع أي ملفات بعد" + }, + "recentShares": { + "title": "المشاركات الأخيرة", + "viewAll": "عرض الكل", + "createShare": "إنشاء مشاركة", + "noShares": "لم يتم إنشاء أي مشاركات بعد", + "createFirst": "أنشئ مشاركتك الأولى" + }, + "recipientSelector": { + "emailPlaceholder": "أدخل بريد المستلم الإلكتروني", + "add": "أضف", + "recipients": "المستلمون ({{count}})", + "notifyAll": "أبلغ الجميع", + "noRecipients": "لم يتم إضافة أي مستلمين بعد", + "addSuccess": "تم إضافة المستلم بنجاح", + "addError": "فشل في إضافة المستلم", + "removeSuccess": "تم إزالة المستلم بنجاح", + "removeError": "فشل في إزالة المستلم", + "sendingNotifications": "جاري إرسال الإشعارات...", + "notifySuccess": "تم إعلام المستلمين بنجاح", + "notifyError": "فشل في إعلام المستلمين" + }, "resetPassword": { "pageTitle": "إعادة تعيين كلمة المرور", "header": { @@ -379,6 +283,10 @@ "invalidToken": "رمز إعادة التعيين غير صالح أو مفقود" } }, + "searchBar": { + "placeholder": "ابحث عن الملفات...", + "results": "تم العثور على {{filtered}} من {{total}} ملف" + }, "settings": { "groups": { "defaultDescription": "خيارات التكوين", @@ -513,6 +421,61 @@ }, "pageTitle": "المشاركة" }, + "shareActions": { + "deleteTitle": "حذف المشاركة", + "deleteConfirmation": "هل أنت متأكد من رغبتك في حذف هذه المشاركة؟ هذا الإجراء لا يمكن التراجع عنه.", + "editTitle": "تعديل المشاركة", + "nameLabel": "اسم المشاركة", + "expirationLabel": "تاريخ الانتهاء", + "expirationPlaceholder": "MM/DD/YYYY HH:MM", + "maxViewsLabel": "أقصى عدد للمشاهدات", + "maxViewsPlaceholder": "اتركه فارغاً للمحدودية غير المحدودة", + "passwordProtection": "محمي بكلمة المرور", + "passwordLabel": "كلمة المرور", + "passwordPlaceholder": "أدخل كلمة المرور", + "newPasswordLabel": "كلمة مرور جديدة (اتركه فارغاً للاحتفاظ بالحالي)", + "newPasswordPlaceholder": "أدخل كلمة مرور جديدة", + "manageFilesTitle": "إدارة الملفات", + "manageRecipientsTitle": "إدارة المستلمين", + "editSuccess": "تم تحديث المشاركة بنجاح", + "editError": "فشل في تحديث المشاركة" + }, + "shareDetails": { + "title": "تفاصيل المشاركة", + "subtitle": "معلومات مفصلة عن هذه المشاركة", + "basicInfo": "المعلومات الأساسية", + "name": "الاسم", + "untitled": "بدون عنوان", + "views": "المشاهدات", + "dates": "التواريخ", + "created": "تم الإنشاء", + "expires": "تنتهي", + "never": "أبدًا", + "security": "الأمان", + "passwordProtected": "محمي بكلمة المرور", + "publicAccess": "الوصول العام", + "maxViews": "أقصى عدد للمشاهدات:", + "files": "الملفات", + "recipients": "المستلمون", + "notAvailable": "غير متوفر", + "invalidDate": "تاريخ غير صالح", + "loadError": "فشل في تحميل تفاصيل المشاركة" + }, + "shareManager": { + "deleteSuccess": "تم حذف المشاركة بنجاح", + "deleteError": "فشل في حذف المشاركة", + "updateSuccess": "تم تحديث المشاركة بنجاح", + "updateError": "فشل في تحديث المشاركة", + "filesUpdateSuccess": "تم تحديث الملفات بنجاح", + "filesUpdateError": "فشل في تحديث الملفات", + "recipientsUpdateSuccess": "تم تحديث المستلمين بنجاح", + "recipientsUpdateError": "فشل في تحديث المستلمين", + "linkGenerateSuccess": "تم إنشاء رابط المشاركة بنجاح", + "linkGenerateError": "فشل في إنشاء رابط المشاركة", + "notifyLoading": "جاري إرسال الإشعارات...", + "notifySuccess": "تم إعلام المستلمين بنجاح", + "notifyError": "فشل في إعلام المستلمين" + }, "shares": { "errors": { "loadFailed": "فشل في تحميل المشاركات", @@ -539,6 +502,64 @@ }, "pageTitle": "المشاركات" }, + "sharesTable": { + "ariaLabel": "جدول المشاركات", + "never": "أبدًا", + "columns": { + "name": "الاسم", + "createdAt": "تاريخ الإنشاء", + "expiresAt": "تاريخ الانتهاء", + "status": "الحالة", + "security": "الأمان", + "files": "الملفات", + "recipients": "المستلمون", + "actions": "الإجراءات" + }, + "status": { + "neverExpires": "لا تنتهي", + "active": "نشطة", + "expired": "منتهية" + }, + "security": { + "protected": "محمي", + "public": "عام" + }, + "filesCount": "ملف", + "recipientsCount": "مستلم", + "actions": { + "menu": "قائمة إجراءات المشاركة", + "edit": "تعديل", + "manageFiles": "إدارة الملفات", + "manageRecipients": "إدارة المستلمين", + "viewDetails": "عرض التفاصيل", + "generateLink": "إنشاء الرابط", + "editLink": "تعديل الرابط", + "copyLink": "نسخ الرابط", + "notifyRecipients": "إعلام المستلمين", + "delete": "حذف" + } + }, + "storageUsage": { + "title": "استخدام التخزين", + "ariaLabel": "شريط تقدم استخدام التخزين", + "used": "المستخدمة", + "available": "المتاحة" + }, + "theme": { + "toggle": "تبديل السمة", + "light": "فاتح", + "dark": "داكن", + "system": "النظام" + }, + "uploadFile": { + "title": "رفع الملف", + "selectFile": "اضغط لاختيار ملف", + "preview": "المعاينة", + "uploadProgress": "تقدم الرفع", + "upload": "رفع", + "success": "تم رفع الملف بنجاح", + "error": "فشل في رفع الملف" + }, "users": { "modes": { "create": "إنشاء", @@ -608,29 +629,16 @@ "userr": "مستخدم" } }, - "logo": { - "labels": { - "appLogo": "شعار التطبيق" - }, - "buttons": { - "upload": "رفع الشعار", - "remove": "حذف الشعار" - }, - "messages": { - "uploadSuccess": "تم رفع الشعار بنجاح", - "removeSuccess": "تم حذف الشعار بنجاح" - }, - "errors": { - "uploadFailed": "فشل في رفع الشعار", - "removeFailed": "فشل في حذف الشعار" - } - }, - "navbar": { - "logoAlt": "شعار التطبيق", - "profileMenu": "قائمة الملف الشخصي", - "profile": "الملف الشخصي", - "settings": "الإعدادات", - "usersManagement": "إدارة المستخدمين", - "logout": "تسجيل الخروج" + "validation": { + "invalidEmail": "عنوان بريد إلكتروني غير صالح", + "passwordMinLength": "يجب أن تحتوي كلمة المرور على 6 أحرف على الأقل", + "firstNameRequired": "الاسم الأول مطلوب", + "lastNameRequired": "اسم العائلة مطلوب", + "usernameLength": "يجب أن يحتوي اسم المستخدم على 3 أحرف على الأقل", + "usernameSpaces": "لا يمكن أن يحتوي اسم المستخدم على فراغات", + "passwordLength": "يجب أن تحتوي كلمة المرور على 8 أحرف على الأقل", + "passwordsMatch": "كلمتا المرور غير متطابقتين", + "emailRequired": "البريد الإلكتروني مطلوب", + "passwordRequired": "كلمة المرور مطلوبة" } -} \ No newline at end of file +} diff --git a/apps/web/src/locales/de-DE.json b/apps/web/messages/de-DE.json similarity index 97% rename from apps/web/src/locales/de-DE.json rename to apps/web/messages/de-DE.json index ff13ed3..e01517c 100644 --- a/apps/web/src/locales/de-DE.json +++ b/apps/web/messages/de-DE.json @@ -1,58 +1,4 @@ { - "login": { - "welcome": "Willkommen", - "signInToContinue": "Melden Sie sich an, um fortzufahren", - "emailLabel": "E-Mail-Adresse", - "emailPlaceholder": "Geben Sie Ihre E-Mail-Adresse ein", - "passwordLabel": "Passwort", - "passwordPlaceholder": "Geben Sie Ihr Passwort ein", - "signIn": "Anmelden", - "signingIn": "Melde an...", - "forgotPassword": "Passwort vergessen?", - "pageTitle": "Anmeldung" - }, - "errors": { - "invalidCredentials": "Ungültige E-Mail oder Passwort", - "userNotFound": "Benutzer nicht gefunden", - "accountLocked": "Konto gesperrt. Bitte versuchen Sie es später erneut", - "unexpectedError": "Ein unerwarteter Fehler ist aufgetreten. Bitte versuchen Sie es erneut" - }, - "validation": { - "invalidEmail": "Ungültige E-Mail-Adresse", - "passwordMinLength": "Das Passwort muss mindestens 6 Zeichen lang sein", - "firstNameRequired": "Vorname ist erforderlich", - "lastNameRequired": "Nachname ist erforderlich", - "usernameLength": "Der Benutzername muss mindestens 3 Zeichen lang sein", - "usernameSpaces": "Der Benutzername darf keine Leerzeichen enthalten", - "passwordLength": "Das Passwort muss mindestens 8 Zeichen lang sein", - "passwordsMatch": "Die Passwörter stimmen nicht überein" - }, - "fileSelector": { - "availableFiles": "Verfügbare Dateien ({{count}})", - "shareFiles": "Dateien teilen ({{count}})", - "searchPlaceholder": "Dateien suchen...", - "noMatchingFiles": "Keine übereinstimmenden Dateien", - "noAvailableFiles": "Keine Dateien verfügbar", - "noFilesInShare": "Keine Dateien in der Freigabe", - "saveChanges": "Änderungen speichern" - }, - "recipientSelector": { - "emailPlaceholder": "Empfänger-E-Mail eingeben", - "add": "Hinzufügen", - "recipients": "Empfänger ({{count}})", - "notifyAll": "Alle benachrichtigen", - "noRecipients": "Noch keine Empfänger hinzugefügt", - "addSuccess": "Empfänger erfolgreich hinzugefügt", - "addError": "Fehler beim Hinzufügen des Empfängers", - "removeSuccess": "Empfänger erfolgreich entfernt", - "removeError": "Fehler beim Entfernen des Empfängers", - "sendingNotifications": "Benachrichtigungen werden gesendet...", - "notifySuccess": "Empfänger erfolgreich benachrichtigt", - "notifyError": "Fehler beim Benachrichtigen der Empfänger" - }, - "navigation": { - "dashboard": "Übersicht" - }, "common": { "loading": "Lädt, bitte warten...", "cancel": "Abbrechen", @@ -78,6 +24,22 @@ "success": "Freigabe erfolgreich erstellt", "error": "Fehler beim Erstellen der Freigabe" }, + "dashboard": { + "loadError": "Fehler beim Laden der Dashboard-Daten", + "linkCopied": "Link in die Zwischenablage kopiert", + "pageTitle": "Übersicht", + "breadcrumb": "Übersicht" + }, + "emptyState": { + "noFiles": "Noch keine Dateien hochgeladen", + "uploadFile": "Datei hochladen" + }, + "errors": { + "invalidCredentials": "Ungültige E-Mail oder Passwort", + "userNotFound": "Benutzer nicht gefunden", + "accountLocked": "Konto gesperrt. Bitte versuchen Sie es später erneut", + "unexpectedError": "Ein unerwarteter Fehler ist aufgetreten. Bitte versuchen Sie es erneut" + }, "fileActions": { "editFile": "Datei bearbeiten", "nameLabel": "Name", @@ -86,9 +48,16 @@ "descriptionLabel": "Beschreibung", "descriptionPlaceholder": "Dateibeschreibung eingeben", "deleteFile": "Datei löschen", - "deleteConfirmation": "Sind Sie sicher, dass Sie \"{{fileName}}\" löschen möchten?", + "deleteConfirmation": "Sind Sie sicher, dass Sie löschen möchten?", "deleteWarning": "Diese Aktion kann nicht rückgängig gemacht werden." }, + "fileManager": { + "downloadError": "Fehler beim Herunterladen der Datei", + "updateSuccess": "Datei erfolgreich aktualisiert", + "updateError": "Fehler beim Aktualisieren der Datei", + "deleteSuccess": "Datei erfolgreich gelöscht", + "deleteError": "Fehler beim Löschen der Datei" + }, "filePreview": { "loading": "Vorschau wird geladen...", "notAvailable": "Vorschau nicht verfügbar", @@ -98,68 +67,21 @@ "loadError": "Fehler beim Laden der Vorschau", "downloadError": "Fehler beim Herunterladen der Datei" }, - "generateShareLink": { - "generateTitle": "Freigabelink generieren", - "updateTitle": "Freigabelink aktualisieren", - "generateDescription": "Erstellen Sie einen Link, um Ihre Dateien zu teilen", - "updateDescription": "Aktualisieren Sie den Alias für diesen Freigabelink", - "aliasPlaceholder": "Alias eingeben", - "linkReady": "Ihr Freigabelink ist fertig:", - "generateButton": "Link generieren", - "updateButton": "Link aktualisieren", - "copyButton": "Link kopieren", - "success": "Link erfolgreich generiert", - "error": "Fehler beim Generieren des Links", - "copied": "Link in die Zwischenablage kopiert" + "fileSelector": { + "availableFiles": "Verfügbare Dateien ({{count}})", + "shareFiles": "Dateien teilen ({{count}})", + "searchPlaceholder": "Dateien suchen...", + "noMatchingFiles": "Keine übereinstimmenden Dateien", + "noAvailableFiles": "Keine Dateien verfügbar", + "noFilesInShare": "Keine Dateien in der Freigabe", + "saveChanges": "Änderungen speichern" }, - "shareActions": { - "deleteTitle": "Freigabe löschen", - "deleteConfirmation": "Sind Sie sicher, dass Sie diese Freigabe löschen möchten? Diese Aktion kann nicht rückgängig gemacht werden.", - "editTitle": "Freigabe bearbeiten", - "nameLabel": "Freigabename", - "expirationLabel": "Ablaufdatum", - "expirationPlaceholder": "MM/TT/JJJJ SS:MM", - "maxViewsLabel": "Maximale Ansichten", - "maxViewsPlaceholder": "Leer lassen für unbegrenzt", - "passwordProtection": "Passwortgeschützt", - "passwordLabel": "Passwort", - "passwordPlaceholder": "Passwort eingeben", - "newPasswordLabel": "Neues Passwort (leer lassen, um das aktuelle zu behalten)", - "newPasswordPlaceholder": "Neues Passwort eingeben", - "manageFilesTitle": "Dateien verwalten", - "manageRecipientsTitle": "Empfänger verwalten", - "editSuccess": "Freigabe erfolgreich aktualisiert", - "editError": "Fehler beim Aktualisieren der Freigabe" - }, - "shareDetails": { - "title": "Freigabedetails", - "subtitle": "Detaillierte Informationen zu dieser Freigabe", - "basicInfo": "Grundinformationen", - "name": "Name", - "untitled": "Ohne Titel", - "views": "Aufrufe", - "dates": "Daten", - "created": "Erstellt", - "expires": "Läuft ab", - "never": "Nie", - "security": "Sicherheit", - "passwordProtected": "Passwortgeschützt", - "publicAccess": "Öffentlicher Zugriff", - "maxViews": "Maximale Ansichten: {{count}}", - "files": "Dateien ({{count}})", - "recipients": "Empfänger ({{count}})", - "notAvailable": "N/V", - "invalidDate": "Ungültiges Datum", - "loadError": "Fehler beim Laden der Freigabedetails" - }, - "uploadFile": { - "title": "Datei hochladen", - "selectFile": "Klicken Sie, um eine Datei auszuwählen", - "preview": "Vorschau", - "uploadProgress": "Upload-Fortschritt", - "upload": "Hochladen", - "success": "Datei erfolgreich hochgeladen", - "error": "Fehler beim Hochladen der Datei" + "files": { + "title": "Alle Dateien", + "uploadFile": "Datei hochladen", + "loadError": "Fehler beim Laden der Dateien", + "pageTitle": "Meine Dateien", + "breadcrumb": "Meine Dateien" }, "filesTable": { "ariaLabel": "Dateitabelle", @@ -179,119 +101,10 @@ "delete": "Löschen" } }, - "sharesTable": { - "ariaLabel": "Freigabetabelle", - "never": "Nie", - "columns": { - "name": "NAME", - "createdAt": "ERSTELLT AM", - "expiresAt": "LÄUFT AB", - "status": "STATUS", - "security": "SICHERHEIT", - "files": "DATEIEN", - "recipients": "EMPFÄNGER", - "actions": "AKTIONEN" - }, - "status": { - "neverExpires": "Läuft nie ab", - "active": "Aktiv", - "expired": "Abgelaufen" - }, - "security": { - "protected": "Geschützt", - "public": "Öffentlich" - }, - "filesCount": "{{count}} Dateien", - "recipientsCount": "{{count}} Empfänger", - "actions": { - "menu": "Freigabeaktionsmenü", - "edit": "Bearbeiten", - "manageFiles": "Dateien verwalten", - "manageRecipients": "Empfänger verwalten", - "viewDetails": "Details anzeigen", - "generateLink": "Link generieren", - "editLink": "Link bearbeiten", - "copyLink": "Link kopieren", - "notifyRecipients": "Empfänger benachrichtigen", - "delete": "Löschen" - } - }, "footer": { "poweredBy": "Powered by", "kyanHomepage": "Kyantech Homepage" }, - "fileManager": { - "downloadError": "Fehler beim Herunterladen der Datei", - "updateSuccess": "Datei erfolgreich aktualisiert", - "updateError": "Fehler beim Aktualisieren der Datei", - "deleteSuccess": "Datei erfolgreich gelöscht", - "deleteError": "Fehler beim Löschen der Datei" - }, - "shareManager": { - "deleteSuccess": "Freigabe erfolgreich gelöscht", - "deleteError": "Fehler beim Löschen der Freigabe", - "updateSuccess": "Freigabe erfolgreich aktualisiert", - "updateError": "Fehler beim Aktualisieren der Freigabe", - "filesUpdateSuccess": "Dateien erfolgreich aktualisiert", - "filesUpdateError": "Fehler beim Aktualisieren der Dateien", - "recipientsUpdateSuccess": "Empfänger erfolgreich aktualisiert", - "recipientsUpdateError": "Fehler beim Aktualisieren der Empfänger", - "linkGenerateSuccess": "Freigabelink erfolgreich generiert", - "linkGenerateError": "Fehler beim Generieren des Freigabelinks", - "notifyLoading": "Benachrichtigungen werden gesendet...", - "notifySuccess": "Empfänger erfolgreich benachrichtigt", - "notifyError": "Fehler beim Benachrichtigen der Empfänger" - }, - "quickAccess": { - "files": { - "title": "Meine Dateien", - "description": "Zugriff und Verwaltung Ihrer hochgeladenen Dateien" - }, - "shares": { - "title": "Meine Freigaben", - "description": "Anzeigen und Verwalten Ihrer geteilten Dateien" - } - }, - "recentFiles": { - "title": "Kürzlich hochgeladen", - "viewAll": "Alle anzeigen", - "uploadFile": "Datei hochladen", - "noFiles": "Noch keine Dateien hochgeladen" - }, - "recentShares": { - "title": "Kürzlich geteilte", - "viewAll": "Alle anzeigen", - "createShare": "Freigabe erstellen", - "noShares": "Noch keine Freigaben erstellt", - "createFirst": "Erstellen Sie Ihre erste Freigabe" - }, - "storageUsage": { - "title": "Speichernutzung", - "ariaLabel": "Fortschrittsbalken der Speichernutzung", - "used": "{{size}} genutzt", - "available": "{{size}} verfügbar" - }, - "dashboard": { - "loadError": "Fehler beim Laden der Dashboard-Daten", - "linkCopied": "Link in die Zwischenablage kopiert", - "pageTitle": "Übersicht", - "breadcrumb": "Übersicht" - }, - "emptyState": { - "noFiles": "Noch keine Dateien hochgeladen", - "uploadFile": "Datei hochladen" - }, - "files": { - "title": "Alle Dateien", - "uploadFile": "Datei hochladen", - "loadError": "Fehler beim Laden der Dateien", - "pageTitle": "Meine Dateien", - "breadcrumb": "Meine Dateien" - }, - "searchBar": { - "placeholder": "Dateien suchen...", - "results": "Gefunden {{filtered}} von {{total}} Dateien" - }, "forgotPassword": { "emailLabel": "E-Mail-Adresse", "emailPlaceholder": "Geben Sie Ihre E-Mail-Adresse ein", @@ -303,6 +116,20 @@ "resetInstructions": "Anweisungen zum Zurücksetzen wurden an Ihre E-Mail gesendet", "pageTitle": "Passwort vergessen" }, + "generateShareLink": { + "generateTitle": "Freigabelink generieren", + "updateTitle": "Freigabelink aktualisieren", + "generateDescription": "Erstellen Sie einen Link, um Ihre Dateien zu teilen", + "updateDescription": "Aktualisieren Sie den Alias für diesen Freigabelink", + "aliasPlaceholder": "Alias eingeben", + "linkReady": "Ihr Freigabelink ist fertig:", + "generateButton": "Link generieren", + "updateButton": "Link aktualisieren", + "copyButton": "Link kopieren", + "success": "Link erfolgreich generiert", + "error": "Fehler beim Generieren des Links", + "copied": "Link in die Zwischenablage kopiert" + }, "home": { "description": "Die Open-Source-Alternative zu WeTransfer. Teilen Sie Dateien sicher, ohne Tracking oder Einschränkungen.", "documentation": "Dokumentation", @@ -314,6 +141,46 @@ }, "pageTitle": "Startseite" }, + "login": { + "welcome": "Willkommen zu", + "signInToContinue": "Melden Sie sich an, um fortzufahren", + "emailLabel": "E-Mail-Adresse", + "emailPlaceholder": "Geben Sie Ihre E-Mail-Adresse ein", + "passwordLabel": "Passwort", + "passwordPlaceholder": "Geben Sie Ihr Passwort ein", + "signIn": "Anmelden", + "signingIn": "Melde an...", + "forgotPassword": "Passwort vergessen?", + "pageTitle": "Anmeldung" + }, + "logo": { + "labels": { + "appLogo": "Anwendungslogo" + }, + "buttons": { + "upload": "Logo hochladen", + "remove": "Logo entfernen" + }, + "messages": { + "uploadSuccess": "Logo erfolgreich hochgeladen", + "removeSuccess": "Logo erfolgreich entfernt" + }, + "errors": { + "uploadFailed": "Fehler beim Hochladen des Logos", + "removeFailed": "Fehler beim Entfernen des Logos" + } + }, + "navbar": { + "logoAlt": "Anwendungslogo", + "profileMenu": "Profilmenü", + "profile": "Profil", + "settings": "Einstellungen", + "usersManagement": "Benutzerverwaltung", + "logout": "Abmelden" + }, + "navigation": { + "dashboard": "Übersicht" + }, "profile": { "password": { "title": "Passwort ändern", @@ -356,6 +223,43 @@ }, "pageTitle": "Profil" }, + "quickAccess": { + "files": { + "title": "Meine Dateien", + "description": "Zugriff und Verwaltung Ihrer hochgeladenen Dateien" + }, + "shares": { + "title": "Meine Freigaben", + "description": "Anzeigen und Verwalten Ihrer geteilten Dateien" + } + }, + "recentFiles": { + "title": "Kürzlich hochgeladen", + "viewAll": "Alle anzeigen", + "uploadFile": "Datei hochladen", + "noFiles": "Noch keine Dateien hochgeladen" + }, + "recentShares": { + "title": "Kürzlich geteilte", + "viewAll": "Alle anzeigen", + "createShare": "Freigabe erstellen", + "noShares": "Noch keine Freigaben erstellt", + "createFirst": "Erstellen Sie Ihre erste Freigabe" + }, + "recipientSelector": { + "emailPlaceholder": "Empfänger-E-Mail eingeben", + "add": "Hinzufügen", + "recipients": "Empfänger ({{count}})", + "notifyAll": "Alle benachrichtigen", + "noRecipients": "Noch keine Empfänger hinzugefügt", + "addSuccess": "Empfänger erfolgreich hinzugefügt", + "addError": "Fehler beim Hinzufügen des Empfängers", + "removeSuccess": "Empfänger erfolgreich entfernt", + "removeError": "Fehler beim Entfernen des Empfängers", + "sendingNotifications": "Benachrichtigungen werden gesendet...", + "notifySuccess": "Empfänger erfolgreich benachrichtigt", + "notifyError": "Fehler beim Benachrichtigen der Empfänger" + }, "resetPassword": { "pageTitle": "Passwort zurücksetzen", "header": { @@ -379,6 +283,10 @@ "invalidToken": "Ungültiges oder fehlendes Zurücksetzungstoken" } }, + "searchBar": { + "placeholder": "Dateien suchen...", + "results": "Gefunden {{filtered}} von {{total}} Dateien" + }, "settings": { "groups": { "defaultDescription": "Konfigurationsoptionen", @@ -513,6 +421,61 @@ }, "pageTitle": "Freigabe" }, + "shareActions": { + "deleteTitle": "Freigabe löschen", + "deleteConfirmation": "Sind Sie sicher, dass Sie diese Freigabe löschen möchten? Diese Aktion kann nicht rückgängig gemacht werden.", + "editTitle": "Freigabe bearbeiten", + "nameLabel": "Freigabename", + "expirationLabel": "Ablaufdatum", + "expirationPlaceholder": "MM/TT/JJJJ SS:MM", + "maxViewsLabel": "Maximale Ansichten", + "maxViewsPlaceholder": "Leer lassen für unbegrenzt", + "passwordProtection": "Passwortgeschützt", + "passwordLabel": "Passwort", + "passwordPlaceholder": "Passwort eingeben", + "newPasswordLabel": "Neues Passwort (leer lassen, um das aktuelle zu behalten)", + "newPasswordPlaceholder": "Neues Passwort eingeben", + "manageFilesTitle": "Dateien verwalten", + "manageRecipientsTitle": "Empfänger verwalten", + "editSuccess": "Freigabe erfolgreich aktualisiert", + "editError": "Fehler beim Aktualisieren der Freigabe" + }, + "shareDetails": { + "title": "Freigabedetails", + "subtitle": "Detaillierte Informationen zu dieser Freigabe", + "basicInfo": "Grundinformationen", + "name": "Name", + "untitled": "Ohne Titel", + "views": "Aufrufe", + "dates": "Daten", + "created": "Erstellt", + "expires": "Läuft ab", + "never": "Nie", + "security": "Sicherheit", + "passwordProtected": "Passwortgeschützt", + "publicAccess": "Öffentlicher Zugriff", + "maxViews": "Maximale Ansichten:", + "files": "Dateien", + "recipients": "Empfänger", + "notAvailable": "N/V", + "invalidDate": "Ungültiges Datum", + "loadError": "Fehler beim Laden der Freigabedetails" + }, + "shareManager": { + "deleteSuccess": "Freigabe erfolgreich gelöscht", + "deleteError": "Fehler beim Löschen der Freigabe", + "updateSuccess": "Freigabe erfolgreich aktualisiert", + "updateError": "Fehler beim Aktualisieren der Freigabe", + "filesUpdateSuccess": "Dateien erfolgreich aktualisiert", + "filesUpdateError": "Fehler beim Aktualisieren der Dateien", + "recipientsUpdateSuccess": "Empfänger erfolgreich aktualisiert", + "recipientsUpdateError": "Fehler beim Aktualisieren der Empfänger", + "linkGenerateSuccess": "Freigabelink erfolgreich generiert", + "linkGenerateError": "Fehler beim Generieren des Freigabelinks", + "notifyLoading": "Benachrichtigungen werden gesendet...", + "notifySuccess": "Empfänger erfolgreich benachrichtigt", + "notifyError": "Fehler beim Benachrichtigen der Empfänger" + }, "shares": { "errors": { "loadFailed": "Fehler beim Laden der Freigaben", @@ -539,6 +502,64 @@ }, "pageTitle": "Freigaben" }, + "sharesTable": { + "ariaLabel": "Freigabetabelle", + "never": "Nie", + "columns": { + "name": "NAME", + "createdAt": "ERSTELLT AM", + "expiresAt": "LÄUFT AB", + "status": "STATUS", + "security": "SICHERHEIT", + "files": "DATEIEN", + "recipients": "EMPFÄNGER", + "actions": "AKTIONEN" + }, + "status": { + "neverExpires": "Läuft nie ab", + "active": "Aktiv", + "expired": "Abgelaufen" + }, + "security": { + "protected": "Geschützt", + "public": "Öffentlich" + }, + "filesCount": "Dateien", + "recipientsCount": "Empfänger", + "actions": { + "menu": "Freigabeaktionsmenü", + "edit": "Bearbeiten", + "manageFiles": "Dateien verwalten", + "manageRecipients": "Empfänger verwalten", + "viewDetails": "Details anzeigen", + "generateLink": "Link generieren", + "editLink": "Link bearbeiten", + "copyLink": "Link kopieren", + "notifyRecipients": "Empfänger benachrichtigen", + "delete": "Löschen" + } + }, + "storageUsage": { + "title": "Speichernutzung", + "ariaLabel": "Fortschrittsbalken der Speichernutzung", + "used": "genutzt", + "available": "verfügbar" + }, + "theme": { + "toggle": "Design umschalten", + "light": "Hell", + "dark": "Dunkel", + "system": "System" + }, + "uploadFile": { + "title": "Datei hochladen", + "selectFile": "Klicken Sie, um eine Datei auszuwählen", + "preview": "Vorschau", + "uploadProgress": "Upload-Fortschritt", + "upload": "Hochladen", + "success": "Datei erfolgreich hochgeladen", + "error": "Fehler beim Hochladen der Datei" + }, "users": { "modes": { "create": "erstellen", @@ -608,29 +629,16 @@ "userr": "Benutzer" } }, - "logo": { - "labels": { - "appLogo": "Anwendungslogo" - }, - "buttons": { - "upload": "Logo hochladen", - "remove": "Logo entfernen" - }, - "messages": { - "uploadSuccess": "Logo erfolgreich hochgeladen", - "removeSuccess": "Logo erfolgreich entfernt" - }, - "errors": { - "uploadFailed": "Fehler beim Hochladen des Logos", - "removeFailed": "Fehler beim Entfernen des Logos" - } - }, - "navbar": { - "logoAlt": "Anwendungslogo", - "profileMenu": "Profilmenü", - "profile": "Profil", - "settings": "Einstellungen", - "usersManagement": "Benutzerverwaltung", - "logout": "Abmelden" + "validation": { + "invalidEmail": "Ungültige E-Mail-Adresse", + "passwordMinLength": "Das Passwort muss mindestens 6 Zeichen lang sein", + "firstNameRequired": "Vorname ist erforderlich", + "lastNameRequired": "Nachname ist erforderlich", + "usernameLength": "Der Benutzername muss mindestens 3 Zeichen lang sein", + "usernameSpaces": "Der Benutzername darf keine Leerzeichen enthalten", + "passwordLength": "Das Passwort muss mindestens 8 Zeichen lang sein", + "passwordsMatch": "Die Passwörter stimmen nicht überein", + "emailRequired": "E-Mail ist erforderlich", + "passwordRequired": "Passwort ist erforderlich" } -} \ No newline at end of file +} diff --git a/apps/web/src/locales/en-US.json b/apps/web/messages/en-US.json similarity index 93% rename from apps/web/src/locales/en-US.json rename to apps/web/messages/en-US.json index c77096b..80e4bd0 100644 --- a/apps/web/src/locales/en-US.json +++ b/apps/web/messages/en-US.json @@ -1,58 +1,4 @@ { - "login": { - "welcome": "Welcome", - "signInToContinue": "Sign in to continue", - "emailLabel": "Email Address", - "emailPlaceholder": "Enter your email", - "passwordLabel": "Password", - "passwordPlaceholder": "Enter your password", - "signIn": "Sign In", - "signingIn": "Signing in...", - "forgotPassword": "Forgot password?", - "pageTitle": "Login" - }, - "errors": { - "invalidCredentials": "Invalid email or password", - "userNotFound": "User not found", - "accountLocked": "Account locked. Please try again later", - "unexpectedError": "An unexpected error occurred. Please try again" - }, - "validation": { - "invalidEmail": "Invalid email address", - "passwordMinLength": "Password must be at least 6 characters", - "firstNameRequired": "First name is required", - "lastNameRequired": "Last name is required", - "usernameLength": "Username must be at least 3 characters", - "usernameSpaces": "Username cannot contain spaces", - "passwordLength": "Password must be at least 8 characters", - "passwordsMatch": "Passwords do not match" - }, - "fileSelector": { - "availableFiles": "Available Files ({{count}})", - "shareFiles": "Share Files ({{count}})", - "searchPlaceholder": "Search files...", - "noMatchingFiles": "No matching files", - "noAvailableFiles": "No files available", - "noFilesInShare": "No files in share", - "saveChanges": "Save Changes" - }, - "recipientSelector": { - "emailPlaceholder": "Enter recipient email", - "add": "Add", - "recipients": "Recipients ({{count}})", - "notifyAll": "Notify All", - "noRecipients": "No recipients added yet", - "addSuccess": "Recipient added successfully", - "addError": "Failed to add recipient", - "removeSuccess": "Recipient removed successfully", - "removeError": "Failed to remove recipient", - "sendingNotifications": "Sending notifications...", - "notifySuccess": "Recipients notified successfully", - "notifyError": "Failed to notify recipients" - }, - "navigation": { - "dashboard": "Dashboard" - }, "common": { "loading": "Loading, please wait...", "cancel": "Cancel", @@ -78,6 +24,22 @@ "success": "Share created successfully", "error": "Failed to create share" }, + "dashboard": { + "loadError": "Failed to load dashboard data", + "linkCopied": "Link copied to clipboard", + "pageTitle": "Dashboard", + "breadcrumb": "Dashboard" + }, + "emptyState": { + "noFiles": "No files uploaded yet", + "uploadFile": "Upload File" + }, + "errors": { + "invalidCredentials": "Invalid email or password", + "userNotFound": "User not found", + "accountLocked": "Account locked. Please try again later", + "unexpectedError": "An unexpected error occurred. Please try again" + }, "fileActions": { "editFile": "Edit File", "nameLabel": "Name", @@ -86,9 +48,16 @@ "descriptionLabel": "Description", "descriptionPlaceholder": "Enter file description", "deleteFile": "Delete File", - "deleteConfirmation": "Are you sure you want to delete \"{{fileName}}\"?", + "deleteConfirmation": "Are you sure you want to delete ?", "deleteWarning": "This action cannot be undone." }, + "fileManager": { + "downloadError": "Failed to download file", + "updateSuccess": "File updated successfully", + "updateError": "Failed to update file", + "deleteSuccess": "File deleted successfully", + "deleteError": "Failed to delete file" + }, "filePreview": { "loading": "Loading preview...", "notAvailable": "Preview not available", @@ -98,68 +67,21 @@ "loadError": "Failed to load preview", "downloadError": "Failed to download file" }, - "generateShareLink": { - "generateTitle": "Generate Share Link", - "updateTitle": "Update Share Link", - "generateDescription": "Generate a link to share your files", - "updateDescription": "Update the alias for this share link", - "aliasPlaceholder": "Enter alias", - "linkReady": "Your share link is ready:", - "generateButton": "Generate Link", - "updateButton": "Update Link", - "copyButton": "Copy Link", - "success": "Link generated successfully", - "error": "Failed to generate link", - "copied": "Link copied to clipboard" + "fileSelector": { + "availableFiles": "Available Files ({count})", + "shareFiles": "Share Files ({count})", + "searchPlaceholder": "Search files...", + "noMatchingFiles": "No matching files", + "noAvailableFiles": "No files available", + "noFilesInShare": "No files in share", + "saveChanges": "Save Changes" }, - "shareActions": { - "deleteTitle": "Delete Share", - "deleteConfirmation": "Are you sure you want to delete this share? This action cannot be undone.", - "editTitle": "Edit Share", - "nameLabel": "Share Name", - "expirationLabel": "Expiration Date", - "expirationPlaceholder": "MM/DD/YYYY HH:MM", - "maxViewsLabel": "Max Views", - "maxViewsPlaceholder": "Leave empty for unlimited", - "passwordProtection": "Password Protected", - "passwordLabel": "Password", - "passwordPlaceholder": "Enter password", - "newPasswordLabel": "New Password (leave empty to keep current)", - "newPasswordPlaceholder": "Enter new password", - "manageFilesTitle": "Manage Files", - "manageRecipientsTitle": "Manage Recipients", - "editSuccess": "Share updated successfully", - "editError": "Failed to update share" - }, - "shareDetails": { - "title": "Share Details", - "subtitle": "Detailed information about this share", - "basicInfo": "Basic Information", - "name": "Name", - "untitled": "Untitled", - "views": "Views", - "dates": "Dates", - "created": "Created", - "expires": "Expires", - "never": "Never", - "security": "Security", - "passwordProtected": "Password Protected", - "publicAccess": "Public Access", - "maxViews": "Max Views: {{count}}", - "files": "Files ({{count}})", - "recipients": "Recipients ({{count}})", - "notAvailable": "N/A", - "invalidDate": "Invalid date", - "loadError": "Failed to load share details" - }, - "uploadFile": { - "title": "Upload File", - "selectFile": "Click to select a file", - "preview": "Preview", - "uploadProgress": "Upload progress", - "upload": "Upload", - "success": "File uploaded successfully", - "error": "Failed to upload file" + "files": { + "title": "All Files", + "uploadFile": "Upload File", + "loadError": "Failed to load files", + "pageTitle": "My Files", + "breadcrumb": "My Files" }, "filesTable": { "ariaLabel": "Files table", @@ -179,119 +101,10 @@ "delete": "Delete" } }, - "sharesTable": { - "ariaLabel": "Shares table", - "never": "Never", - "columns": { - "name": "NAME", - "createdAt": "CREATED AT", - "expiresAt": "EXPIRES AT", - "status": "STATUS", - "security": "SECURITY", - "files": "FILES", - "recipients": "RECIPIENTS", - "actions": "ACTIONS" - }, - "status": { - "neverExpires": "Never Expires", - "active": "Active", - "expired": "Expired" - }, - "security": { - "protected": "Protected", - "public": "Public" - }, - "filesCount": "{{count}} files", - "recipientsCount": "{{count}} recipients", - "actions": { - "menu": "Share actions menu", - "edit": "Edit", - "manageFiles": "Manage Files", - "manageRecipients": "Manage Recipients", - "viewDetails": "View Details", - "generateLink": "Generate Link", - "editLink": "Edit Link", - "copyLink": "Copy Link", - "notifyRecipients": "Notify Recipients", - "delete": "Delete" - } - }, "footer": { "poweredBy": "Powered by", "kyanHomepage": "Kyantech homepage" }, - "fileManager": { - "downloadError": "Failed to download file", - "updateSuccess": "File updated successfully", - "updateError": "Failed to update file", - "deleteSuccess": "File deleted successfully", - "deleteError": "Failed to delete file" - }, - "shareManager": { - "deleteSuccess": "Share deleted successfully", - "deleteError": "Failed to delete share", - "updateSuccess": "Share updated successfully", - "updateError": "Failed to update share", - "filesUpdateSuccess": "Files updated successfully", - "filesUpdateError": "Failed to update files", - "recipientsUpdateSuccess": "Recipients updated successfully", - "recipientsUpdateError": "Failed to update recipients", - "linkGenerateSuccess": "Share link generated successfully", - "linkGenerateError": "Failed to generate share link", - "notifyLoading": "Sending notifications...", - "notifySuccess": "Recipients notified successfully", - "notifyError": "Failed to notify recipients" - }, - "quickAccess": { - "files": { - "title": "My Files", - "description": "Access and manage your uploaded files" - }, - "shares": { - "title": "My Shares", - "description": "View and manage your shared files" - } - }, - "recentFiles": { - "title": "Recent Uploads", - "viewAll": "View All", - "uploadFile": "Upload File", - "noFiles": "No files uploaded yet" - }, - "recentShares": { - "title": "Recent Shares", - "viewAll": "View All", - "createShare": "Create Share", - "noShares": "No shares created yet", - "createFirst": "Create your first share" - }, - "storageUsage": { - "title": "Storage Usage", - "ariaLabel": "Storage usage progress bar", - "used": "{{size}} used", - "available": "{{size}} available" - }, - "dashboard": { - "loadError": "Failed to load dashboard data", - "linkCopied": "Link copied to clipboard", - "pageTitle": "Dashboard", - "breadcrumb": "Dashboard" - }, - "emptyState": { - "noFiles": "No files uploaded yet", - "uploadFile": "Upload File" - }, - "files": { - "title": "All Files", - "uploadFile": "Upload File", - "loadError": "Failed to load files", - "pageTitle": "My Files", - "breadcrumb": "My Files" - }, - "searchBar": { - "placeholder": "Search files...", - "results": "Found {{filtered}} of {{total}} files" - }, "forgotPassword": { "emailLabel": "Email Address", "emailPlaceholder": "Enter your email", @@ -303,6 +116,20 @@ "resetInstructions": "Reset instructions sent to your email", "pageTitle": "Forgot Password" }, + "generateShareLink": { + "generateTitle": "Generate Share Link", + "updateTitle": "Update Share Link", + "generateDescription": "Generate a link to share your files", + "updateDescription": "Update the alias for this share link", + "aliasPlaceholder": "Enter alias", + "linkReady": "Your share link is ready:", + "generateButton": "Generate Link", + "updateButton": "Update Link", + "copyButton": "Copy Link", + "success": "Link generated successfully", + "error": "Failed to generate link", + "copied": "Link copied to clipboard" + }, "home": { "description": "The open-source alternative to WeTransfer. Share files securely, without tracking, or limitations.", "documentation": "Documentation", @@ -314,6 +141,46 @@ }, "pageTitle": "Home" }, + "login": { + "welcome": "Welcome to", + "signInToContinue": "Sign in to continue", + "emailLabel": "Email Address", + "emailPlaceholder": "Enter your email", + "passwordLabel": "Password", + "passwordPlaceholder": "Enter your password", + "signIn": "Sign In", + "signingIn": "Signing in...", + "forgotPassword": "Forgot password?", + "pageTitle": "Login" + }, + "logo": { + "labels": { + "appLogo": "App Logo" + }, + "buttons": { + "upload": "Upload Logo", + "remove": "Remove Logo" + }, + "messages": { + "uploadSuccess": "Logo uploaded successfully", + "removeSuccess": "Logo removed successfully" + }, + "errors": { + "uploadFailed": "Failed to upload logo", + "removeFailed": "Failed to remove logo" + } + }, + "navbar": { + "logoAlt": "App Logo", + "profileMenu": "Profile Menu", + "profile": "Profile", + "settings": "Settings", + "usersManagement": "Users Management", + "logout": "Log Out" + }, + "navigation": { + "dashboard": "Dashboard" + }, "profile": { "password": { "title": "Change Password", @@ -356,6 +223,43 @@ }, "pageTitle": "Profile" }, + "quickAccess": { + "files": { + "title": "My Files", + "description": "Access and manage your uploaded files" + }, + "shares": { + "title": "My Shares", + "description": "View and manage your shared files" + } + }, + "recentFiles": { + "title": "Recent Uploads", + "viewAll": "View All", + "uploadFile": "Upload File", + "noFiles": "No files uploaded yet" + }, + "recentShares": { + "title": "Recent Shares", + "viewAll": "View All", + "createShare": "Create Share", + "noShares": "No shares created yet", + "createFirst": "Create your first share" + }, + "recipientSelector": { + "emailPlaceholder": "Enter recipient email", + "add": "Add", + "recipients": "Recipients ({count})", + "notifyAll": "Notify All", + "noRecipients": "No recipients added yet", + "addSuccess": "Recipient added successfully", + "addError": "Failed to add recipient", + "removeSuccess": "Recipient removed successfully", + "removeError": "Failed to remove recipient", + "sendingNotifications": "Sending notifications...", + "notifySuccess": "Recipients notified successfully", + "notifyError": "Failed to notify recipients" + }, "resetPassword": { "pageTitle": "Reset Password", "header": { @@ -379,6 +283,10 @@ "invalidToken": "Invalid or missing reset token" } }, + "searchBar": { + "placeholder": "Search files...", + "results": "Found {filtered} of {total} files" + }, "settings": { "groups": { "defaultDescription": "Configuration options", @@ -471,7 +379,7 @@ } }, "buttons": { - "save": "Save {{group}}" + "save": "Save {group}" }, "errors": { "loadFailed": "Failed to load settings", @@ -479,7 +387,7 @@ }, "messages": { "noChanges": "No changes to save", - "updateSuccess": "{{group}} settings updated successfully" + "updateSuccess": "{group} settings updated successfully" }, "title": "Settings", "breadcrumb": "Settings", @@ -504,8 +412,8 @@ }, "details": { "untitled": "Untitled Share", - "created": "Created: {{date}}", - "expires": "Expires: {{date}}" + "created": "Created: {date}", + "expires": "Expires: {date}" }, "notFound": { "title": "Share Not Found", @@ -513,6 +421,61 @@ }, "pageTitle": "Share" }, + "shareActions": { + "deleteTitle": "Delete Share", + "deleteConfirmation": "Are you sure you want to delete this share? This action cannot be undone.", + "editTitle": "Edit Share", + "nameLabel": "Share Name", + "expirationLabel": "Expiration Date", + "expirationPlaceholder": "MM/DD/YYYY HH:MM", + "maxViewsLabel": "Max Views", + "maxViewsPlaceholder": "Leave empty for unlimited", + "passwordProtection": "Password Protected", + "passwordLabel": "Password", + "passwordPlaceholder": "Enter password", + "newPasswordLabel": "New Password (leave empty to keep current)", + "newPasswordPlaceholder": "Enter new password", + "manageFilesTitle": "Manage Files", + "manageRecipientsTitle": "Manage Recipients", + "editSuccess": "Share updated successfully", + "editError": "Failed to update share" + }, + "shareDetails": { + "title": "Share Details", + "subtitle": "Detailed information about this share", + "basicInfo": "Basic Information", + "name": "Name", + "untitled": "Untitled", + "views": "Views", + "dates": "Dates", + "created": "Created", + "expires": "Expires", + "never": "Never", + "security": "Security", + "passwordProtected": "Password Protected", + "publicAccess": "Public Access", + "maxViews": "Max Views:", + "files": "Files", + "recipients": "Recipients", + "notAvailable": "N/A", + "invalidDate": "Invalid date", + "loadError": "Failed to load share details" + }, + "shareManager": { + "deleteSuccess": "Share deleted successfully", + "deleteError": "Failed to delete share", + "updateSuccess": "Share updated successfully", + "updateError": "Failed to update share", + "filesUpdateSuccess": "Files updated successfully", + "filesUpdateError": "Failed to update files", + "recipientsUpdateSuccess": "Recipients updated successfully", + "recipientsUpdateError": "Failed to update recipients", + "linkGenerateSuccess": "Share link generated successfully", + "linkGenerateError": "Failed to generate share link", + "notifyLoading": "Sending notifications...", + "notifySuccess": "Recipients notified successfully", + "notifyError": "Failed to notify recipients" + }, "shares": { "errors": { "loadFailed": "Failed to load shares", @@ -535,10 +498,68 @@ "title": "All Shares", "createButton": "Create Share", "placeholder": "Search shares...", - "results": "Found {{filtered}} of {{total}} shares" + "results": "Found {filtered} of {total} shares" }, "pageTitle": "Shares" }, + "sharesTable": { + "ariaLabel": "Shares table", + "never": "Never", + "columns": { + "name": "NAME", + "createdAt": "CREATED AT", + "expiresAt": "EXPIRES AT", + "status": "STATUS", + "security": "SECURITY", + "files": "FILES", + "recipients": "RECIPIENTS", + "actions": "ACTIONS" + }, + "status": { + "neverExpires": "Never Expires", + "active": "Active", + "expired": "Expired" + }, + "security": { + "protected": "Protected", + "public": "Public" + }, + "filesCount": "files", + "recipientsCount": "recipients", + "actions": { + "menu": "Share actions menu", + "edit": "Edit", + "manageFiles": "Manage Files", + "manageRecipients": "Manage Recipients", + "viewDetails": "View Details", + "generateLink": "Generate Link", + "editLink": "Edit Link", + "copyLink": "Copy Link", + "notifyRecipients": "Notify Recipients", + "delete": "Delete" + } + }, + "storageUsage": { + "title": "Storage Usage", + "ariaLabel": "Storage usage progress bar", + "used": "used", + "available": "available" + }, + "theme": { + "toggle": "Toggle theme", + "light": "Light", + "dark": "Dark", + "system": "System" + }, + "uploadFile": { + "title": "Upload File", + "selectFile": "Click to select a file", + "preview": "Preview", + "uploadProgress": "Upload progress", + "upload": "Upload", + "success": "File uploaded successfully", + "error": "Failed to upload file" + }, "users": { "modes": { "create": "create", @@ -546,7 +567,7 @@ }, "errors": { "loadFailed": "Failed to load users", - "submitFailed": "Failed to {{mode}} user", + "submitFailed": "Failed to {mode} user", "deleteFailed": "Failed to delete user", "statusUpdateFailed": "Failed to update user status" }, @@ -565,7 +586,7 @@ }, "delete": { "title": "Confirm Delete User", - "confirmation": "Are you sure you want to delete user {{firstName}} {{lastName}}? This action cannot be undone.", + "confirmation": "Are you sure you want to delete user {firstName} {lastName}? This action cannot be undone.", "confirm": "Delete User" }, "form": { @@ -586,7 +607,7 @@ }, "status": { "title": "Confirm Status Change", - "confirmation": "Are you sure you want to {{action}} user {{firstName}} {{lastName}}?", + "confirmation": "Are you sure you want to {action} user {firstName} {lastName}?", "activate": "activate", "deactivate": "deactivate", "user": "User" @@ -608,29 +629,15 @@ "userr": "User" } }, - "logo": { - "labels": { - "appLogo": "App Logo" - }, - "buttons": { - "upload": "Upload Logo", - "remove": "Remove Logo" - }, - "messages": { - "uploadSuccess": "Logo uploaded successfully", - "removeSuccess": "Logo removed successfully" - }, - "errors": { - "uploadFailed": "Failed to upload logo", - "removeFailed": "Failed to remove logo" - } - }, - "navbar": { - "logoAlt": "App Logo", - "profileMenu": "Profile Menu", - "profile": "Profile", - "settings": "Settings", - "usersManagement": "Users Management", - "logout": "Log Out" + "validation": { + "firstNameRequired": "First name is required", + "lastNameRequired": "Last name is required", + "usernameLength": "Username must be at least 3 characters long", + "usernameSpaces": "Username cannot contain spaces", + "invalidEmail": "Please enter a valid email address", + "passwordLength": "Password must be at least 8 characters long", + "passwordsMatch": "Passwords must match", + "emailRequired": "Email is required", + "passwordRequired": "Password is required" } -} \ No newline at end of file +} diff --git a/apps/web/src/locales/es-ES.json b/apps/web/messages/es-ES.json similarity index 97% rename from apps/web/src/locales/es-ES.json rename to apps/web/messages/es-ES.json index 513a3d1..aea790e 100644 --- a/apps/web/src/locales/es-ES.json +++ b/apps/web/messages/es-ES.json @@ -1,58 +1,4 @@ { - "login": { - "welcome": "Bienvenido", - "signInToContinue": "Inicia sesión para continuar", - "emailLabel": "Dirección de correo electrónico", - "emailPlaceholder": "Introduce tu correo electrónico", - "passwordLabel": "Contraseña", - "passwordPlaceholder": "Introduce tu contraseña", - "signIn": "Iniciar sesión", - "signingIn": "Iniciando sesión...", - "forgotPassword": "¿Olvidaste tu contraseña?", - "pageTitle": "Iniciar sesión" - }, - "errors": { - "invalidCredentials": "Correo electrónico o contraseña inválidos", - "userNotFound": "Usuario no encontrado", - "accountLocked": "Cuenta bloqueada. Por favor, inténtalo de nuevo más tarde", - "unexpectedError": "Ocurrió un error inesperado. Por favor, inténtalo de nuevo" - }, - "validation": { - "invalidEmail": "Dirección de correo electrónico no válida", - "passwordMinLength": "La contraseña debe tener al menos 6 caracteres", - "firstNameRequired": "Se requiere el nombre", - "lastNameRequired": "Se requiere el apellido", - "usernameLength": "El nombre de usuario debe tener al menos 3 caracteres", - "usernameSpaces": "El nombre de usuario no puede contener espacios", - "passwordLength": "La contraseña debe tener al menos 8 caracteres", - "passwordsMatch": "Las contraseñas no coinciden" - }, - "fileSelector": { - "availableFiles": "Archivos disponibles ({{count}})", - "shareFiles": "Compartir archivos ({{count}})", - "searchPlaceholder": "Buscar archivos...", - "noMatchingFiles": "No hay archivos que coincidan", - "noAvailableFiles": "No hay archivos disponibles", - "noFilesInShare": "No hay archivos compartidos", - "saveChanges": "Guardar cambios" - }, - "recipientSelector": { - "emailPlaceholder": "Introduce el correo del destinatario", - "add": "Agregar", - "recipients": "Destinatarios ({{count}})", - "notifyAll": "Notificar a todos", - "noRecipients": "Aún no se han agregado destinatarios", - "addSuccess": "Destinatario agregado exitosamente", - "addError": "Error al agregar el destinatario", - "removeSuccess": "Destinatario eliminado exitosamente", - "removeError": "Error al eliminar el destinatario", - "sendingNotifications": "Enviando notificaciones...", - "notifySuccess": "Destinatarios notificados exitosamente", - "notifyError": "Error al notificar a los destinatarios" - }, - "navigation": { - "dashboard": "Panel de control" - }, "common": { "loading": "Cargando, por favor espera...", "cancel": "Cancelar", @@ -78,6 +24,22 @@ "success": "Compartición creada exitosamente", "error": "Error al crear la compartición" }, + "dashboard": { + "loadError": "Error al cargar los datos del tablero", + "linkCopied": "Enlace copiado al portapapeles", + "pageTitle": "Panel de control", + "breadcrumb": "Panel de control" + }, + "emptyState": { + "noFiles": "Aún no se han subido archivos", + "uploadFile": "Subir archivo" + }, + "errors": { + "invalidCredentials": "Correo electrónico o contraseña inválidos", + "userNotFound": "Usuario no encontrado", + "accountLocked": "Cuenta bloqueada. Por favor, inténtalo de nuevo más tarde", + "unexpectedError": "Ocurrió un error inesperado. Por favor, inténtalo de nuevo" + }, "fileActions": { "editFile": "Editar archivo", "nameLabel": "Nombre", @@ -86,9 +48,16 @@ "descriptionLabel": "Descripción", "descriptionPlaceholder": "Introduce una descripción del archivo", "deleteFile": "Eliminar archivo", - "deleteConfirmation": "¿Estás seguro de que deseas eliminar \"{{fileName}}\"?", + "deleteConfirmation": "¿Estás seguro de que deseas eliminar ?", "deleteWarning": "Esta acción no se puede deshacer." }, + "fileManager": { + "downloadError": "Error al descargar el archivo", + "updateSuccess": "Archivo actualizado exitosamente", + "updateError": "Error al actualizar el archivo", + "deleteSuccess": "Archivo eliminado exitosamente", + "deleteError": "Error al eliminar el archivo" + }, "filePreview": { "loading": "Cargando vista previa...", "notAvailable": "Vista previa no disponible", @@ -98,68 +67,21 @@ "loadError": "Error al cargar la vista previa", "downloadError": "Error al descargar el archivo" }, - "generateShareLink": { - "generateTitle": "Generar enlace de compartición", - "updateTitle": "Actualizar enlace de compartición", - "generateDescription": "Genera un enlace para compartir tus archivos", - "updateDescription": "Actualiza el alias para este enlace de compartición", - "aliasPlaceholder": "Introduce un alias", - "linkReady": "Tu enlace de compartición está listo:", - "generateButton": "Generar enlace", - "updateButton": "Actualizar enlace", - "copyButton": "Copiar enlace", - "success": "Enlace generado exitosamente", - "error": "Error al generar el enlace", - "copied": "Enlace copiado al portapapeles" + "fileSelector": { + "availableFiles": "Archivos disponibles ({{count}})", + "shareFiles": "Compartir archivos ({{count}})", + "searchPlaceholder": "Buscar archivos...", + "noMatchingFiles": "No hay archivos que coincidan", + "noAvailableFiles": "No hay archivos disponibles", + "noFilesInShare": "No hay archivos compartidos", + "saveChanges": "Guardar cambios" }, - "shareActions": { - "deleteTitle": "Eliminar compartición", - "deleteConfirmation": "¿Estás seguro de que deseas eliminar esta compartición? Esta acción no se puede deshacer.", - "editTitle": "Editar compartición", - "nameLabel": "Nombre de la compartición", - "expirationLabel": "Fecha de expiración", - "expirationPlaceholder": "MM/DD/AAAA HH:MM", - "maxViewsLabel": "Máximo de visualizaciones", - "maxViewsPlaceholder": "Dejar vacío para ilimitado", - "passwordProtection": "Protegido con contraseña", - "passwordLabel": "Contraseña", - "passwordPlaceholder": "Introduce la contraseña", - "newPasswordLabel": "Nueva contraseña (dejar vacío para mantener la actual)", - "newPasswordPlaceholder": "Introduce la nueva contraseña", - "manageFilesTitle": "Gestionar archivos", - "manageRecipientsTitle": "Gestionar destinatarios", - "editSuccess": "Compartición actualizada exitosamente", - "editError": "Error al actualizar la compartición" - }, - "shareDetails": { - "title": "Detalles de la compartición", - "subtitle": "Información detallada sobre esta compartición", - "basicInfo": "Información básica", - "name": "Nombre", - "untitled": "Sin título", - "views": "Visualizaciones", - "dates": "Fechas", - "created": "Creada", - "expires": "Expira", - "never": "Nunca", - "security": "Seguridad", - "passwordProtected": "Protegido con contraseña", - "publicAccess": "Acceso público", - "maxViews": "Máximo de visualizaciones: {{count}}", - "files": "Archivos ({{count}})", - "recipients": "Destinatarios ({{count}})", - "notAvailable": "N/D", - "invalidDate": "Fecha inválida", - "loadError": "Error al cargar los detalles de la compartición" - }, - "uploadFile": { - "title": "Subir archivo", - "selectFile": "Haz clic para seleccionar un archivo", - "preview": "Vista previa", - "uploadProgress": "Progreso de la subida", - "upload": "Subir", - "success": "Archivo subido exitosamente", - "error": "Error al subir el archivo" + "files": { + "title": "Todos los archivos", + "uploadFile": "Subir archivo", + "loadError": "Error al cargar los archivos", + "pageTitle": "Mis archivos", + "breadcrumb": "Mis archivos" }, "filesTable": { "ariaLabel": "Tabla de archivos", @@ -179,119 +101,10 @@ "delete": "Eliminar" } }, - "sharesTable": { - "ariaLabel": "Tabla de comparticiones", - "never": "Nunca", - "columns": { - "name": "NOMBRE", - "createdAt": "CREADO", - "expiresAt": "EXPIRA", - "status": "ESTADO", - "security": "SEGURIDAD", - "files": "ARCHIVOS", - "recipients": "DESTINATARIOS", - "actions": "ACCIONES" - }, - "status": { - "neverExpires": "Nunca expira", - "active": "Activa", - "expired": "Expirada" - }, - "security": { - "protected": "Protegida", - "public": "Pública" - }, - "filesCount": "{{count}} archivos", - "recipientsCount": "{{count}} destinatarios", - "actions": { - "menu": "Menú de acciones de la compartición", - "edit": "Editar", - "manageFiles": "Gestionar archivos", - "manageRecipients": "Gestionar destinatarios", - "viewDetails": "Ver detalles", - "generateLink": "Generar enlace", - "editLink": "Editar enlace", - "copyLink": "Copiar enlace", - "notifyRecipients": "Notificar destinatarios", - "delete": "Eliminar" - } - }, "footer": { "poweredBy": "Desarrollado por", "kyanHomepage": "Página principal de Kyantech" }, - "fileManager": { - "downloadError": "Error al descargar el archivo", - "updateSuccess": "Archivo actualizado exitosamente", - "updateError": "Error al actualizar el archivo", - "deleteSuccess": "Archivo eliminado exitosamente", - "deleteError": "Error al eliminar el archivo" - }, - "shareManager": { - "deleteSuccess": "Compartición eliminada exitosamente", - "deleteError": "Error al eliminar la compartición", - "updateSuccess": "Compartición actualizada exitosamente", - "updateError": "Error al actualizar la compartición", - "filesUpdateSuccess": "Archivos actualizados exitosamente", - "filesUpdateError": "Error al actualizar los archivos", - "recipientsUpdateSuccess": "Destinatarios actualizados exitosamente", - "recipientsUpdateError": "Error al actualizar los destinatarios", - "linkGenerateSuccess": "Enlace de compartición generado exitosamente", - "linkGenerateError": "Error al generar el enlace de compartición", - "notifyLoading": "Enviando notificaciones...", - "notifySuccess": "Destinatarios notificados exitosamente", - "notifyError": "Error al notificar a los destinatarios" - }, - "quickAccess": { - "files": { - "title": "Mis archivos", - "description": "Accede y gestiona tus archivos subidos" - }, - "shares": { - "title": "Mis comparticiones", - "description": "Visualiza y gestiona tus archivos compartidos" - } - }, - "recentFiles": { - "title": "Subidas recientes", - "viewAll": "Ver todo", - "uploadFile": "Subir archivo", - "noFiles": "Aún no se han subido archivos" - }, - "recentShares": { - "title": "Comparticiones recientes", - "viewAll": "Ver todo", - "createShare": "Crear compartición", - "noShares": "Aún no se han creado comparticiones", - "createFirst": "Crea tu primera compartición" - }, - "storageUsage": { - "title": "Uso de almacenamiento", - "ariaLabel": "Barra de progreso del uso de almacenamiento", - "used": "{{size}} usados", - "available": "{{size}} disponibles" - }, - "dashboard": { - "loadError": "Error al cargar los datos del tablero", - "linkCopied": "Enlace copiado al portapapeles", - "pageTitle": "Panel de control", - "breadcrumb": "Panel de control" - }, - "emptyState": { - "noFiles": "Aún no se han subido archivos", - "uploadFile": "Subir archivo" - }, - "files": { - "title": "Todos los archivos", - "uploadFile": "Subir archivo", - "loadError": "Error al cargar los archivos", - "pageTitle": "Mis archivos", - "breadcrumb": "Mis archivos" - }, - "searchBar": { - "placeholder": "Buscar archivos...", - "results": "Se encontraron {{filtered}} de {{total}} archivos" - }, "forgotPassword": { "emailLabel": "Dirección de correo electrónico", "emailPlaceholder": "Introduce tu correo electrónico", @@ -303,6 +116,20 @@ "resetInstructions": "Instrucciones de restablecimiento enviadas a tu correo electrónico", "pageTitle": "Recuperar contraseña" }, + "generateShareLink": { + "generateTitle": "Generar enlace de compartición", + "updateTitle": "Actualizar enlace de compartición", + "generateDescription": "Genera un enlace para compartir tus archivos", + "updateDescription": "Actualiza el alias para este enlace de compartición", + "aliasPlaceholder": "Introduce un alias", + "linkReady": "Tu enlace de compartición está listo:", + "generateButton": "Generar enlace", + "updateButton": "Actualizar enlace", + "copyButton": "Copiar enlace", + "success": "Enlace generado exitosamente", + "error": "Error al generar el enlace", + "copied": "Enlace copiado al portapapeles" + }, "home": { "description": "La alternativa de código abierto a WeTransfer. Comparte archivos de forma segura, sin rastreo ni limitaciones.", "documentation": "Documentación", @@ -314,6 +141,46 @@ }, "pageTitle": "Inicio" }, + "login": { + "welcome": "Bienvenido a", + "signInToContinue": "Inicia sesión para continuar", + "emailLabel": "Dirección de correo electrónico", + "emailPlaceholder": "Introduce tu correo electrónico", + "passwordLabel": "Contraseña", + "passwordPlaceholder": "Introduce tu contraseña", + "signIn": "Iniciar sesión", + "signingIn": "Iniciando sesión...", + "forgotPassword": "¿Olvidaste tu contraseña?", + "pageTitle": "Iniciar sesión" + }, + "logo": { + "labels": { + "appLogo": "Logo de la aplicación" + }, + "buttons": { + "upload": "Subir logo", + "remove": "Eliminar logo" + }, + "messages": { + "uploadSuccess": "Logo subido exitosamente", + "removeSuccess": "Logo eliminado exitosamente" + }, + "errors": { + "uploadFailed": "Error al subir el logo", + "removeFailed": "Error al eliminar el logo" + } + }, + "navbar": { + "logoAlt": "Logo de la aplicación", + "profileMenu": "Menú de perfil", + "profile": "Perfil", + "settings": "Configuración", + "usersManagement": "Gestión de usuarios", + "logout": "Cerrar sesión" + }, + "navigation": { + "dashboard": "Panel de control" + }, "profile": { "password": { "title": "Cambiar contraseña", @@ -356,6 +223,43 @@ }, "pageTitle": "Perfil" }, + "quickAccess": { + "files": { + "title": "Mis archivos", + "description": "Accede y gestiona tus archivos subidos" + }, + "shares": { + "title": "Mis comparticiones", + "description": "Visualiza y gestiona tus archivos compartidos" + } + }, + "recentFiles": { + "title": "Subidas recientes", + "viewAll": "Ver todo", + "uploadFile": "Subir archivo", + "noFiles": "Aún no se han subido archivos" + }, + "recentShares": { + "title": "Comparticiones recientes", + "viewAll": "Ver todo", + "createShare": "Crear compartición", + "noShares": "Aún no se han creado comparticiones", + "createFirst": "Crea tu primera compartición" + }, + "recipientSelector": { + "emailPlaceholder": "Introduce el correo del destinatario", + "add": "Agregar", + "recipients": "Destinatarios ({{count}})", + "notifyAll": "Notificar a todos", + "noRecipients": "Aún no se han agregado destinatarios", + "addSuccess": "Destinatario agregado exitosamente", + "addError": "Error al agregar el destinatario", + "removeSuccess": "Destinatario eliminado exitosamente", + "removeError": "Error al eliminar el destinatario", + "sendingNotifications": "Enviando notificaciones...", + "notifySuccess": "Destinatarios notificados exitosamente", + "notifyError": "Error al notificar a los destinatarios" + }, "resetPassword": { "pageTitle": "Restablecer contraseña", "header": { @@ -379,6 +283,10 @@ "invalidToken": "Token de restablecimiento inválido o ausente" } }, + "searchBar": { + "placeholder": "Buscar archivos...", + "results": "Se encontraron {{filtered}} de {{total}} archivos" + }, "settings": { "groups": { "defaultDescription": "Opciones de configuración", @@ -513,6 +421,61 @@ }, "pageTitle": "Compartición" }, + "shareActions": { + "deleteTitle": "Eliminar compartición", + "deleteConfirmation": "¿Estás seguro de que deseas eliminar esta compartición? Esta acción no se puede deshacer.", + "editTitle": "Editar compartición", + "nameLabel": "Nombre de la compartición", + "expirationLabel": "Fecha de expiración", + "expirationPlaceholder": "MM/DD/AAAA HH:MM", + "maxViewsLabel": "Máximo de visualizaciones", + "maxViewsPlaceholder": "Dejar vacío para ilimitado", + "passwordProtection": "Protegido con contraseña", + "passwordLabel": "Contraseña", + "passwordPlaceholder": "Introduce la contraseña", + "newPasswordLabel": "Nueva contraseña (dejar vacío para mantener la actual)", + "newPasswordPlaceholder": "Introduce la nueva contraseña", + "manageFilesTitle": "Gestionar archivos", + "manageRecipientsTitle": "Gestionar destinatarios", + "editSuccess": "Compartición actualizada exitosamente", + "editError": "Error al actualizar la compartición" + }, + "shareDetails": { + "title": "Detalles de la compartición", + "subtitle": "Información detallada sobre esta compartición", + "basicInfo": "Información básica", + "name": "Nombre", + "untitled": "Sin título", + "views": "Visualizaciones", + "dates": "Fechas", + "created": "Creada", + "expires": "Expira", + "never": "Nunca", + "security": "Seguridad", + "passwordProtected": "Protegido con contraseña", + "publicAccess": "Acceso público", + "maxViews": "Máximo de visualizaciones:", + "files": "Archivos", + "recipients": "Destinatarios", + "notAvailable": "N/D", + "invalidDate": "Fecha inválida", + "loadError": "Error al cargar los detalles de la compartición" + }, + "shareManager": { + "deleteSuccess": "Compartición eliminada exitosamente", + "deleteError": "Error al eliminar la compartición", + "updateSuccess": "Compartición actualizada exitosamente", + "updateError": "Error al actualizar la compartición", + "filesUpdateSuccess": "Archivos actualizados exitosamente", + "filesUpdateError": "Error al actualizar los archivos", + "recipientsUpdateSuccess": "Destinatarios actualizados exitosamente", + "recipientsUpdateError": "Error al actualizar los destinatarios", + "linkGenerateSuccess": "Enlace de compartición generado exitosamente", + "linkGenerateError": "Error al generar el enlace de compartición", + "notifyLoading": "Enviando notificaciones...", + "notifySuccess": "Destinatarios notificados exitosamente", + "notifyError": "Error al notificar a los destinatarios" + }, "shares": { "errors": { "loadFailed": "Error al cargar las comparticiones", @@ -539,6 +502,64 @@ }, "pageTitle": "Comparticiones" }, + "sharesTable": { + "ariaLabel": "Tabla de comparticiones", + "never": "Nunca", + "columns": { + "name": "NOMBRE", + "createdAt": "CREADO", + "expiresAt": "EXPIRA", + "status": "ESTADO", + "security": "SEGURIDAD", + "files": "ARCHIVOS", + "recipients": "DESTINATARIOS", + "actions": "ACCIONES" + }, + "status": { + "neverExpires": "Nunca expira", + "active": "Activa", + "expired": "Expirada" + }, + "security": { + "protected": "Protegida", + "public": "Pública" + }, + "filesCount": "archivos", + "recipientsCount": "destinatarios", + "actions": { + "menu": "Menú de acciones de la compartición", + "edit": "Editar", + "manageFiles": "Gestionar archivos", + "manageRecipients": "Gestionar destinatarios", + "viewDetails": "Ver detalles", + "generateLink": "Generar enlace", + "editLink": "Editar enlace", + "copyLink": "Copiar enlace", + "notifyRecipients": "Notificar destinatarios", + "delete": "Eliminar" + } + }, + "storageUsage": { + "title": "Uso de almacenamiento", + "ariaLabel": "Barra de progreso del uso de almacenamiento", + "used": "usados", + "available": "disponibles" + }, + "theme": { + "toggle": "Cambiar tema", + "light": "Claro", + "dark": "Oscuro", + "system": "Sistema" + }, + "uploadFile": { + "title": "Subir archivo", + "selectFile": "Haz clic para seleccionar un archivo", + "preview": "Vista previa", + "uploadProgress": "Progreso de la subida", + "upload": "Subir", + "success": "Archivo subido exitosamente", + "error": "Error al subir el archivo" + }, "users": { "modes": { "create": "crear", @@ -608,29 +629,16 @@ "userr": "Usuario" } }, - "logo": { - "labels": { - "appLogo": "Logo de la aplicación" - }, - "buttons": { - "upload": "Subir logo", - "remove": "Eliminar logo" - }, - "messages": { - "uploadSuccess": "Logo subido exitosamente", - "removeSuccess": "Logo eliminado exitosamente" - }, - "errors": { - "uploadFailed": "Error al subir el logo", - "removeFailed": "Error al eliminar el logo" - } - }, - "navbar": { - "logoAlt": "Logo de la aplicación", - "profileMenu": "Menú de perfil", - "profile": "Perfil", - "settings": "Configuración", - "usersManagement": "Gestión de usuarios", - "logout": "Cerrar sesión" + "validation": { + "invalidEmail": "Dirección de correo electrónico no válida", + "passwordMinLength": "La contraseña debe tener al menos 6 caracteres", + "firstNameRequired": "Se requiere el nombre", + "lastNameRequired": "Se requiere el apellido", + "usernameLength": "El nombre de usuario debe tener al menos 3 caracteres", + "usernameSpaces": "El nombre de usuario no puede contener espacios", + "passwordLength": "La contraseña debe tener al menos 8 caracteres", + "passwordsMatch": "Las contraseñas no coinciden", + "emailRequired": "Se requiere el correo electrónico", + "passwordRequired": "Se requiere la contraseña" } -} \ No newline at end of file +} diff --git a/apps/web/src/locales/fr-FR.json b/apps/web/messages/fr-FR.json similarity index 97% rename from apps/web/src/locales/fr-FR.json rename to apps/web/messages/fr-FR.json index 95321af..329c81c 100644 --- a/apps/web/src/locales/fr-FR.json +++ b/apps/web/messages/fr-FR.json @@ -1,58 +1,4 @@ { - "login": { - "welcome": "Bienvenue", - "signInToContinue": "Connectez-vous pour continuer", - "emailLabel": "Adresse e-mail", - "emailPlaceholder": "Entrez votre e-mail", - "passwordLabel": "Mot de passe", - "passwordPlaceholder": "Entrez votre mot de passe", - "signIn": "Se connecter", - "signingIn": "Connexion en cours...", - "forgotPassword": "Mot de passe oublié ?", - "pageTitle": "Connexion" - }, - "errors": { - "invalidCredentials": "E-mail ou mot de passe invalide", - "userNotFound": "Utilisateur non trouvé", - "accountLocked": "Compte bloqué. Veuillez réessayer plus tard", - "unexpectedError": "Une erreur inattendue s'est produite. Veuillez réessayer" - }, - "validation": { - "invalidEmail": "Adresse email invalide", - "passwordMinLength": "Le mot de passe doit contenir au moins 6 caractères", - "firstNameRequired": "Le prénom est requis", - "lastNameRequired": "Le nom est requis", - "usernameLength": "Le nom d'utilisateur doit contenir au moins 3 caractères", - "usernameSpaces": "Le nom d'utilisateur ne peut pas contenir d'espaces", - "passwordLength": "Le mot de passe doit contenir au moins 8 caractères", - "passwordsMatch": "Les mots de passe ne correspondent pas" - }, - "fileSelector": { - "availableFiles": "Fichiers Disponibles ({{count}})", - "shareFiles": "Fichiers Partagés ({{count}})", - "searchPlaceholder": "Rechercher des fichiers...", - "noMatchingFiles": "Aucun fichier correspondant", - "noAvailableFiles": "Aucun fichier disponible", - "noFilesInShare": "Aucun fichier partagé", - "saveChanges": "Enregistrer les Modifications" - }, - "recipientSelector": { - "emailPlaceholder": "Entrez l'e-mail du destinataire", - "add": "Ajouter", - "recipients": "Destinataires ({{count}})", - "notifyAll": "Notifier Tous", - "noRecipients": "Aucun destinataire ajouté", - "addSuccess": "Destinataire ajouté avec succès", - "addError": "Échec de l'ajout du destinataire", - "removeSuccess": "Destinataire supprimé avec succès", - "removeError": "Échec de la suppression du destinataire", - "sendingNotifications": "Envoi des notifications...", - "notifySuccess": "Destinataires notifiés avec succès", - "notifyError": "Échec de la notification des destinataires" - }, - "navigation": { - "dashboard": "Tableau de bord" - }, "common": { "loading": "Chargement, veuillez patienter...", "cancel": "Annuler", @@ -78,6 +24,22 @@ "success": "Partage créé avec succès", "error": "Échec de la création du partage" }, + "dashboard": { + "loadError": "Échec du chargement des données du tableau de bord", + "linkCopied": "Lien copié dans le presse-papiers", + "pageTitle": "Tableau de Bord", + "breadcrumb": "Tableau de Bord" + }, + "emptyState": { + "noFiles": "Aucun fichier téléchargé pour le moment", + "uploadFile": "Envoyer un Fichier" + }, + "errors": { + "invalidCredentials": "E-mail ou mot de passe invalide", + "userNotFound": "Utilisateur non trouvé", + "accountLocked": "Compte bloqué. Veuillez réessayer plus tard", + "unexpectedError": "Une erreur inattendue s'est produite. Veuillez réessayer" + }, "fileActions": { "editFile": "Modifier le Fichier", "nameLabel": "Nom", @@ -86,9 +48,16 @@ "descriptionLabel": "Description", "descriptionPlaceholder": "Entrez la description du fichier", "deleteFile": "Supprimer le Fichier", - "deleteConfirmation": "Êtes-vous sûr de vouloir supprimer \"{{fileName}}\" ?", + "deleteConfirmation": "Êtes-vous sûr de vouloir supprimer ?", "deleteWarning": "Cette action ne peut pas être annulée." }, + "fileManager": { + "downloadError": "Échec du téléchargement du fichier", + "updateSuccess": "Fichier mis à jour avec succès", + "updateError": "Échec de la mise à jour du fichier", + "deleteSuccess": "Fichier supprimé avec succès", + "deleteError": "Échec de la suppression du fichier" + }, "filePreview": { "loading": "Chargement de l'aperçu...", "notAvailable": "Aperçu non disponible", @@ -98,68 +67,21 @@ "loadError": "Échec du chargement de l'aperçu", "downloadError": "Échec du téléchargement du fichier" }, - "generateShareLink": { - "generateTitle": "Générer un Lien de Partage", - "updateTitle": "Mettre à Jour le Lien de Partage", - "generateDescription": "Générez un lien pour partager vos fichiers", - "updateDescription": "Mettez à jour l'alias de ce lien de partage", - "aliasPlaceholder": "Entrez l'alias", - "linkReady": "Votre lien de partage est prêt :", - "generateButton": "Générer le Lien", - "updateButton": "Mettre à Jour le Lien", - "copyButton": "Copier le Lien", - "success": "Lien généré avec succès", - "error": "Échec de la génération du lien", - "copied": "Lien copié dans le presse-papiers" + "fileSelector": { + "availableFiles": "Fichiers Disponibles ({{count}})", + "shareFiles": "Fichiers Partagés ({{count}})", + "searchPlaceholder": "Rechercher des fichiers...", + "noMatchingFiles": "Aucun fichier correspondant", + "noAvailableFiles": "Aucun fichier disponible", + "noFilesInShare": "Aucun fichier partagé", + "saveChanges": "Enregistrer les Modifications" }, - "shareActions": { - "deleteTitle": "Supprimer le Partage", - "deleteConfirmation": "Êtes-vous sûr de vouloir supprimer ce partage ? Cette action ne peut pas être annulée.", - "editTitle": "Modifier le Partage", - "nameLabel": "Nom du Partage", - "expirationLabel": "Date d'Expiration", - "expirationPlaceholder": "JJ/MM/AAAA HH:MM", - "maxViewsLabel": "Vues Maximales", - "maxViewsPlaceholder": "Laisser vide pour illimité", - "passwordProtection": "Protégé par Mot de Passe", - "passwordLabel": "Mot de Passe", - "passwordPlaceholder": "Entrez le mot de passe", - "newPasswordLabel": "Nouveau Mot de Passe (laisser vide pour garder l'actuel)", - "newPasswordPlaceholder": "Entrez le nouveau mot de passe", - "manageFilesTitle": "Gérer les Fichiers", - "manageRecipientsTitle": "Gérer les Destinataires", - "editSuccess": "Partage mis à jour avec succès", - "editError": "Échec de la mise à jour du partage" - }, - "shareDetails": { - "title": "Détails du Partage", - "subtitle": "Informations détaillées sur ce partage", - "basicInfo": "Informations de Base", - "name": "Nom", - "untitled": "Partage sans titre", - "views": "Vues", - "dates": "Dates", - "created": "Créé le: {{date}}", - "expires": "Expire le: {{date}}", - "never": "Jamais", - "security": "Sécurité", - "passwordProtected": "Protégé par Mot de Passe", - "publicAccess": "Accès Public", - "maxViews": "Vues Maximales : {{count}}", - "files": "Fichiers ({{count}})", - "recipients": "Destinataires ({{count}})", - "notAvailable": "N/D", - "invalidDate": "Date invalide", - "loadError": "Échec du chargement des détails du partage" - }, - "uploadFile": { - "title": "Envoyer un Fichier", - "selectFile": "Cliquez pour sélectionner un fichier", - "preview": "Aperçu", - "uploadProgress": "Progression de l'envoi", - "upload": "Envoyer", - "success": "Fichier envoyé avec succès", - "error": "Échec de l'envoi du fichier" + "files": { + "title": "Tous les Fichiers", + "uploadFile": "Envoyer un Fichier", + "loadError": "Échec du chargement des fichiers", + "pageTitle": "Mes Fichiers", + "breadcrumb": "Mes Fichiers" }, "filesTable": { "ariaLabel": "Tableau des fichiers", @@ -179,119 +101,10 @@ "delete": "Supprimer" } }, - "sharesTable": { - "ariaLabel": "Tableau des partages", - "never": "Jamais", - "columns": { - "name": "NOM", - "createdAt": "CRÉÉ LE", - "expiresAt": "EXPIRE LE", - "status": "STATUT", - "security": "SÉCURITÉ", - "files": "FICHIERS", - "recipients": "DESTINATAIRES", - "actions": "ACTIONS" - }, - "status": { - "neverExpires": "N'expire Jamais", - "active": "Actif", - "expired": "Expiré" - }, - "security": { - "protected": "Protégé", - "public": "Public" - }, - "filesCount": "{{count}} fichiers", - "recipientsCount": "{{count}} destinataires", - "actions": { - "menu": "Menu d'actions du partage", - "edit": "Modifier", - "manageFiles": "Gérer les Fichiers", - "manageRecipients": "Gérer les Destinataires", - "viewDetails": "Voir les Détails", - "generateLink": "Générer un Lien", - "editLink": "Modifier le Lien", - "copyLink": "Copier le Lien", - "notifyRecipients": "Notifier les Destinataires", - "delete": "Supprimer" - } - }, "footer": { "poweredBy": "Propulsé par", "kyanHomepage": "Page d'accueil de Kyantech" }, - "fileManager": { - "downloadError": "Échec du téléchargement du fichier", - "updateSuccess": "Fichier mis à jour avec succès", - "updateError": "Échec de la mise à jour du fichier", - "deleteSuccess": "Fichier supprimé avec succès", - "deleteError": "Échec de la suppression du fichier" - }, - "shareManager": { - "deleteSuccess": "Partage supprimé avec succès", - "deleteError": "Échec de la suppression du partage", - "updateSuccess": "Partage mis à jour avec succès", - "updateError": "Échec de la mise à jour du partage", - "filesUpdateSuccess": "Fichiers mis à jour avec succès", - "filesUpdateError": "Échec de la mise à jour des fichiers", - "recipientsUpdateSuccess": "Destinataires mis à jour avec succès", - "recipientsUpdateError": "Échec de la mise à jour des destinataires", - "linkGenerateSuccess": "Lien de partage généré avec succès", - "linkGenerateError": "Échec de la génération du lien de partage", - "notifyLoading": "Envoi des notifications...", - "notifySuccess": "Destinataires notifiés avec succès", - "notifyError": "Échec de la notification des destinataires" - }, - "quickAccess": { - "files": { - "title": "Mes Fichiers", - "description": "Accédez et gérez vos fichiers téléchargés" - }, - "shares": { - "title": "Mes Partages", - "description": "Visualisez et gérez vos fichiers partagés" - } - }, - "recentFiles": { - "title": "Téléchargements Récents", - "viewAll": "Voir Tout", - "uploadFile": "Envoyer un Fichier", - "noFiles": "Aucun fichier téléchargé pour le moment" - }, - "recentShares": { - "title": "Partages Récents", - "viewAll": "Voir Tout", - "createShare": "Créer un Partage", - "noShares": "Aucun partage créé pour le moment", - "createFirst": "Créer votre premier partage" - }, - "storageUsage": { - "title": "Utilisation du Stockage", - "ariaLabel": "Barre de progression de l'utilisation du stockage", - "used": "{{size}} utilisé", - "available": "{{size}} disponible" - }, - "dashboard": { - "loadError": "Échec du chargement des données du tableau de bord", - "linkCopied": "Lien copié dans le presse-papiers", - "pageTitle": "Tableau de Bord", - "breadcrumb": "Tableau de Bord" - }, - "emptyState": { - "noFiles": "Aucun fichier téléchargé pour le moment", - "uploadFile": "Envoyer un Fichier" - }, - "files": { - "title": "Tous les Fichiers", - "uploadFile": "Envoyer un Fichier", - "loadError": "Échec du chargement des fichiers", - "pageTitle": "Mes Fichiers", - "breadcrumb": "Mes Fichiers" - }, - "searchBar": { - "placeholder": "Rechercher des fichiers...", - "results": "Trouvé {{filtered}} sur {{total}} fichiers" - }, "forgotPassword": { "emailLabel": "Adresse Email", "emailPlaceholder": "Entrez votre email", @@ -303,6 +116,20 @@ "resetInstructions": "Instructions de réinitialisation envoyées à votre email", "pageTitle": "Mot de Passe Oublié" }, + "generateShareLink": { + "generateTitle": "Générer un Lien de Partage", + "updateTitle": "Mettre à Jour le Lien de Partage", + "generateDescription": "Générez un lien pour partager vos fichiers", + "updateDescription": "Mettez à jour l'alias de ce lien de partage", + "aliasPlaceholder": "Entrez l'alias", + "linkReady": "Votre lien de partage est prêt :", + "generateButton": "Générer le Lien", + "updateButton": "Mettre à Jour le Lien", + "copyButton": "Copier le Lien", + "success": "Lien généré avec succès", + "error": "Échec de la génération du lien", + "copied": "Lien copié dans le presse-papiers" + }, "home": { "description": "L'alternative open-source à WeTransfer. Partagez des fichiers en toute sécurité, sans suivi ni limitations.", "documentation": "Documentation", @@ -314,6 +141,46 @@ }, "pageTitle": "Accueil" }, + "login": { + "welcome": "Bienvenue à", + "signInToContinue": "Connectez-vous pour continuer", + "emailLabel": "Adresse e-mail", + "emailPlaceholder": "Entrez votre e-mail", + "passwordLabel": "Mot de passe", + "passwordPlaceholder": "Entrez votre mot de passe", + "signIn": "Se connecter", + "signingIn": "Connexion en cours...", + "forgotPassword": "Mot de passe oublié ?", + "pageTitle": "Connexion" + }, + "logo": { + "labels": { + "appLogo": "Logo de l'application" + }, + "buttons": { + "upload": "Télécharger le logo", + "remove": "Supprimer le logo" + }, + "messages": { + "uploadSuccess": "Logo téléchargé avec succès", + "removeSuccess": "Logo supprimé avec succès" + }, + "errors": { + "uploadFailed": "Échec du téléchargement du logo", + "removeFailed": "Échec de la suppression du logo" + } + }, + "navbar": { + "logoAlt": "Logo de l'Application", + "profileMenu": "Menu du Profil", + "profile": "Profil", + "settings": "Paramètres", + "usersManagement": "Gestion des Utilisateurs", + "logout": "Déconnexion" + }, + "navigation": { + "dashboard": "Tableau de bord" + }, "profile": { "password": { "title": "Changer le Mot de Passe", @@ -356,6 +223,43 @@ }, "pageTitle": "Profil" }, + "quickAccess": { + "files": { + "title": "Mes Fichiers", + "description": "Accédez et gérez vos fichiers téléchargés" + }, + "shares": { + "title": "Mes Partages", + "description": "Visualisez et gérez vos fichiers partagés" + } + }, + "recentFiles": { + "title": "Téléchargements Récents", + "viewAll": "Voir Tout", + "uploadFile": "Envoyer un Fichier", + "noFiles": "Aucun fichier téléchargé pour le moment" + }, + "recentShares": { + "title": "Partages Récents", + "viewAll": "Voir Tout", + "createShare": "Créer un Partage", + "noShares": "Aucun partage créé pour le moment", + "createFirst": "Créer votre premier partage" + }, + "recipientSelector": { + "emailPlaceholder": "Entrez l'e-mail du destinataire", + "add": "Ajouter", + "recipients": "Destinataires ({{count}})", + "notifyAll": "Notifier Tous", + "noRecipients": "Aucun destinataire ajouté", + "addSuccess": "Destinataire ajouté avec succès", + "addError": "Échec de l'ajout du destinataire", + "removeSuccess": "Destinataire supprimé avec succès", + "removeError": "Échec de la suppression du destinataire", + "sendingNotifications": "Envoi des notifications...", + "notifySuccess": "Destinataires notifiés avec succès", + "notifyError": "Échec de la notification des destinataires" + }, "resetPassword": { "pageTitle": "Réinitialiser le Mot de Passe", "header": { @@ -379,6 +283,10 @@ "invalidToken": "Jeton de réinitialisation invalide ou manquant" } }, + "searchBar": { + "placeholder": "Rechercher des fichiers...", + "results": "Trouvé {{filtered}} sur {{total}} fichiers" + }, "settings": { "title": "Paramètres", "breadcrumb": "Paramètres", @@ -512,6 +420,61 @@ }, "pageTitle": "Partage" }, + "shareActions": { + "deleteTitle": "Supprimer le Partage", + "deleteConfirmation": "Êtes-vous sûr de vouloir supprimer ce partage ? Cette action ne peut pas être annulée.", + "editTitle": "Modifier le Partage", + "nameLabel": "Nom du Partage", + "expirationLabel": "Date d'Expiration", + "expirationPlaceholder": "JJ/MM/AAAA HH:MM", + "maxViewsLabel": "Vues Maximales", + "maxViewsPlaceholder": "Laisser vide pour illimité", + "passwordProtection": "Protégé par Mot de Passe", + "passwordLabel": "Mot de Passe", + "passwordPlaceholder": "Entrez le mot de passe", + "newPasswordLabel": "Nouveau Mot de Passe (laisser vide pour garder l'actuel)", + "newPasswordPlaceholder": "Entrez le nouveau mot de passe", + "manageFilesTitle": "Gérer les Fichiers", + "manageRecipientsTitle": "Gérer les Destinataires", + "editSuccess": "Partage mis à jour avec succès", + "editError": "Échec de la mise à jour du partage" + }, + "shareDetails": { + "title": "Détails du Partage", + "subtitle": "Informations détaillées sur ce partage", + "basicInfo": "Informations de Base", + "name": "Nom", + "untitled": "Partage sans titre", + "views": "Vues", + "dates": "Dates", + "created": "Créé le: {{date}}", + "expires": "Expire le: {{date}}", + "never": "Jamais", + "security": "Sécurité", + "passwordProtected": "Protégé par Mot de Passe", + "publicAccess": "Accès Public", + "maxViews": "Vues Maximales:", + "files": "Fichiers", + "recipients": "Destinataires", + "notAvailable": "N/D", + "invalidDate": "Date invalide", + "loadError": "Échec du chargement des détails du partage" + }, + "shareManager": { + "deleteSuccess": "Partage supprimé avec succès", + "deleteError": "Échec de la suppression du partage", + "updateSuccess": "Partage mis à jour avec succès", + "updateError": "Échec de la mise à jour du partage", + "filesUpdateSuccess": "Fichiers mis à jour avec succès", + "filesUpdateError": "Échec de la mise à jour des fichiers", + "recipientsUpdateSuccess": "Destinataires mis à jour avec succès", + "recipientsUpdateError": "Échec de la mise à jour des destinataires", + "linkGenerateSuccess": "Lien de partage généré avec succès", + "linkGenerateError": "Échec de la génération du lien de partage", + "notifyLoading": "Envoi des notifications...", + "notifySuccess": "Destinataires notifiés avec succès", + "notifyError": "Échec de la notification des destinataires" + }, "shares": { "errors": { "loadFailed": "Échec du chargement des partages", @@ -538,6 +501,64 @@ }, "pageTitle": "Partages" }, + "sharesTable": { + "ariaLabel": "Tableau des partages", + "never": "Jamais", + "columns": { + "name": "NOM", + "createdAt": "CRÉÉ LE", + "expiresAt": "EXPIRE LE", + "status": "STATUT", + "security": "SÉCURITÉ", + "files": "FICHIERS", + "recipients": "DESTINATAIRES", + "actions": "ACTIONS" + }, + "status": { + "neverExpires": "N'expire Jamais", + "active": "Actif", + "expired": "Expiré" + }, + "security": { + "protected": "Protégé", + "public": "Public" + }, + "filesCount": "fichiers", + "recipientsCount": "destinataires", + "actions": { + "menu": "Menu d'actions du partage", + "edit": "Modifier", + "manageFiles": "Gérer les Fichiers", + "manageRecipients": "Gérer les Destinataires", + "viewDetails": "Voir les Détails", + "generateLink": "Générer un Lien", + "editLink": "Modifier le Lien", + "copyLink": "Copier le Lien", + "notifyRecipients": "Notifier les Destinataires", + "delete": "Supprimer" + } + }, + "storageUsage": { + "title": "Utilisation du Stockage", + "ariaLabel": "Barre de progression de l'utilisation du stockage", + "used": "utilisé", + "available": "disponible" + }, + "theme": { + "toggle": "Changer le thème", + "light": "Clair", + "dark": "Sombre", + "system": "Système" + }, + "uploadFile": { + "title": "Envoyer un Fichier", + "selectFile": "Cliquez pour sélectionner un fichier", + "preview": "Aperçu", + "uploadProgress": "Progression de l'envoi", + "upload": "Envoyer", + "success": "Fichier envoyé avec succès", + "error": "Échec de l'envoi du fichier" + }, "users": { "modes": { "create": "créer", @@ -607,29 +628,16 @@ "userr": "Utilisateur" } }, - "logo": { - "labels": { - "appLogo": "Logo de l'application" - }, - "buttons": { - "upload": "Télécharger le logo", - "remove": "Supprimer le logo" - }, - "messages": { - "uploadSuccess": "Logo téléchargé avec succès", - "removeSuccess": "Logo supprimé avec succès" - }, - "errors": { - "uploadFailed": "Échec du téléchargement du logo", - "removeFailed": "Échec de la suppression du logo" - } - }, - "navbar": { - "logoAlt": "Logo de l'Application", - "profileMenu": "Menu du Profil", - "profile": "Profil", - "settings": "Paramètres", - "usersManagement": "Gestion des Utilisateurs", - "logout": "Déconnexion" + "validation": { + "invalidEmail": "Adresse email invalide", + "passwordMinLength": "Le mot de passe doit contenir au moins 6 caractères", + "firstNameRequired": "Le prénom est requis", + "lastNameRequired": "Le nom est requis", + "usernameLength": "Le nom d'utilisateur doit contenir au moins 3 caractères", + "usernameSpaces": "Le nom d'utilisateur ne peut pas contenir d'espaces", + "passwordLength": "Le mot de passe doit contenir au moins 8 caractères", + "passwordsMatch": "Les mots de passe ne correspondent pas", + "emailRequired": "L'email est requis", + "passwordRequired": "Le mot de passe est requis" } -} \ No newline at end of file +} diff --git a/apps/web/src/locales/hi-IN.json b/apps/web/messages/hi-IN.json similarity index 97% rename from apps/web/src/locales/hi-IN.json rename to apps/web/messages/hi-IN.json index 00a85d0..d601c52 100644 --- a/apps/web/src/locales/hi-IN.json +++ b/apps/web/messages/hi-IN.json @@ -1,58 +1,4 @@ { - "login": { - "welcome": "स्वागत है", - "signInToContinue": "जारी रखने के लिए साइन इन करें", - "emailLabel": "ईमेल पता", - "emailPlaceholder": "अपना ईमेल दर्ज करें", - "passwordLabel": "पासवर्ड", - "passwordPlaceholder": "अपना पासवर्ड दर्ज करें", - "signIn": "साइन इन करें", - "signingIn": "साइन इन हो रहा है...", - "forgotPassword": "पासवर्ड भूल गए?", - "pageTitle": "लॉगिन" - }, - "errors": { - "invalidCredentials": "गलत ईमेल या पासवर्ड", - "userNotFound": "उपयोगकर्ता नहीं मिला", - "accountLocked": "खाता लॉक है। कृपया बाद में प्रयास करें", - "unexpectedError": "एक अप्रत्याशित त्रुटि हुई। कृपया पुनः प्रयास करें" - }, - "validation": { - "invalidEmail": "अमान्य ईमेल पता", - "passwordMinLength": "पासवर्ड कम से कम 6 अक्षर का होना चाहिए", - "firstNameRequired": "पहला नाम आवश्यक है", - "lastNameRequired": "अंतिम नाम आवश्यक है", - "usernameLength": "उपयोगकर्ता नाम कम से कम 3 अक्षर का होना चाहिए", - "usernameSpaces": "उपयोगकर्ता नाम में रिक्त स्थान नहीं हो सकते", - "passwordLength": "पासवर्ड कम से कम 8 अक्षर का होना चाहिए", - "passwordsMatch": "पासवर्ड मेल नहीं खाते" - }, - "fileSelector": { - "availableFiles": "उपलब्ध फाइलें ({{count}})", - "shareFiles": "फाइलें साझा करें ({{count}})", - "searchPlaceholder": "फाइलें खोजें...", - "noMatchingFiles": "कोई मेल खाने वाली फाइलें नहीं", - "noAvailableFiles": "कोई फाइल उपलब्ध नहीं", - "noFilesInShare": "साझाकरण में कोई फाइलें नहीं", - "saveChanges": "परिवर्तन सहेजें" - }, - "recipientSelector": { - "emailPlaceholder": "प्राप्तकर्ता का ईमेल दर्ज करें", - "add": "जोड़ें", - "recipients": "प्राप्तकर्ता ({{count}})", - "notifyAll": "सभी को सूचित करें", - "noRecipients": "अभी तक कोई प्राप्तकर्ता नहीं जोड़ा गया", - "addSuccess": "प्राप्तकर्ता सफलतापूर्वक जोड़ा गया", - "addError": "प्राप्तकर्ता जोड़ने में विफल", - "removeSuccess": "प्राप्तकर्ता सफलतापूर्वक हटाया गया", - "removeError": "प्राप्तकर्ता हटाने में विफल", - "sendingNotifications": "सूचनाएँ भेजी जा रही हैं...", - "notifySuccess": "प्राप्तकर्ताओं को सफलतापूर्वक सूचित किया गया", - "notifyError": "प्राप्तकर्ताओं को सूचित करने में विफल" - }, - "navigation": { - "dashboard": "डैशबोर्ड" - }, "common": { "loading": "लोड हो रहा है, कृपया प्रतीक्षा करें...", "cancel": "रद्द करें", @@ -78,6 +24,22 @@ "success": "साझाकरण सफलतापूर्वक बनाया गया", "error": "साझाकरण बनाने में विफल" }, + "dashboard": { + "loadError": "डैशबोर्ड डेटा लोड करने में त्रुटि", + "linkCopied": "लिंक क्लिपबोर्ड में कॉपी हुआ", + "pageTitle": "डैशबोर्ड", + "breadcrumb": "डैशबोर्ड" + }, + "emptyState": { + "noFiles": "अभी तक कोई फाइल अपलोड नहीं हुई", + "uploadFile": "फाइल अपलोड करें" + }, + "errors": { + "invalidCredentials": "गलत ईमेल या पासवर्ड", + "userNotFound": "उपयोगकर्ता नहीं मिला", + "accountLocked": "खाता लॉक है। कृपया बाद में प्रयास करें", + "unexpectedError": "एक अप्रत्याशित त्रुटि हुई। कृपया पुनः प्रयास करें" + }, "fileActions": { "editFile": "फाइल संपादित करें", "nameLabel": "नाम", @@ -86,9 +48,16 @@ "descriptionLabel": "विवरण", "descriptionPlaceholder": "फाइल का विवरण दर्ज करें", "deleteFile": "फाइल हटाएं", - "deleteConfirmation": "क्या आप वाकई \"{{fileName}}\" हटाना चाहते हैं?", + "deleteConfirmation": "क्या आप वाकई हटाना चाहते हैं?", "deleteWarning": "यह क्रिया अपरिवर्तनीय है।" }, + "fileManager": { + "downloadError": "फाइल डाउनलोड करने में त्रुटि", + "updateSuccess": "फाइल सफलतापूर्वक अपडेट हुई", + "updateError": "फाइल अपडेट करने में त्रुटि", + "deleteSuccess": "फाइल सफलतापूर्वक हटाई गई", + "deleteError": "फाइल हटाने में त्रुटि" + }, "filePreview": { "loading": "पूर्वावलोकन लोड हो रहा है...", "notAvailable": "पूर्वावलोकन उपलब्ध नहीं", @@ -98,68 +67,21 @@ "loadError": "पूर्वावलोकन लोड करने में विफल", "downloadError": "फाइल डाउनलोड करने में विफल" }, - "generateShareLink": { - "generateTitle": "साझाकरण लिंक उत्पन्न करें", - "updateTitle": "साझाकरण लिंक अपडेट करें", - "generateDescription": "अपनी फाइलें साझा करने के लिए एक लिंक उत्पन्न करें", - "updateDescription": "इस साझाकरण लिंक के लिए उपनाम अपडेट करें", - "aliasPlaceholder": "उपनाम दर्ज करें", - "linkReady": "आपका साझाकरण लिंक तैयार है:", - "generateButton": "लिंक उत्पन्न करें", - "updateButton": "लिंक अपडेट करें", - "copyButton": "लिंक कॉपी करें", - "success": "लिंक सफलतापूर्वक उत्पन्न हुआ", - "error": "लिंक उत्पन्न करने में विफल", - "copied": "लिंक क्लिपबोर्ड में कॉपी किया गया" + "fileSelector": { + "availableFiles": "उपलब्ध फाइलें ({{count}})", + "shareFiles": "फाइलें साझा करें ({{count}})", + "searchPlaceholder": "फाइलें खोजें...", + "noMatchingFiles": "कोई मेल खाने वाली फाइलें नहीं", + "noAvailableFiles": "कोई फाइल उपलब्ध नहीं", + "noFilesInShare": "साझाकरण में कोई फाइलें नहीं", + "saveChanges": "परिवर्तन सहेजें" }, - "shareActions": { - "deleteTitle": "साझाकरण हटाएं", - "deleteConfirmation": "क्या आप वाकई इस साझाकरण को हटाना चाहते हैं? यह क्रिया अपरिवर्तनीय है।", - "editTitle": "साझाकरण संपादित करें", - "nameLabel": "साझाकरण का नाम", - "expirationLabel": "समाप्ति तिथि", - "expirationPlaceholder": "MM/DD/YYYY HH:MM", - "maxViewsLabel": "अधिकतम दृश्य", - "maxViewsPlaceholder": "अनलिमिटेड के लिए खाली छोड़ें", - "passwordProtection": "पासवर्ड सुरक्षा", - "passwordLabel": "पासवर्ड", - "passwordPlaceholder": "पासवर्ड दर्ज करें", - "newPasswordLabel": "नया पासवर्ड (वर्तमान रखने के लिए खाली छोड़ें)", - "newPasswordPlaceholder": "नया पासवर्ड दर्ज करें", - "manageFilesTitle": "फाइलें प्रबंधित करें", - "manageRecipientsTitle": "प्राप्तकर्ताओं का प्रबंधन करें", - "editSuccess": "साझाकरण सफलतापूर्वक अपडेट हुआ", - "editError": "साझाकरण अपडेट करने में विफल" - }, - "shareDetails": { - "title": "साझाकरण विवरण", - "subtitle": "इस साझाकरण की विस्तृत जानकारी", - "basicInfo": "मूल जानकारी", - "name": "नाम", - "untitled": "बिना शीर्षक के", - "views": "दृश्य", - "dates": "तिथियाँ", - "created": "बनाया गया", - "expires": "समाप्त होता है", - "never": "कभी नहीं", - "security": "सुरक्षा", - "passwordProtected": "पासवर्ड द्वारा संरक्षित", - "publicAccess": "सार्वजनिक पहुँच", - "maxViews": "अधिकतम दृश्य: {{count}}", - "files": "फाइलें ({{count}})", - "recipients": "प्राप्तकर्ता ({{count}})", - "notAvailable": "एन/ए", - "invalidDate": "अमान्य तिथि", - "loadError": "साझाकरण विवरण लोड करने में विफल" - }, - "uploadFile": { - "title": "फाइल अपलोड करें", - "selectFile": "फाइल चुनने के लिए क्लिक करें", - "preview": "पूर्वावलोकन", - "uploadProgress": "अपलोड प्रगति", - "upload": "अपलोड करें", - "success": "फाइल सफलतापूर्वक अपलोड हुई", - "error": "फाइल अपलोड करने में विफल" + "files": { + "title": "सभी फाइलें", + "uploadFile": "फाइल अपलोड करें", + "loadError": "फाइलें लोड करने में त्रुटि", + "pageTitle": "मेरी फाइलें", + "breadcrumb": "मेरी फाइलें" }, "filesTable": { "ariaLabel": "फाइल टेबल", @@ -179,119 +101,10 @@ "delete": "हटाएं" } }, - "sharesTable": { - "ariaLabel": "साझाकरण टेबल", - "never": "कभी नहीं", - "columns": { - "name": "नाम", - "createdAt": "बनाया गया", - "expiresAt": "समाप्त होता है", - "status": "स्थिति", - "security": "सुरक्षा", - "files": "फाइलें", - "recipients": "प्राप्तकर्ता", - "actions": "क्रियाएं" - }, - "status": { - "neverExpires": "कभी समाप्त नहीं", - "active": "सक्रिय", - "expired": "समाप्त" - }, - "security": { - "protected": "संरक्षित", - "public": "सार्वजनिक" - }, - "filesCount": "{{count}} फाइलें", - "recipientsCount": "{{count}} प्राप्तकर्ता", - "actions": { - "menu": "साझाकरण क्रिया मेनू", - "edit": "संपादित करें", - "manageFiles": "फाइलें प्रबंधित करें", - "manageRecipients": "प्राप्तकर्ताओं का प्रबंधन करें", - "viewDetails": "विवरण देखें", - "generateLink": "लिंक उत्पन्न करें", - "editLink": "लिंक संपादित करें", - "copyLink": "लिंक कॉपी करें", - "notifyRecipients": "प्राप्तकर्ताओं को सूचित करें", - "delete": "हटाएं" - } - }, "footer": { "poweredBy": "द्वारा संचालित", "kyanHomepage": "Kyantech होमपेज" }, - "fileManager": { - "downloadError": "फाइल डाउनलोड करने में त्रुटि", - "updateSuccess": "फाइल सफलतापूर्वक अपडेट हुई", - "updateError": "फाइल अपडेट करने में त्रुटि", - "deleteSuccess": "फाइल सफलतापूर्वक हटाई गई", - "deleteError": "फाइल हटाने में त्रुटि" - }, - "shareManager": { - "deleteSuccess": "साझाकरण सफलतापूर्वक हटाया गया", - "deleteError": "साझाकरण हटाने में त्रुटि", - "updateSuccess": "साझाकरण सफलतापूर्वक अपडेट हुआ", - "updateError": "साझाकरण अपडेट करने में त्रुटि", - "filesUpdateSuccess": "फाइलें सफलतापूर्वक अपडेट हुईं", - "filesUpdateError": "फाइलें अपडेट करने में त्रुटि", - "recipientsUpdateSuccess": "प्राप्तकर्ता सफलतापूर्वक अपडेट हुए", - "recipientsUpdateError": "प्राप्तकर्ता अपडेट करने में त्रुटि", - "linkGenerateSuccess": "साझाकरण लिंक सफलतापूर्वक उत्पन्न हुआ", - "linkGenerateError": "साझाकरण लिंक उत्पन्न करने में त्रुटि", - "notifyLoading": "सूचनाएँ भेजी जा रही हैं...", - "notifySuccess": "प्राप्तकर्ताओं को सफलतापूर्वक सूचित किया गया", - "notifyError": "प्राप्तकर्ताओं को सूचित करने में त्रुटि" - }, - "quickAccess": { - "files": { - "title": "मेरी फाइलें", - "description": "अपलोड की गई फाइलों तक पहुंच और प्रबंधन" - }, - "shares": { - "title": "मेरे साझाकरण", - "description": "साझा की गई फाइलों को देखें और प्रबंधित करें" - } - }, - "recentFiles": { - "title": "हाल की अपलोड्स", - "viewAll": "सभी देखें", - "uploadFile": "फाइल अपलोड करें", - "noFiles": "अभी तक कोई फाइल अपलोड नहीं हुई" - }, - "recentShares": { - "title": "हाल के साझाकरण", - "viewAll": "सभी देखें", - "createShare": "साझा करें बनाएं", - "noShares": "अभी तक कोई साझाकरण नहीं बनाया गया", - "createFirst": "अपना पहला साझाकरण बनाएं" - }, - "storageUsage": { - "title": "स्टोरेज उपयोग", - "ariaLabel": "स्टोरेज उपयोग प्रगति पट्टी", - "used": "{{size}} उपयोग किया गया", - "available": "{{size}} उपलब्ध" - }, - "dashboard": { - "loadError": "डैशबोर्ड डेटा लोड करने में त्रुटि", - "linkCopied": "लिंक क्लिपबोर्ड में कॉपी हुआ", - "pageTitle": "डैशबोर्ड", - "breadcrumb": "डैशबोर्ड" - }, - "emptyState": { - "noFiles": "अभी तक कोई फाइल अपलोड नहीं हुई", - "uploadFile": "फाइल अपलोड करें" - }, - "files": { - "title": "सभी फाइलें", - "uploadFile": "फाइल अपलोड करें", - "loadError": "फाइलें लोड करने में त्रुटि", - "pageTitle": "मेरी फाइलें", - "breadcrumb": "मेरी फाइलें" - }, - "searchBar": { - "placeholder": "फाइलें खोजें...", - "results": "{{total}} में से {{filtered}} फाइलें मिलीं" - }, "forgotPassword": { "emailLabel": "ईमेल पता", "emailPlaceholder": "अपना ईमेल दर्ज करें", @@ -303,6 +116,20 @@ "resetInstructions": "रीसेट निर्देश आपके ईमेल पर भेज दिए गए हैं", "pageTitle": "पासवर्ड भूल गए" }, + "generateShareLink": { + "generateTitle": "साझाकरण लिंक उत्पन्न करें", + "updateTitle": "साझाकरण लिंक अपडेट करें", + "generateDescription": "अपनी फाइलें साझा करने के लिए एक लिंक उत्पन्न करें", + "updateDescription": "इस साझाकरण लिंक के लिए उपनाम अपडेट करें", + "aliasPlaceholder": "उपनाम दर्ज करें", + "linkReady": "आपका साझाकरण लिंक तैयार है:", + "generateButton": "लिंक उत्पन्न करें", + "updateButton": "लिंक अपडेट करें", + "copyButton": "लिंक कॉपी करें", + "success": "लिंक सफलतापूर्वक उत्पन्न हुआ", + "error": "लिंक उत्पन्न करने में विफल", + "copied": "लिंक क्लिपबोर्ड में कॉपी किया गया" + }, "home": { "description": "WeTransfer का ओपन-सोर्स विकल्प। फाइलें सुरक्षित रूप से साझा करें, बिना ट्रैकिंग या सीमाओं के।", "documentation": "दस्तावेज", @@ -314,6 +141,46 @@ }, "pageTitle": "होम" }, + "login": { + "welcome": "स्वागत है में", + "signInToContinue": "जारी रखने के लिए साइन इन करें", + "emailLabel": "ईमेल पता", + "emailPlaceholder": "अपना ईमेल दर्ज करें", + "passwordLabel": "पासवर्ड", + "passwordPlaceholder": "अपना पासवर्ड दर्ज करें", + "signIn": "साइन इन करें", + "signingIn": "साइन इन हो रहा है...", + "forgotPassword": "पासवर्ड भूल गए?", + "pageTitle": "लॉगिन" + }, + "logo": { + "labels": { + "appLogo": "एप्लिकेशन लोगो" + }, + "buttons": { + "upload": "लोगो अपलोड करें", + "remove": "लोगो हटाएं" + }, + "messages": { + "uploadSuccess": "लोगो सफलतापूर्वक अपलोड हुआ", + "removeSuccess": "लोगो सफलतापूर्वक हटाया गया" + }, + "errors": { + "uploadFailed": "लोगो अपलोड करने में विफल", + "removeFailed": "लोगो हटाने में विफल" + } + }, + "navbar": { + "logoAlt": "एप्लिकेशन लोगो", + "profileMenu": "प्रोफ़ाइल मेन्यू", + "profile": "प्रोफ़ाइल", + "settings": "सेटिंग्स", + "usersManagement": "उपयोगकर्ता प्रबंधन", + "logout": "लॉग आउट" + }, + "navigation": { + "dashboard": "डैशबोर्ड" + }, "profile": { "password": { "title": "पासवर्ड बदलें", @@ -356,6 +223,43 @@ }, "pageTitle": "प्रोफ़ाइल" }, + "quickAccess": { + "files": { + "title": "मेरी फाइलें", + "description": "अपलोड की गई फाइलों तक पहुंच और प्रबंधन" + }, + "shares": { + "title": "मेरे साझाकरण", + "description": "साझा की गई फाइलों को देखें और प्रबंधित करें" + } + }, + "recentFiles": { + "title": "हाल की अपलोड्स", + "viewAll": "सभी देखें", + "uploadFile": "फाइल अपलोड करें", + "noFiles": "अभी तक कोई फाइल अपलोड नहीं हुई" + }, + "recentShares": { + "title": "हाल के साझाकरण", + "viewAll": "सभी देखें", + "createShare": "साझा करें बनाएं", + "noShares": "अभी तक कोई साझाकरण नहीं बनाया गया", + "createFirst": "अपना पहला साझाकरण बनाएं" + }, + "recipientSelector": { + "emailPlaceholder": "प्राप्तकर्ता का ईमेल दर्ज करें", + "add": "जोड़ें", + "recipients": "प्राप्तकर्ता ({{count}})", + "notifyAll": "सभी को सूचित करें", + "noRecipients": "अभी तक कोई प्राप्तकर्ता नहीं जोड़ा गया", + "addSuccess": "प्राप्तकर्ता सफलतापूर्वक जोड़ा गया", + "addError": "प्राप्तकर्ता जोड़ने में विफल", + "removeSuccess": "प्राप्तकर्ता सफलतापूर्वक हटाया गया", + "removeError": "प्राप्तकर्ता हटाने में विफल", + "sendingNotifications": "सूचनाएँ भेजी जा रही हैं...", + "notifySuccess": "प्राप्तकर्ताओं को सफलतापूर्वक सूचित किया गया", + "notifyError": "प्राप्तकर्ताओं को सूचित करने में विफल" + }, "resetPassword": { "pageTitle": "पासवर्ड रीसेट करें", "header": { @@ -379,6 +283,10 @@ "invalidToken": "अमान्य या गायब रीसेट टोकन" } }, + "searchBar": { + "placeholder": "फाइलें खोजें...", + "results": "{{total}} में से {{filtered}} फाइलें मिलीं" + }, "settings": { "groups": { "defaultDescription": "कॉन्फ़िगरेशन विकल्प", @@ -513,6 +421,61 @@ }, "pageTitle": "साझाकरण" }, + "shareActions": { + "deleteTitle": "साझाकरण हटाएं", + "deleteConfirmation": "क्या आप वाकई इस साझाकरण को हटाना चाहते हैं? यह क्रिया अपरिवर्तनीय है।", + "editTitle": "साझाकरण संपादित करें", + "nameLabel": "साझाकरण का नाम", + "expirationLabel": "समाप्ति तिथि", + "expirationPlaceholder": "MM/DD/YYYY HH:MM", + "maxViewsLabel": "अधिकतम दृश्य", + "maxViewsPlaceholder": "अनलिमिटेड के लिए खाली छोड़ें", + "passwordProtection": "पासवर्ड सुरक्षा", + "passwordLabel": "पासवर्ड", + "passwordPlaceholder": "पासवर्ड दर्ज करें", + "newPasswordLabel": "नया पासवर्ड (वर्तमान रखने के लिए खाली छोड़ें)", + "newPasswordPlaceholder": "नया पासवर्ड दर्ज करें", + "manageFilesTitle": "फाइलें प्रबंधित करें", + "manageRecipientsTitle": "प्राप्तकर्ताओं का प्रबंधन करें", + "editSuccess": "साझाकरण सफलतापूर्वक अपडेट हुआ", + "editError": "साझाकरण अपडेट करने में विफल" + }, + "shareDetails": { + "title": "साझाकरण विवरण", + "subtitle": "इस साझाकरण की विस्तृत जानकारी", + "basicInfo": "मूल जानकारी", + "name": "नाम", + "untitled": "बिना शीर्षक के", + "views": "दृश्य", + "dates": "तिथियाँ", + "created": "बनाया गया", + "expires": "समाप्त होता है", + "never": "कभी नहीं", + "security": "सुरक्षा", + "passwordProtected": "पासवर्ड द्वारा संरक्षित", + "publicAccess": "सार्वजनिक पहुँच", + "maxViews": "अधिकतम दृश्य:", + "files": "फाइलें", + "recipients": "प्राप्तकर्ता", + "notAvailable": "एन/ए", + "invalidDate": "अमान्य तिथि", + "loadError": "साझाकरण विवरण लोड करने में विफल" + }, + "shareManager": { + "deleteSuccess": "साझाकरण सफलतापूर्वक हटाया गया", + "deleteError": "साझाकरण हटाने में त्रुटि", + "updateSuccess": "साझाकरण सफलतापूर्वक अपडेट हुआ", + "updateError": "साझाकरण अपडेट करने में त्रुटि", + "filesUpdateSuccess": "फाइलें सफलतापूर्वक अपडेट हुईं", + "filesUpdateError": "फाइलें अपडेट करने में त्रुटि", + "recipientsUpdateSuccess": "प्राप्तकर्ता सफलतापूर्वक अपडेट हुए", + "recipientsUpdateError": "प्राप्तकर्ता अपडेट करने में त्रुटि", + "linkGenerateSuccess": "साझाकरण लिंक सफलतापूर्वक उत्पन्न हुआ", + "linkGenerateError": "साझाकरण लिंक उत्पन्न करने में त्रुटि", + "notifyLoading": "सूचनाएँ भेजी जा रही हैं...", + "notifySuccess": "प्राप्तकर्ताओं को सफलतापूर्वक सूचित किया गया", + "notifyError": "प्राप्तकर्ताओं को सूचित करने में त्रुटि" + }, "shares": { "errors": { "loadFailed": "साझाकरण लोड करने में विफल", @@ -539,6 +502,64 @@ }, "pageTitle": "साझाकरण" }, + "sharesTable": { + "ariaLabel": "साझाकरण टेबल", + "never": "कभी नहीं", + "columns": { + "name": "नाम", + "createdAt": "बनाया गया", + "expiresAt": "समाप्त होता है", + "status": "स्थिति", + "security": "सुरक्षा", + "files": "फाइलें", + "recipients": "प्राप्तकर्ता", + "actions": "क्रियाएं" + }, + "status": { + "neverExpires": "कभी समाप्त नहीं", + "active": "सक्रिय", + "expired": "समाप्त" + }, + "security": { + "protected": "संरक्षित", + "public": "सार्वजनिक" + }, + "filesCount": "फाइलें", + "recipientsCount": "प्राप्तकर्ता", + "actions": { + "menu": "साझाकरण क्रिया मेनू", + "edit": "संपादित करें", + "manageFiles": "फाइलें प्रबंधित करें", + "manageRecipients": "प्राप्तकर्ताओं का प्रबंधन करें", + "viewDetails": "विवरण देखें", + "generateLink": "लिंक उत्पन्न करें", + "editLink": "लिंक संपादित करें", + "copyLink": "लिंक कॉपी करें", + "notifyRecipients": "प्राप्तकर्ताओं को सूचित करें", + "delete": "हटाएं" + } + }, + "storageUsage": { + "title": "स्टोरेज उपयोग", + "ariaLabel": "स्टोरेज उपयोग प्रगति पट्टी", + "used": "उपयोग किया गया", + "available": "उपलब्ध" + }, + "theme": { + "toggle": "थीम टॉगल करें", + "light": "लाइट", + "dark": "डार्क", + "system": "सिस्टम" + }, + "uploadFile": { + "title": "फाइल अपलोड करें", + "selectFile": "फाइल चुनने के लिए क्लिक करें", + "preview": "पूर्वावलोकन", + "uploadProgress": "अपलोड प्रगति", + "upload": "अपलोड करें", + "success": "फाइल सफलतापूर्वक अपलोड हुई", + "error": "फाइल अपलोड करने में विफल" + }, "users": { "modes": { "create": "बनाएं", @@ -608,29 +629,16 @@ "userr": "उपयोगकर्ता" } }, - "logo": { - "labels": { - "appLogo": "एप्लिकेशन लोगो" - }, - "buttons": { - "upload": "लोगो अपलोड करें", - "remove": "लोगो हटाएं" - }, - "messages": { - "uploadSuccess": "लोगो सफलतापूर्वक अपलोड हुआ", - "removeSuccess": "लोगो सफलतापूर्वक हटाया गया" - }, - "errors": { - "uploadFailed": "लोगो अपलोड करने में विफल", - "removeFailed": "लोगो हटाने में विफल" - } - }, - "navbar": { - "logoAlt": "एप्लिकेशन लोगो", - "profileMenu": "प्रोफ़ाइल मेन्यू", - "profile": "प्रोफ़ाइल", - "settings": "सेटिंग्स", - "usersManagement": "उपयोगकर्ता प्रबंधन", - "logout": "लॉग आउट" + "validation": { + "invalidEmail": "अमान्य ईमेल पता", + "passwordMinLength": "पासवर्ड कम से कम 6 अक्षर का होना चाहिए", + "firstNameRequired": "पहला नाम आवश्यक है", + "lastNameRequired": "अंतिम नाम आवश्यक है", + "usernameLength": "उपयोगकर्ता नाम कम से कम 3 अक्षर का होना चाहिए", + "usernameSpaces": "उपयोगकर्ता नाम में रिक्त स्थान नहीं हो सकते", + "passwordLength": "पासवर्ड कम से कम 8 अक्षर का होना चाहिए", + "passwordsMatch": "पासवर्ड मेल नहीं खाते", + "emailRequired": "ईमेल आवश्यक है", + "passwordRequired": "पासवर्ड आवश्यक है" } -} \ No newline at end of file +} diff --git a/apps/web/src/locales/ja-JP.json b/apps/web/messages/ja-JP.json similarity index 97% rename from apps/web/src/locales/ja-JP.json rename to apps/web/messages/ja-JP.json index ef02730..9478551 100644 --- a/apps/web/src/locales/ja-JP.json +++ b/apps/web/messages/ja-JP.json @@ -1,58 +1,4 @@ { - "login": { - "welcome": "ようこそ", - "signInToContinue": "続行するにはサインインしてください", - "emailLabel": "メールアドレス", - "emailPlaceholder": "メールアドレスを入力してください", - "passwordLabel": "パスワード", - "passwordPlaceholder": "パスワードを入力してください", - "signIn": "サインイン", - "signingIn": "サインイン中...", - "forgotPassword": "パスワードをお忘れですか?", - "pageTitle": "ログイン" - }, - "errors": { - "invalidCredentials": "無効なメールアドレスまたはパスワードです", - "userNotFound": "ユーザーが見つかりません", - "accountLocked": "アカウントがロックされています。後でもう一度お試しください", - "unexpectedError": "予期しないエラーが発生しました。もう一度お試しください" - }, - "validation": { - "invalidEmail": "無効なメールアドレスです", - "passwordMinLength": "パスワードは最低6文字必要です", - "firstNameRequired": "名は必須です", - "lastNameRequired": "姓は必須です", - "usernameLength": "ユーザー名は最低3文字必要です", - "usernameSpaces": "ユーザー名にスペースは使用できません", - "passwordLength": "パスワードは最低8文字必要です", - "passwordsMatch": "パスワードが一致しません" - }, - "fileSelector": { - "availableFiles": "利用可能なファイル ({{count}})", - "shareFiles": "ファイルを共有 ({{count}})", - "searchPlaceholder": "ファイルを検索...", - "noMatchingFiles": "一致するファイルがありません", - "noAvailableFiles": "利用可能なファイルがありません", - "noFilesInShare": "共有ファイルがありません", - "saveChanges": "変更を保存" - }, - "recipientSelector": { - "emailPlaceholder": "受信者のメールを入力してください", - "add": "追加", - "recipients": "受信者 ({{count}})", - "notifyAll": "全員に通知", - "noRecipients": "まだ受信者が追加されていません", - "addSuccess": "受信者が正常に追加されました", - "addError": "受信者の追加に失敗しました", - "removeSuccess": "受信者が正常に削除されました", - "removeError": "受信者の削除に失敗しました", - "sendingNotifications": "通知を送信中...", - "notifySuccess": "受信者に正常に通知しました", - "notifyError": "受信者への通知に失敗しました" - }, - "navigation": { - "dashboard": "ダッシュボード" - }, "common": { "loading": "読み込み中です。しばらくお待ちください...", "cancel": "キャンセル", @@ -78,6 +24,22 @@ "success": "共有が正常に作成されました", "error": "共有の作成に失敗しました" }, + "dashboard": { + "loadError": "ダッシュボードデータの読み込みに失敗しました", + "linkCopied": "リンクがクリップボードにコピーされました", + "pageTitle": "ダッシュボード", + "breadcrumb": "ダッシュボード" + }, + "emptyState": { + "noFiles": "まだファイルがアップロードされていません", + "uploadFile": "ファイルをアップロード" + }, + "errors": { + "invalidCredentials": "無効なメールアドレスまたはパスワードです", + "userNotFound": "ユーザーが見つかりません", + "accountLocked": "アカウントがロックされています。後でもう一度お試しください", + "unexpectedError": "予期しないエラーが発生しました。もう一度お試しください" + }, "fileActions": { "editFile": "ファイルを編集", "nameLabel": "名前", @@ -86,9 +48,16 @@ "descriptionLabel": "説明", "descriptionPlaceholder": "ファイルの説明を入力してください", "deleteFile": "ファイルを削除", - "deleteConfirmation": "\"{{fileName}}\"を削除してもよろしいですか?", + "deleteConfirmation": "を削除してもよろしいですか?", "deleteWarning": "この操作は元に戻せません。" }, + "fileManager": { + "downloadError": "ファイルのダウンロードに失敗しました", + "updateSuccess": "ファイルが正常に更新されました", + "updateError": "ファイルの更新に失敗しました", + "deleteSuccess": "ファイルが正常に削除されました", + "deleteError": "ファイルの削除に失敗しました" + }, "filePreview": { "loading": "プレビューを読み込み中...", "notAvailable": "プレビューは利用できません", @@ -98,68 +67,21 @@ "loadError": "プレビューの読み込みに失敗しました", "downloadError": "ファイルのダウンロードに失敗しました" }, - "generateShareLink": { - "generateTitle": "共有リンクを生成", - "updateTitle": "共有リンクを更新", - "generateDescription": "ファイルを共有するためのリンクを生成します", - "updateDescription": "この共有リンクのエイリアスを更新します", - "aliasPlaceholder": "エイリアスを入力してください", - "linkReady": "共有リンクの準備ができました:", - "generateButton": "リンクを生成", - "updateButton": "リンクを更新", - "copyButton": "リンクをコピー", - "success": "リンクが正常に生成されました", - "error": "リンクの生成に失敗しました", - "copied": "リンクがクリップボードにコピーされました" + "fileSelector": { + "availableFiles": "利用可能なファイル ({{count}})", + "shareFiles": "ファイルを共有 ({{count}})", + "searchPlaceholder": "ファイルを検索...", + "noMatchingFiles": "一致するファイルがありません", + "noAvailableFiles": "利用可能なファイルがありません", + "noFilesInShare": "共有ファイルがありません", + "saveChanges": "変更を保存" }, - "shareActions": { - "deleteTitle": "共有を削除", - "deleteConfirmation": "この共有を削除してもよろしいですか?この操作は元に戻せません。", - "editTitle": "共有を編集", - "nameLabel": "共有名", - "expirationLabel": "有効期限", - "expirationPlaceholder": "MM/DD/YYYY HH:MM", - "maxViewsLabel": "最大ビュー数", - "maxViewsPlaceholder": "無制限の場合は空白のままにする", - "passwordProtection": "パスワード保護", - "passwordLabel": "パスワード", - "passwordPlaceholder": "パスワードを入力してください", - "newPasswordLabel": "新しいパスワード(現在のパスワードを保持する場合は空白のまま)", - "newPasswordPlaceholder": "新しいパスワードを入力してください", - "manageFilesTitle": "ファイルの管理", - "manageRecipientsTitle": "受信者の管理", - "editSuccess": "共有が正常に更新されました", - "editError": "共有の更新に失敗しました" - }, - "shareDetails": { - "title": "共有の詳細", - "subtitle": "この共有の詳細情報", - "basicInfo": "基本情報", - "name": "名前", - "untitled": "無題", - "views": "ビュー数", - "dates": "日付", - "created": "作成日", - "expires": "有効期限", - "never": "なし", - "security": "セキュリティ", - "passwordProtected": "パスワード保護", - "publicAccess": "公開アクセス", - "maxViews": "最大ビュー数: {{count}}", - "files": "ファイル ({{count}})", - "recipients": "受信者 ({{count}})", - "notAvailable": "該当なし", - "invalidDate": "無効な日付です", - "loadError": "共有の詳細の読み込みに失敗しました" - }, - "uploadFile": { - "title": "ファイルをアップロード", - "selectFile": "ファイルを選択するにはクリックしてください", - "preview": "プレビュー", - "uploadProgress": "アップロードの進行状況", - "upload": "アップロード", - "success": "ファイルが正常にアップロードされました", - "error": "ファイルのアップロードに失敗しました" + "files": { + "title": "すべてのファイル", + "uploadFile": "ファイルをアップロード", + "loadError": "ファイルの読み込みに失敗しました", + "pageTitle": "マイファイル", + "breadcrumb": "マイファイル" }, "filesTable": { "ariaLabel": "ファイルテーブル", @@ -179,119 +101,10 @@ "delete": "削除" } }, - "sharesTable": { - "ariaLabel": "共有テーブル", - "never": "なし", - "columns": { - "name": "名前", - "createdAt": "作成日", - "expiresAt": "有効期限", - "status": "ステータス", - "security": "セキュリティ", - "files": "ファイル", - "recipients": "受信者", - "actions": "操作" - }, - "status": { - "neverExpires": "無期限", - "active": "アクティブ", - "expired": "期限切れ" - }, - "security": { - "protected": "保護済み", - "public": "公開" - }, - "filesCount": "{{count}} ファイル", - "recipientsCount": "{{count}} 受信者", - "actions": { - "menu": "共有操作メニュー", - "edit": "編集", - "manageFiles": "ファイル管理", - "manageRecipients": "受信者管理", - "viewDetails": "詳細を表示", - "generateLink": "リンクを生成", - "editLink": "リンクを編集", - "copyLink": "リンクをコピー", - "notifyRecipients": "受信者に通知", - "delete": "削除" - } - }, "footer": { "poweredBy": "提供:", "kyanHomepage": "Kyantech ホームページ" }, - "fileManager": { - "downloadError": "ファイルのダウンロードに失敗しました", - "updateSuccess": "ファイルが正常に更新されました", - "updateError": "ファイルの更新に失敗しました", - "deleteSuccess": "ファイルが正常に削除されました", - "deleteError": "ファイルの削除に失敗しました" - }, - "shareManager": { - "deleteSuccess": "共有が正常に削除されました", - "deleteError": "共有の削除に失敗しました", - "updateSuccess": "共有が正常に更新されました", - "updateError": "共有の更新に失敗しました", - "filesUpdateSuccess": "ファイルが正常に更新されました", - "filesUpdateError": "ファイルの更新に失敗しました", - "recipientsUpdateSuccess": "受信者が正常に更新されました", - "recipientsUpdateError": "受信者の更新に失敗しました", - "linkGenerateSuccess": "共有リンクが正常に生成されました", - "linkGenerateError": "共有リンクの生成に失敗しました", - "notifyLoading": "通知を送信中...", - "notifySuccess": "受信者に正常に通知しました", - "notifyError": "受信者への通知に失敗しました" - }, - "quickAccess": { - "files": { - "title": "マイファイル", - "description": "アップロードされたファイルにアクセスし、管理します" - }, - "shares": { - "title": "マイ共有", - "description": "共有されたファイルを表示および管理します" - } - }, - "recentFiles": { - "title": "最近のアップロード", - "viewAll": "すべて表示", - "uploadFile": "ファイルをアップロード", - "noFiles": "まだファイルがアップロードされていません" - }, - "recentShares": { - "title": "最近の共有", - "viewAll": "すべて表示", - "createShare": "共有を作成", - "noShares": "まだ共有が作成されていません", - "createFirst": "最初の共有を作成してください" - }, - "storageUsage": { - "title": "ストレージ使用量", - "ariaLabel": "ストレージ使用状況のプログレスバー", - "used": "{{size}} 使用済み", - "available": "{{size}} 利用可能" - }, - "dashboard": { - "loadError": "ダッシュボードデータの読み込みに失敗しました", - "linkCopied": "リンクがクリップボードにコピーされました", - "pageTitle": "ダッシュボード", - "breadcrumb": "ダッシュボード" - }, - "emptyState": { - "noFiles": "まだファイルがアップロードされていません", - "uploadFile": "ファイルをアップロード" - }, - "files": { - "title": "すべてのファイル", - "uploadFile": "ファイルをアップロード", - "loadError": "ファイルの読み込みに失敗しました", - "pageTitle": "マイファイル", - "breadcrumb": "マイファイル" - }, - "searchBar": { - "placeholder": "ファイルを検索...", - "results": "全{{total}}件中{{filtered}}件が見つかりました" - }, "forgotPassword": { "emailLabel": "メールアドレス", "emailPlaceholder": "メールアドレスを入力してください", @@ -303,6 +116,20 @@ "resetInstructions": "パスワードリセットの指示がメールに送信されました", "pageTitle": "パスワードをお忘れですか?" }, + "generateShareLink": { + "generateTitle": "共有リンクを生成", + "updateTitle": "共有リンクを更新", + "generateDescription": "ファイルを共有するためのリンクを生成します", + "updateDescription": "この共有リンクのエイリアスを更新します", + "aliasPlaceholder": "エイリアスを入力してください", + "linkReady": "共有リンクの準備ができました:", + "generateButton": "リンクを生成", + "updateButton": "リンクを更新", + "copyButton": "リンクをコピー", + "success": "リンクが正常に生成されました", + "error": "リンクの生成に失敗しました", + "copied": "リンクがクリップボードにコピーされました" + }, "home": { "description": "WeTransferのオープンソース代替です。トラッキングや制限なしに安全にファイルを共有します。", "documentation": "ドキュメント", @@ -314,6 +141,46 @@ }, "pageTitle": "ホーム" }, + "login": { + "welcome": "ようこそへ", + "signInToContinue": "続行するにはサインインしてください", + "emailLabel": "メールアドレス", + "emailPlaceholder": "メールアドレスを入力してください", + "passwordLabel": "パスワード", + "passwordPlaceholder": "パスワードを入力してください", + "signIn": "サインイン", + "signingIn": "サインイン中...", + "forgotPassword": "パスワードをお忘れですか?", + "pageTitle": "ログイン" + }, + "logo": { + "labels": { + "appLogo": "アプリケーションロゴ" + }, + "buttons": { + "upload": "ロゴをアップロード", + "remove": "ロゴを削除" + }, + "messages": { + "uploadSuccess": "ロゴが正常にアップロードされました", + "removeSuccess": "ロゴが正常に削除されました" + }, + "errors": { + "uploadFailed": "ロゴのアップロードに失敗しました", + "removeFailed": "ロゴの削除に失敗しました" + } + }, + "navbar": { + "logoAlt": "アプリケーションロゴ", + "profileMenu": "プロフィールメニュー", + "profile": "プロフィール", + "settings": "設定", + "usersManagement": "ユーザー管理", + "logout": "ログアウト" + }, + "navigation": { + "dashboard": "ダッシュボード" + }, "profile": { "password": { "title": "パスワードを変更", @@ -356,6 +223,43 @@ }, "pageTitle": "プロフィール" }, + "quickAccess": { + "files": { + "title": "マイファイル", + "description": "アップロードされたファイルにアクセスし、管理します" + }, + "shares": { + "title": "マイ共有", + "description": "共有されたファイルを表示および管理します" + } + }, + "recentFiles": { + "title": "最近のアップロード", + "viewAll": "すべて表示", + "uploadFile": "ファイルをアップロード", + "noFiles": "まだファイルがアップロードされていません" + }, + "recentShares": { + "title": "最近の共有", + "viewAll": "すべて表示", + "createShare": "共有を作成", + "noShares": "まだ共有が作成されていません", + "createFirst": "最初の共有を作成してください" + }, + "recipientSelector": { + "emailPlaceholder": "受信者のメールを入力してください", + "add": "追加", + "recipients": "受信者 ({{count}})", + "notifyAll": "全員に通知", + "noRecipients": "まだ受信者が追加されていません", + "addSuccess": "受信者が正常に追加されました", + "addError": "受信者の追加に失敗しました", + "removeSuccess": "受信者が正常に削除されました", + "removeError": "受信者の削除に失敗しました", + "sendingNotifications": "通知を送信中...", + "notifySuccess": "受信者に正常に通知しました", + "notifyError": "受信者への通知に失敗しました" + }, "resetPassword": { "pageTitle": "パスワードリセット", "header": { @@ -379,6 +283,10 @@ "invalidToken": "無効なリセットトークン、またはトークンが存在しません" } }, + "searchBar": { + "placeholder": "ファイルを検索...", + "results": "全{{total}}件中{{filtered}}件が見つかりました" + }, "settings": { "groups": { "defaultDescription": "構成オプション", @@ -513,6 +421,61 @@ }, "pageTitle": "共有" }, + "shareActions": { + "deleteTitle": "共有を削除", + "deleteConfirmation": "この共有を削除してもよろしいですか?この操作は元に戻せません。", + "editTitle": "共有を編集", + "nameLabel": "共有名", + "expirationLabel": "有効期限", + "expirationPlaceholder": "MM/DD/YYYY HH:MM", + "maxViewsLabel": "最大ビュー数", + "maxViewsPlaceholder": "無制限の場合は空白のままにする", + "passwordProtection": "パスワード保護", + "passwordLabel": "パスワード", + "passwordPlaceholder": "パスワードを入力してください", + "newPasswordLabel": "新しいパスワード(現在のパスワードを保持する場合は空白のまま)", + "newPasswordPlaceholder": "新しいパスワードを入力してください", + "manageFilesTitle": "ファイルの管理", + "manageRecipientsTitle": "受信者の管理", + "editSuccess": "共有が正常に更新されました", + "editError": "共有の更新に失敗しました" + }, + "shareDetails": { + "title": "共有の詳細", + "subtitle": "この共有の詳細情報", + "basicInfo": "基本情報", + "name": "名前", + "untitled": "無題", + "views": "ビュー数", + "dates": "日付", + "created": "作成日", + "expires": "有効期限", + "never": "なし", + "security": "セキュリティ", + "passwordProtected": "パスワード保護", + "publicAccess": "公開アクセス", + "maxViews": "最大ビュー数:", + "files": "ファイル", + "recipients": "受信者", + "notAvailable": "該当なし", + "invalidDate": "無効な日付です", + "loadError": "共有の詳細の読み込みに失敗しました" + }, + "shareManager": { + "deleteSuccess": "共有が正常に削除されました", + "deleteError": "共有の削除に失敗しました", + "updateSuccess": "共有が正常に更新されました", + "updateError": "共有の更新に失敗しました", + "filesUpdateSuccess": "ファイルが正常に更新されました", + "filesUpdateError": "ファイルの更新に失敗しました", + "recipientsUpdateSuccess": "受信者が正常に更新されました", + "recipientsUpdateError": "受信者の更新に失敗しました", + "linkGenerateSuccess": "共有リンクが正常に生成されました", + "linkGenerateError": "共有リンクの生成に失敗しました", + "notifyLoading": "通知を送信中...", + "notifySuccess": "受信者に正常に通知しました", + "notifyError": "受信者への通知に失敗しました" + }, "shares": { "errors": { "loadFailed": "共有の読み込みに失敗しました", @@ -539,6 +502,64 @@ }, "pageTitle": "共有" }, + "sharesTable": { + "ariaLabel": "共有テーブル", + "never": "なし", + "columns": { + "name": "名前", + "createdAt": "作成日", + "expiresAt": "有効期限", + "status": "ステータス", + "security": "セキュリティ", + "files": "ファイル", + "recipients": "受信者", + "actions": "操作" + }, + "status": { + "neverExpires": "無期限", + "active": "アクティブ", + "expired": "期限切れ" + }, + "security": { + "protected": "保護済み", + "public": "公開" + }, + "filesCount": "ファイル", + "recipientsCount": "受信者", + "actions": { + "menu": "共有操作メニュー", + "edit": "編集", + "manageFiles": "ファイル管理", + "manageRecipients": "受信者管理", + "viewDetails": "詳細を表示", + "generateLink": "リンクを生成", + "editLink": "リンクを編集", + "copyLink": "リンクをコピー", + "notifyRecipients": "受信者に通知", + "delete": "削除" + } + }, + "storageUsage": { + "title": "ストレージ使用量", + "ariaLabel": "ストレージ使用状況のプログレスバー", + "used": "使用済み", + "available": "利用可能" + }, + "theme": { + "toggle": "テーマを切り替える", + "light": "ライト", + "dark": "ダーク", + "system": "システム" + }, + "uploadFile": { + "title": "ファイルをアップロード", + "selectFile": "ファイルを選択するにはクリックしてください", + "preview": "プレビュー", + "uploadProgress": "アップロードの進行状況", + "upload": "アップロード", + "success": "ファイルが正常にアップロードされました", + "error": "ファイルのアップロードに失敗しました" + }, "users": { "modes": { "create": "作成", @@ -608,29 +629,16 @@ "userr": "ユーザー" } }, - "logo": { - "labels": { - "appLogo": "アプリケーションロゴ" - }, - "buttons": { - "upload": "ロゴをアップロード", - "remove": "ロゴを削除" - }, - "messages": { - "uploadSuccess": "ロゴが正常にアップロードされました", - "removeSuccess": "ロゴが正常に削除されました" - }, - "errors": { - "uploadFailed": "ロゴのアップロードに失敗しました", - "removeFailed": "ロゴの削除に失敗しました" - } - }, - "navbar": { - "logoAlt": "アプリケーションロゴ", - "profileMenu": "プロフィールメニュー", - "profile": "プロフィール", - "settings": "設定", - "usersManagement": "ユーザー管理", - "logout": "ログアウト" + "validation": { + "invalidEmail": "無効なメールアドレスです", + "passwordMinLength": "パスワードは最低6文字必要です", + "firstNameRequired": "名は必須です", + "lastNameRequired": "姓は必須です", + "usernameLength": "ユーザー名は最低3文字必要です", + "usernameSpaces": "ユーザー名にスペースは使用できません", + "passwordLength": "パスワードは最低8文字必要です", + "passwordsMatch": "パスワードが一致しません", + "emailRequired": "メールアドレスは必須です", + "passwordRequired": "パスワードは必須です" } -} \ No newline at end of file +} diff --git a/apps/web/src/locales/ko-KR.json b/apps/web/messages/ko-KR.json similarity index 97% rename from apps/web/src/locales/ko-KR.json rename to apps/web/messages/ko-KR.json index 5453131..030359b 100644 --- a/apps/web/src/locales/ko-KR.json +++ b/apps/web/messages/ko-KR.json @@ -1,58 +1,4 @@ { - "login": { - "welcome": "환영합니다", - "signInToContinue": "계속하려면 로그인하세요", - "emailLabel": "이메일 주소", - "emailPlaceholder": "이메일을 입력하세요", - "passwordLabel": "비밀번호", - "passwordPlaceholder": "비밀번호를 입력하세요", - "signIn": "로그인", - "signingIn": "로그인 중...", - "forgotPassword": "비밀번호를 잊으셨나요?", - "pageTitle": "로그인" - }, - "errors": { - "invalidCredentials": "잘못된 이메일 또는 비밀번호입니다", - "userNotFound": "사용자를 찾을 수 없습니다", - "accountLocked": "계정이 잠겼습니다. 나중에 다시 시도하세요", - "unexpectedError": "예기치 않은 오류가 발생했습니다. 다시 시도해주세요" - }, - "validation": { - "invalidEmail": "유효하지 않은 이메일 주소입니다", - "passwordMinLength": "비밀번호는 최소 6자 이상이어야 합니다", - "firstNameRequired": "이름은 필수입니다", - "lastNameRequired": "성을 입력하세요", - "usernameLength": "사용자 이름은 최소 3자 이상이어야 합니다", - "usernameSpaces": "사용자 이름에는 공백을 사용할 수 없습니다", - "passwordLength": "비밀번호는 최소 8자 이상이어야 합니다", - "passwordsMatch": "비밀번호가 일치하지 않습니다" - }, - "fileSelector": { - "availableFiles": "사용 가능한 파일 ({{count}})", - "shareFiles": "파일 공유 ({{count}})", - "searchPlaceholder": "파일 검색...", - "noMatchingFiles": "일치하는 파일이 없습니다", - "noAvailableFiles": "사용 가능한 파일이 없습니다", - "noFilesInShare": "공유된 파일이 없습니다", - "saveChanges": "변경 사항 저장" - }, - "recipientSelector": { - "emailPlaceholder": "수신자 이메일을 입력하세요", - "add": "추가", - "recipients": "수신자 ({{count}})", - "notifyAll": "모두에게 알림", - "noRecipients": "아직 수신자가 추가되지 않았습니다", - "addSuccess": "수신자가 성공적으로 추가되었습니다", - "addError": "수신자 추가에 실패했습니다", - "removeSuccess": "수신자가 성공적으로 제거되었습니다", - "removeError": "수신자 제거에 실패했습니다", - "sendingNotifications": "알림 전송 중...", - "notifySuccess": "수신자에게 성공적으로 알렸습니다", - "notifyError": "수신자 알림 전송에 실패했습니다" - }, - "navigation": { - "dashboard": "대시보드" - }, "common": { "loading": "로딩 중입니다. 잠시 기다려주세요...", "cancel": "취소", @@ -78,6 +24,22 @@ "success": "공유가 성공적으로 생성되었습니다", "error": "공유 생성에 실패했습니다" }, + "dashboard": { + "loadError": "대시보드 데이터를 불러오는데 실패했습니다", + "linkCopied": "링크가 클립보드에 복사되었습니다", + "pageTitle": "대시보드", + "breadcrumb": "대시보드" + }, + "emptyState": { + "noFiles": "아직 파일이 업로드되지 않았습니다", + "uploadFile": "파일 업로드" + }, + "errors": { + "invalidCredentials": "잘못된 이메일 또는 비밀번호입니다", + "userNotFound": "사용자를 찾을 수 없습니다", + "accountLocked": "계정이 잠겼습니다. 나중에 다시 시도하세요", + "unexpectedError": "예기치 않은 오류가 발생했습니다. 다시 시도해주세요" + }, "fileActions": { "editFile": "파일 편집", "nameLabel": "이름", @@ -86,9 +48,16 @@ "descriptionLabel": "설명", "descriptionPlaceholder": "파일 설명을 입력하세요", "deleteFile": "파일 삭제", - "deleteConfirmation": "\"{{fileName}}\"을(를) 삭제하시겠습니까?", + "deleteConfirmation": "을(를) 삭제하시겠습니까?", "deleteWarning": "이 작업은 취소할 수 없습니다." }, + "fileManager": { + "downloadError": "파일 다운로드에 실패했습니다", + "updateSuccess": "파일이 성공적으로 업데이트되었습니다", + "updateError": "파일 업데이트에 실패했습니다", + "deleteSuccess": "파일이 성공적으로 삭제되었습니다", + "deleteError": "파일 삭제에 실패했습니다" + }, "filePreview": { "loading": "미리보기를 불러오는 중...", "notAvailable": "미리보기를 사용할 수 없습니다", @@ -98,68 +67,21 @@ "loadError": "미리보기 불러오기에 실패했습니다", "downloadError": "파일 다운로드에 실패했습니다" }, - "generateShareLink": { - "generateTitle": "공유 링크 생성", - "updateTitle": "공유 링크 업데이트", - "generateDescription": "파일을 공유할 링크를 생성합니다", - "updateDescription": "이 공유 링크의 별칭을 업데이트합니다", - "aliasPlaceholder": "별칭을 입력하세요", - "linkReady": "공유 링크가 준비되었습니다:", - "generateButton": "링크 생성", - "updateButton": "링크 업데이트", - "copyButton": "링크 복사", - "success": "링크가 성공적으로 생성되었습니다", - "error": "링크 생성에 실패했습니다", - "copied": "링크가 클립보드에 복사되었습니다" + "fileSelector": { + "availableFiles": "사용 가능한 파일 ({{count}})", + "shareFiles": "파일 공유 ({{count}})", + "searchPlaceholder": "파일 검색...", + "noMatchingFiles": "일치하는 파일이 없습니다", + "noAvailableFiles": "사용 가능한 파일이 없습니다", + "noFilesInShare": "공유된 파일이 없습니다", + "saveChanges": "변경 사항 저장" }, - "shareActions": { - "deleteTitle": "공유 삭제", - "deleteConfirmation": "이 공유를 삭제하시겠습니까? 이 작업은 되돌릴 수 없습니다.", - "editTitle": "공유 편집", - "nameLabel": "공유 이름", - "expirationLabel": "만료 날짜", - "expirationPlaceholder": "MM/DD/YYYY HH:MM", - "maxViewsLabel": "최대 조회수", - "maxViewsPlaceholder": "무제한인 경우 비워두세요", - "passwordProtection": "비밀번호 보호", - "passwordLabel": "비밀번호", - "passwordPlaceholder": "비밀번호를 입력하세요", - "newPasswordLabel": "새 비밀번호 (현재 비밀번호 유지 시 비워두세요)", - "newPasswordPlaceholder": "새 비밀번호를 입력하세요", - "manageFilesTitle": "파일 관리", - "manageRecipientsTitle": "수신자 관리", - "editSuccess": "공유가 성공적으로 업데이트되었습니다", - "editError": "공유 업데이트에 실패했습니다" - }, - "shareDetails": { - "title": "공유 세부 정보", - "subtitle": "이 공유에 대한 자세한 정보", - "basicInfo": "기본 정보", - "name": "이름", - "untitled": "제목 없음", - "views": "조회수", - "dates": "날짜", - "created": "생성됨", - "expires": "만료됨", - "never": "없음", - "security": "보안", - "passwordProtected": "비밀번호 보호됨", - "publicAccess": "공개 접근", - "maxViews": "최대 조회수: {{count}}", - "files": "파일 ({{count}})", - "recipients": "수신자 ({{count}})", - "notAvailable": "해당 없음", - "invalidDate": "유효하지 않은 날짜입니다", - "loadError": "공유 세부 정보를 불러오는데 실패했습니다" - }, - "uploadFile": { - "title": "파일 업로드", - "selectFile": "파일 선택을 위해 클릭하세요", - "preview": "미리보기", - "uploadProgress": "업로드 진행", - "upload": "업로드", - "success": "파일이 성공적으로 업로드되었습니다", - "error": "파일 업로드에 실패했습니다" + "files": { + "title": "모든 파일", + "uploadFile": "파일 업로드", + "loadError": "파일을 불러오는데 실패했습니다", + "pageTitle": "내 파일", + "breadcrumb": "내 파일" }, "filesTable": { "ariaLabel": "파일 테이블", @@ -179,119 +101,10 @@ "delete": "삭제" } }, - "sharesTable": { - "ariaLabel": "공유 테이블", - "never": "없음", - "columns": { - "name": "이름", - "createdAt": "생성일", - "expiresAt": "만료일", - "status": "상태", - "security": "보안", - "files": "파일", - "recipients": "수신자", - "actions": "작업" - }, - "status": { - "neverExpires": "만료되지 않음", - "active": "활성", - "expired": "만료됨" - }, - "security": { - "protected": "보호됨", - "public": "공개" - }, - "filesCount": "{{count}}개의 파일", - "recipientsCount": "{{count}}명의 수신자", - "actions": { - "menu": "공유 작업 메뉴", - "edit": "편집", - "manageFiles": "파일 관리", - "manageRecipients": "수신자 관리", - "viewDetails": "세부 정보 보기", - "generateLink": "링크 생성", - "editLink": "링크 편집", - "copyLink": "링크 복사", - "notifyRecipients": "수신자 알림", - "delete": "삭제" - } - }, "footer": { "poweredBy": "제공:", "kyanHomepage": "Kyantech 홈페이지" }, - "fileManager": { - "downloadError": "파일 다운로드에 실패했습니다", - "updateSuccess": "파일이 성공적으로 업데이트되었습니다", - "updateError": "파일 업데이트에 실패했습니다", - "deleteSuccess": "파일이 성공적으로 삭제되었습니다", - "deleteError": "파일 삭제에 실패했습니다" - }, - "shareManager": { - "deleteSuccess": "공유가 성공적으로 삭제되었습니다", - "deleteError": "공유 삭제에 실패했습니다", - "updateSuccess": "공유가 성공적으로 업데이트되었습니다", - "updateError": "공유 업데이트에 실패했습니다", - "filesUpdateSuccess": "파일이 성공적으로 업데이트되었습니다", - "filesUpdateError": "파일 업데이트에 실패했습니다", - "recipientsUpdateSuccess": "수신자가 성공적으로 업데이트되었습니다", - "recipientsUpdateError": "수신자 업데이트에 실패했습니다", - "linkGenerateSuccess": "공유 링크가 성공적으로 생성되었습니다", - "linkGenerateError": "공유 링크 생성에 실패했습니다", - "notifyLoading": "알림 전송 중...", - "notifySuccess": "수신자에게 성공적으로 알렸습니다", - "notifyError": "수신자 알림 전송에 실패했습니다" - }, - "quickAccess": { - "files": { - "title": "내 파일", - "description": "업로드된 파일에 접근하고 관리합니다" - }, - "shares": { - "title": "내 공유", - "description": "공유된 파일을 보고 관리합니다" - } - }, - "recentFiles": { - "title": "최근 업로드", - "viewAll": "전체 보기", - "uploadFile": "파일 업로드", - "noFiles": "아직 파일이 업로드되지 않았습니다" - }, - "recentShares": { - "title": "최근 공유", - "viewAll": "전체 보기", - "createShare": "공유 생성", - "noShares": "아직 공유가 생성되지 않았습니다", - "createFirst": "첫 번째 공유를 생성하세요" - }, - "storageUsage": { - "title": "스토리지 사용량", - "ariaLabel": "스토리지 사용량 진행 바", - "used": "{{size}} 사용됨", - "available": "{{size}} 사용 가능" - }, - "dashboard": { - "loadError": "대시보드 데이터를 불러오는데 실패했습니다", - "linkCopied": "링크가 클립보드에 복사되었습니다", - "pageTitle": "대시보드", - "breadcrumb": "대시보드" - }, - "emptyState": { - "noFiles": "아직 파일이 업로드되지 않았습니다", - "uploadFile": "파일 업로드" - }, - "files": { - "title": "모든 파일", - "uploadFile": "파일 업로드", - "loadError": "파일을 불러오는데 실패했습니다", - "pageTitle": "내 파일", - "breadcrumb": "내 파일" - }, - "searchBar": { - "placeholder": "파일 검색...", - "results": "전체 {{total}}개 중 {{filtered}}개 파일을 찾았습니다" - }, "forgotPassword": { "emailLabel": "이메일 주소", "emailPlaceholder": "이메일을 입력하세요", @@ -303,6 +116,20 @@ "resetInstructions": "비밀번호 재설정 지침이 이메일로 전송되었습니다", "pageTitle": "비밀번호를 잊으셨나요?" }, + "generateShareLink": { + "generateTitle": "공유 링크 생성", + "updateTitle": "공유 링크 업데이트", + "generateDescription": "파일을 공유할 링크를 생성합니다", + "updateDescription": "이 공유 링크의 별칭을 업데이트합니다", + "aliasPlaceholder": "별칭을 입력하세요", + "linkReady": "공유 링크가 준비되었습니다:", + "generateButton": "링크 생성", + "updateButton": "링크 업데이트", + "copyButton": "링크 복사", + "success": "링크가 성공적으로 생성되었습니다", + "error": "링크 생성에 실패했습니다", + "copied": "링크가 클립보드에 복사되었습니다" + }, "home": { "description": "WeTransfer의 오픈소스 대안입니다. 추적이나 제한 없이 파일을 안전하게 공유하세요.", "documentation": "문서", @@ -314,6 +141,46 @@ }, "pageTitle": "홈" }, + "login": { + "welcome": "에 오신 것을 환영합니다", + "signInToContinue": "계속하려면 로그인하세요", + "emailLabel": "이메일 주소", + "emailPlaceholder": "이메일을 입력하세요", + "passwordLabel": "비밀번호", + "passwordPlaceholder": "비밀번호를 입력하세요", + "signIn": "로그인", + "signingIn": "로그인 중...", + "forgotPassword": "비밀번호를 잊으셨나요?", + "pageTitle": "로그인" + }, + "logo": { + "labels": { + "appLogo": "애플리케이션 로고" + }, + "buttons": { + "upload": "로고 업로드", + "remove": "로고 삭제" + }, + "messages": { + "uploadSuccess": "로고가 성공적으로 업로드되었습니다", + "removeSuccess": "로고가 성공적으로 삭제되었습니다" + }, + "errors": { + "uploadFailed": "로고 업로드에 실패했습니다", + "removeFailed": "로고 삭제에 실패했습니다" + } + }, + "navbar": { + "logoAlt": "애플리케이션 로고", + "profileMenu": "프로필 메뉴", + "profile": "프로필", + "settings": "설정", + "usersManagement": "사용자 관리", + "logout": "로그아웃" + }, + "navigation": { + "dashboard": "대시보드" + }, "profile": { "password": { "title": "비밀번호 변경", @@ -356,6 +223,43 @@ }, "pageTitle": "프로필" }, + "quickAccess": { + "files": { + "title": "내 파일", + "description": "업로드된 파일에 접근하고 관리합니다" + }, + "shares": { + "title": "내 공유", + "description": "공유된 파일을 보고 관리합니다" + } + }, + "recentFiles": { + "title": "최근 업로드", + "viewAll": "전체 보기", + "uploadFile": "파일 업로드", + "noFiles": "아직 파일이 업로드되지 않았습니다" + }, + "recentShares": { + "title": "최근 공유", + "viewAll": "전체 보기", + "createShare": "공유 생성", + "noShares": "아직 공유가 생성되지 않았습니다", + "createFirst": "첫 번째 공유를 생성하세요" + }, + "recipientSelector": { + "emailPlaceholder": "수신자 이메일을 입력하세요", + "add": "추가", + "recipients": "수신자 ({{count}})", + "notifyAll": "모두에게 알림", + "noRecipients": "아직 수신자가 추가되지 않았습니다", + "addSuccess": "수신자가 성공적으로 추가되었습니다", + "addError": "수신자 추가에 실패했습니다", + "removeSuccess": "수신자가 성공적으로 제거되었습니다", + "removeError": "수신자 제거에 실패했습니다", + "sendingNotifications": "알림 전송 중...", + "notifySuccess": "수신자에게 성공적으로 알렸습니다", + "notifyError": "수신자 알림 전송에 실패했습니다" + }, "resetPassword": { "pageTitle": "비밀번호 재설정", "header": { @@ -379,6 +283,10 @@ "invalidToken": "유효하지 않거나 누락된 재설정 토큰" } }, + "searchBar": { + "placeholder": "파일 검색...", + "results": "전체 {{total}}개 중 {{filtered}}개 파일을 찾았습니다" + }, "settings": { "groups": { "defaultDescription": "구성 옵션", @@ -513,6 +421,61 @@ }, "pageTitle": "공유" }, + "shareActions": { + "deleteTitle": "공유 삭제", + "deleteConfirmation": "이 공유를 삭제하시겠습니까? 이 작업은 되돌릴 수 없습니다.", + "editTitle": "공유 편집", + "nameLabel": "공유 이름", + "expirationLabel": "만료 날짜", + "expirationPlaceholder": "MM/DD/YYYY HH:MM", + "maxViewsLabel": "최대 조회수", + "maxViewsPlaceholder": "무제한인 경우 비워두세요", + "passwordProtection": "비밀번호 보호", + "passwordLabel": "비밀번호", + "passwordPlaceholder": "비밀번호를 입력하세요", + "newPasswordLabel": "새 비밀번호 (현재 비밀번호 유지 시 비워두세요)", + "newPasswordPlaceholder": "새 비밀번호를 입력하세요", + "manageFilesTitle": "파일 관리", + "manageRecipientsTitle": "수신자 관리", + "editSuccess": "공유가 성공적으로 업데이트되었습니다", + "editError": "공유 업데이트에 실패했습니다" + }, + "shareDetails": { + "title": "공유 세부 정보", + "subtitle": "이 공유에 대한 자세한 정보", + "basicInfo": "기본 정보", + "name": "이름", + "untitled": "제목 없음", + "views": "조회수", + "dates": "날짜", + "created": "생성됨", + "expires": "만료됨", + "never": "없음", + "security": "보안", + "passwordProtected": "비밀번호 보호됨", + "publicAccess": "공개 접근", + "maxViews": "최대 조회수:", + "files": "파일", + "recipients": "수신자", + "notAvailable": "해당 없음", + "invalidDate": "유효하지 않은 날짜입니다", + "loadError": "공유 세부 정보를 불러오는데 실패했습니다" + }, + "shareManager": { + "deleteSuccess": "공유가 성공적으로 삭제되었습니다", + "deleteError": "공유 삭제에 실패했습니다", + "updateSuccess": "공유가 성공적으로 업데이트되었습니다", + "updateError": "공유 업데이트에 실패했습니다", + "filesUpdateSuccess": "파일이 성공적으로 업데이트되었습니다", + "filesUpdateError": "파일 업데이트에 실패했습니다", + "recipientsUpdateSuccess": "수신자가 성공적으로 업데이트되었습니다", + "recipientsUpdateError": "수신자 업데이트에 실패했습니다", + "linkGenerateSuccess": "공유 링크가 성공적으로 생성되었습니다", + "linkGenerateError": "공유 링크 생성에 실패했습니다", + "notifyLoading": "알림 전송 중...", + "notifySuccess": "수신자에게 성공적으로 알렸습니다", + "notifyError": "수신자 알림 전송에 실패했습니다" + }, "shares": { "errors": { "loadFailed": "공유 목록을 불러오는데 실패했습니다", @@ -539,6 +502,64 @@ }, "pageTitle": "공유" }, + "sharesTable": { + "ariaLabel": "공유 테이블", + "never": "없음", + "columns": { + "name": "이름", + "createdAt": "생성일", + "expiresAt": "만료일", + "status": "상태", + "security": "보안", + "files": "파일", + "recipients": "수신자", + "actions": "작업" + }, + "status": { + "neverExpires": "만료되지 않음", + "active": "활성", + "expired": "만료됨" + }, + "security": { + "protected": "보호됨", + "public": "공개" + }, + "filesCount": "개의 파일", + "recipientsCount": "명의 수신자", + "actions": { + "menu": "공유 작업 메뉴", + "edit": "편집", + "manageFiles": "파일 관리", + "manageRecipients": "수신자 관리", + "viewDetails": "세부 정보 보기", + "generateLink": "링크 생성", + "editLink": "링크 편집", + "copyLink": "링크 복사", + "notifyRecipients": "수신자 알림", + "delete": "삭제" + } + }, + "storageUsage": { + "title": "스토리지 사용량", + "ariaLabel": "스토리지 사용량 진행 바", + "used": "사용됨", + "available": "사용 가능" + }, + "theme": { + "toggle": "테마 전환", + "light": "라이트", + "dark": "다크", + "system": "시스템" + }, + "uploadFile": { + "title": "파일 업로드", + "selectFile": "파일 선택을 위해 클릭하세요", + "preview": "미리보기", + "uploadProgress": "업로드 진행", + "upload": "업로드", + "success": "파일이 성공적으로 업로드되었습니다", + "error": "파일 업로드에 실패했습니다" + }, "users": { "modes": { "create": "생성", @@ -608,29 +629,16 @@ "userr": "사용자" } }, - "logo": { - "labels": { - "appLogo": "애플리케이션 로고" - }, - "buttons": { - "upload": "로고 업로드", - "remove": "로고 삭제" - }, - "messages": { - "uploadSuccess": "로고가 성공적으로 업로드되었습니다", - "removeSuccess": "로고가 성공적으로 삭제되었습니다" - }, - "errors": { - "uploadFailed": "로고 업로드에 실패했습니다", - "removeFailed": "로고 삭제에 실패했습니다" - } - }, - "navbar": { - "logoAlt": "애플리케이션 로고", - "profileMenu": "프로필 메뉴", - "profile": "프로필", - "settings": "설정", - "usersManagement": "사용자 관리", - "logout": "로그아웃" + "validation": { + "invalidEmail": "유효하지 않은 이메일 주소입니다", + "passwordMinLength": "비밀번호는 최소 6자 이상이어야 합니다", + "firstNameRequired": "이름은 필수입니다", + "lastNameRequired": "성을 입력하세요", + "usernameLength": "사용자 이름은 최소 3자 이상이어야 합니다", + "usernameSpaces": "사용자 이름에는 공백을 사용할 수 없습니다", + "passwordLength": "비밀번호는 최소 8자 이상이어야 합니다", + "passwordsMatch": "비밀번호가 일치하지 않습니다", + "emailRequired": "이메일은 필수입니다", + "passwordRequired": "비밀번호는 필수입니다" } -} \ No newline at end of file +} diff --git a/apps/web/src/locales/pt-BR.json b/apps/web/messages/pt-BR.json similarity index 97% rename from apps/web/src/locales/pt-BR.json rename to apps/web/messages/pt-BR.json index 27ef35a..c90d1e5 100644 --- a/apps/web/src/locales/pt-BR.json +++ b/apps/web/messages/pt-BR.json @@ -1,58 +1,4 @@ { - "login": { - "welcome": "Bem-vindo", - "signInToContinue": "Entre para continuar", - "emailLabel": "Endereço de E-mail", - "emailPlaceholder": "Digite seu e-mail", - "passwordLabel": "Senha", - "passwordPlaceholder": "Digite sua senha", - "signIn": "Entrar", - "signingIn": "Entrando...", - "forgotPassword": "Esqueceu a senha?", - "pageTitle": "Entrar" - }, - "errors": { - "invalidCredentials": "E-mail ou senha inválidos", - "userNotFound": "Usuário não encontrado", - "accountLocked": "Conta bloqueada. Tente novamente mais tarde", - "unexpectedError": "Ocorreu um erro inesperado. Por favor, tente novamente" - }, - "validation": { - "invalidEmail": "Endereço de email inválido", - "passwordMinLength": "A senha deve ter pelo menos 6 caracteres", - "firstNameRequired": "Nome é obrigatório", - "lastNameRequired": "Sobrenome é obrigatório", - "usernameLength": "Nome de usuário deve ter pelo menos 3 caracteres", - "usernameSpaces": "Nome de usuário não pode conter espaços", - "passwordLength": "A senha deve ter pelo menos 8 caracteres", - "passwordsMatch": "As senhas não coincidem" - }, - "fileSelector": { - "availableFiles": "Arquivos Disponíveis ({{count}})", - "shareFiles": "Arquivos Compartilhados ({{count}})", - "searchPlaceholder": "Buscar arquivos...", - "noMatchingFiles": "Nenhum arquivo encontrado", - "noAvailableFiles": "Nenhum arquivo disponível", - "noFilesInShare": "Nenhum arquivo compartilhado", - "saveChanges": "Salvar Alterações" - }, - "recipientSelector": { - "emailPlaceholder": "Digite o e-mail do destinatário", - "add": "Adicionar", - "recipients": "Destinatários ({{count}})", - "notifyAll": "Notificar Todos", - "noRecipients": "Nenhum destinatário adicionado", - "addSuccess": "Destinatário adicionado com sucesso", - "addError": "Falha ao adicionar destinatário", - "removeSuccess": "Destinatário removido com sucesso", - "removeError": "Falha ao remover destinatário", - "sendingNotifications": "Enviando notificações...", - "notifySuccess": "Destinatários notificados com sucesso", - "notifyError": "Falha ao notificar destinatários" - }, - "navigation": { - "dashboard": "Painel" - }, "common": { "loading": "Carregando, aguarde...", "cancel": "Cancelar", @@ -78,6 +24,22 @@ "success": "Compartilhamento criado com sucesso", "error": "Falha ao criar compartilhamento" }, + "dashboard": { + "loadError": "Falha ao carregar dados do painel", + "linkCopied": "Link copiado para a área de transferência", + "pageTitle": "Painel", + "breadcrumb": "Painel" + }, + "emptyState": { + "noFiles": "Nenhum arquivo enviado ainda", + "uploadFile": "Enviar Arquivo" + }, + "errors": { + "invalidCredentials": "E-mail ou senha inválidos", + "userNotFound": "Usuário não encontrado", + "accountLocked": "Conta bloqueada. Tente novamente mais tarde", + "unexpectedError": "Ocorreu um erro inesperado. Por favor, tente novamente" + }, "fileActions": { "editFile": "Editar Arquivo", "nameLabel": "Nome", @@ -86,9 +48,16 @@ "descriptionLabel": "Descrição", "descriptionPlaceholder": "Digite a descrição do arquivo", "deleteFile": "Excluir Arquivo", - "deleteConfirmation": "Tem certeza que deseja excluir \"{{fileName}}\"?", + "deleteConfirmation": "Tem certeza que deseja excluir ?", "deleteWarning": "Esta ação não pode ser desfeita." }, + "fileManager": { + "downloadError": "Falha ao baixar arquivo", + "updateSuccess": "Arquivo atualizado com sucesso", + "updateError": "Falha ao atualizar arquivo", + "deleteSuccess": "Arquivo excluído com sucesso", + "deleteError": "Falha ao excluir arquivo" + }, "filePreview": { "loading": "Carregando visualização...", "notAvailable": "Visualização não disponível", @@ -98,68 +67,21 @@ "loadError": "Falha ao carregar a visualização", "downloadError": "Falha ao baixar o arquivo" }, - "generateShareLink": { - "generateTitle": "Gerar Link de Compartilhamento", - "updateTitle": "Atualizar Link de Compartilhamento", - "generateDescription": "Gere um link para compartilhar seus arquivos", - "updateDescription": "Atualize o alias deste link de compartilhamento", - "aliasPlaceholder": "Digite o alias", - "linkReady": "Seu link de compartilhamento está pronto:", - "generateButton": "Gerar Link", - "updateButton": "Atualizar Link", - "copyButton": "Copiar Link", - "success": "Link gerado com sucesso", - "error": "Erro ao gerar link", - "copied": "Link copiado para a área de transferência" + "fileSelector": { + "availableFiles": "Arquivos Disponíveis ({{count}})", + "shareFiles": "Arquivos Compartilhados ({{count}})", + "searchPlaceholder": "Buscar arquivos...", + "noMatchingFiles": "Nenhum arquivo encontrado", + "noAvailableFiles": "Nenhum arquivo disponível", + "noFilesInShare": "Nenhum arquivo compartilhado", + "saveChanges": "Salvar Alterações" }, - "shareActions": { - "deleteTitle": "Excluir Compartilhamento", - "deleteConfirmation": "Tem certeza que deseja excluir este compartilhamento? Esta ação não pode ser desfeita.", - "editTitle": "Editar Compartilhamento", - "nameLabel": "Nome do Compartilhamento", - "expirationLabel": "Data de Expiração", - "expirationPlaceholder": "DD/MM/AAAA HH:MM", - "maxViewsLabel": "Máximo de Visualizações", - "maxViewsPlaceholder": "Deixe vazio para ilimitado", - "passwordProtection": "Protegido por Senha", - "passwordLabel": "Senha", - "passwordPlaceholder": "Digite a senha", - "newPasswordLabel": "Nova Senha (deixe vazio para manter a atual)", - "newPasswordPlaceholder": "Digite a nova senha", - "manageFilesTitle": "Gerenciar Arquivos", - "manageRecipientsTitle": "Gerenciar Destinatários", - "editSuccess": "Compartilhamento atualizado com sucesso", - "editError": "Falha ao atualizar compartilhamento" - }, - "shareDetails": { - "title": "Detalhes do Compartilhamento", - "subtitle": "Informações detalhadas sobre este compartilhamento", - "basicInfo": "Informações Básicas", - "name": "Nome", - "untitled": "Compartilhamento sem título", - "views": "Visualizações", - "dates": "Datas", - "created": "Criado em: {{date}}", - "expires": "Expira em: {{date}}", - "never": "Nunca", - "security": "Segurança", - "passwordProtected": "Protegido por Senha", - "publicAccess": "Acesso Público", - "maxViews": "Máximo de Visualizações: {{count}}", - "files": "Arquivos ({{count}})", - "recipients": "Destinatários ({{count}})", - "notAvailable": "N/A", - "invalidDate": "Data inválida", - "loadError": "Falha ao carregar detalhes do compartilhamento" - }, - "uploadFile": { - "title": "Enviar Arquivo", - "selectFile": "Clique para selecionar um arquivo", - "preview": "Pré-visualização", - "uploadProgress": "Progresso do upload", - "upload": "Enviar", - "success": "Arquivo enviado com sucesso", - "error": "Falha ao enviar arquivo" + "files": { + "title": "Todos os Arquivos", + "uploadFile": "Enviar Arquivo", + "loadError": "Falha ao carregar arquivos", + "pageTitle": "Meus Arquivos", + "breadcrumb": "Meus Arquivos" }, "filesTable": { "ariaLabel": "Tabela de arquivos", @@ -179,119 +101,10 @@ "delete": "Excluir" } }, - "sharesTable": { - "ariaLabel": "Tabela de compartilhamentos", - "never": "Nunca", - "columns": { - "name": "NOME", - "createdAt": "CRIADO EM", - "expiresAt": "EXPIRA EM", - "status": "STATUS", - "security": "SEGURANÇA", - "files": "ARQUIVOS", - "recipients": "DESTINATÁRIOS", - "actions": "AÇÕES" - }, - "status": { - "neverExpires": "Nunca Expira", - "active": "Ativo", - "expired": "Expirado" - }, - "security": { - "protected": "Protegido", - "public": "Público" - }, - "filesCount": "{{count}} arquivos", - "recipientsCount": "{{count}} destinatários", - "actions": { - "menu": "Menu de ações do compartilhamento", - "edit": "Editar", - "manageFiles": "Gerenciar Arquivos", - "manageRecipients": "Gerenciar Destinatários", - "viewDetails": "Ver Detalhes", - "generateLink": "Gerar Link", - "editLink": "Editar Link", - "copyLink": "Copiar Link", - "notifyRecipients": "Notificar Destinatários", - "delete": "Excluir" - } - }, "footer": { "poweredBy": "Desenvolvido por", "kyanHomepage": "Página inicial da Kyantech" }, - "fileManager": { - "downloadError": "Falha ao baixar arquivo", - "updateSuccess": "Arquivo atualizado com sucesso", - "updateError": "Falha ao atualizar arquivo", - "deleteSuccess": "Arquivo excluído com sucesso", - "deleteError": "Falha ao excluir arquivo" - }, - "shareManager": { - "deleteSuccess": "Compartilhamento excluído com sucesso", - "deleteError": "Falha ao excluir compartilhamento", - "updateSuccess": "Compartilhamento atualizado com sucesso", - "updateError": "Falha ao atualizar compartilhamento", - "filesUpdateSuccess": "Arquivos atualizados com sucesso", - "filesUpdateError": "Falha ao atualizar arquivos", - "recipientsUpdateSuccess": "Destinatários atualizados com sucesso", - "recipientsUpdateError": "Falha ao atualizar destinatários", - "linkGenerateSuccess": "Link de compartilhamento gerado com sucesso", - "linkGenerateError": "Falha ao gerar link de compartilhamento", - "notifyLoading": "Enviando notificações...", - "notifySuccess": "Destinatários notificados com sucesso", - "notifyError": "Falha ao notificar destinatários" - }, - "quickAccess": { - "files": { - "title": "Meus Arquivos", - "description": "Acesse e gerencie seus arquivos enviados" - }, - "shares": { - "title": "Meus Compartilhamentos", - "description": "Visualize e gerencie seus arquivos compartilhados" - } - }, - "recentFiles": { - "title": "Uploads Recentes", - "viewAll": "Ver Todos", - "uploadFile": "Enviar Arquivo", - "noFiles": "Nenhum arquivo enviado ainda" - }, - "recentShares": { - "title": "Compartilhamentos Recentes", - "viewAll": "Ver Todos", - "createShare": "Criar Compartilhamento", - "noShares": "Nenhum compartilhamento criado ainda", - "createFirst": "Criar seu primeiro compartilhamento" - }, - "storageUsage": { - "title": "Uso de Armazenamento", - "ariaLabel": "Barra de progresso do uso de armazenamento", - "used": "{{size}} usado", - "available": "{{size}} disponível" - }, - "dashboard": { - "loadError": "Falha ao carregar dados do painel", - "linkCopied": "Link copiado para a área de transferência", - "pageTitle": "Painel", - "breadcrumb": "Painel" - }, - "emptyState": { - "noFiles": "Nenhum arquivo enviado ainda", - "uploadFile": "Enviar Arquivo" - }, - "files": { - "title": "Todos os Arquivos", - "uploadFile": "Enviar Arquivo", - "loadError": "Falha ao carregar arquivos", - "pageTitle": "Meus Arquivos", - "breadcrumb": "Meus Arquivos" - }, - "searchBar": { - "placeholder": "Buscar arquivos...", - "results": "Encontrados {{filtered}} de {{total}} arquivos" - }, "forgotPassword": { "emailLabel": "Endereço de Email", "emailPlaceholder": "Digite seu email", @@ -303,6 +116,20 @@ "resetInstructions": "Instruções de redefinição enviadas para seu email", "pageTitle": "Esqueceu a Senha" }, + "generateShareLink": { + "generateTitle": "Gerar Link de Compartilhamento", + "updateTitle": "Atualizar Link de Compartilhamento", + "generateDescription": "Gere um link para compartilhar seus arquivos", + "updateDescription": "Atualize o alias deste link de compartilhamento", + "aliasPlaceholder": "Digite o alias", + "linkReady": "Seu link de compartilhamento está pronto:", + "generateButton": "Gerar Link", + "updateButton": "Atualizar Link", + "copyButton": "Copiar Link", + "success": "Link gerado com sucesso", + "error": "Erro ao gerar link", + "copied": "Link copiado para a área de transferência" + }, "home": { "description": "A alternativa open-source ao WeTransfer. Compartilhe arquivos com segurança, sem rastreamento ou limitações.", "documentation": "Documentação", @@ -314,6 +141,46 @@ }, "pageTitle": "Início" }, + "login": { + "welcome": "Bem-vindo ao", + "signInToContinue": "Entre para continuar", + "emailLabel": "Endereço de E-mail", + "emailPlaceholder": "Digite seu e-mail", + "passwordLabel": "Senha", + "passwordPlaceholder": "Digite sua senha", + "signIn": "Entrar", + "signingIn": "Entrando...", + "forgotPassword": "Esqueceu a senha?", + "pageTitle": "Entrar" + }, + "logo": { + "labels": { + "appLogo": "Logo do Aplicativo" + }, + "buttons": { + "upload": "Enviar Logo", + "remove": "Remover Logo" + }, + "messages": { + "uploadSuccess": "Logo enviado com sucesso", + "removeSuccess": "Logo removido com sucesso" + }, + "errors": { + "uploadFailed": "Falha ao enviar logo", + "removeFailed": "Falha ao remover logo" + } + }, + "navbar": { + "logoAlt": "Logo do Aplicativo", + "profileMenu": "Menu do Perfil", + "profile": "Perfil", + "settings": "Configurações", + "usersManagement": "Gerenciar Usuários", + "logout": "Sair" + }, + "navigation": { + "dashboard": "Painel" + }, "profile": { "password": { "title": "Alterar Senha", @@ -356,6 +223,43 @@ }, "pageTitle": "Perfil" }, + "quickAccess": { + "files": { + "title": "Meus Arquivos", + "description": "Acesse e gerencie seus arquivos enviados" + }, + "shares": { + "title": "Meus Compartilhamentos", + "description": "Visualize e gerencie seus arquivos compartilhados" + } + }, + "recentFiles": { + "title": "Uploads Recentes", + "viewAll": "Ver Todos", + "uploadFile": "Enviar Arquivo", + "noFiles": "Nenhum arquivo enviado ainda" + }, + "recentShares": { + "title": "Compartilhamentos Recentes", + "viewAll": "Ver Todos", + "createShare": "Criar Compartilhamento", + "noShares": "Nenhum compartilhamento criado ainda", + "createFirst": "Criar seu primeiro compartilhamento" + }, + "recipientSelector": { + "emailPlaceholder": "Digite o e-mail do destinatário", + "add": "Adicionar", + "recipients": "Destinatários ({{count}})", + "notifyAll": "Notificar Todos", + "noRecipients": "Nenhum destinatário adicionado", + "addSuccess": "Destinatário adicionado com sucesso", + "addError": "Falha ao adicionar destinatário", + "removeSuccess": "Destinatário removido com sucesso", + "removeError": "Falha ao remover destinatário", + "sendingNotifications": "Enviando notificações...", + "notifySuccess": "Destinatários notificados com sucesso", + "notifyError": "Falha ao notificar destinatários" + }, "resetPassword": { "pageTitle": "Redefinir Senha", "header": { @@ -379,6 +283,10 @@ "invalidToken": "Token de redefinição inválido ou ausente" } }, + "searchBar": { + "placeholder": "Buscar arquivos...", + "results": "Encontrados {{filtered}} de {{total}} arquivos" + }, "settings": { "groups": { "defaultDescription": "Opções de configuração", @@ -513,6 +421,61 @@ }, "pageTitle": "Compartilhamento" }, + "shareActions": { + "deleteTitle": "Excluir Compartilhamento", + "deleteConfirmation": "Tem certeza que deseja excluir este compartilhamento? Esta ação não pode ser desfeita.", + "editTitle": "Editar Compartilhamento", + "nameLabel": "Nome do Compartilhamento", + "expirationLabel": "Data de Expiração", + "expirationPlaceholder": "DD/MM/AAAA HH:MM", + "maxViewsLabel": "Máximo de Visualizações", + "maxViewsPlaceholder": "Deixe vazio para ilimitado", + "passwordProtection": "Protegido por Senha", + "passwordLabel": "Senha", + "passwordPlaceholder": "Digite a senha", + "newPasswordLabel": "Nova Senha (deixe vazio para manter a atual)", + "newPasswordPlaceholder": "Digite a nova senha", + "manageFilesTitle": "Gerenciar Arquivos", + "manageRecipientsTitle": "Gerenciar Destinatários", + "editSuccess": "Compartilhamento atualizado com sucesso", + "editError": "Falha ao atualizar compartilhamento" + }, + "shareDetails": { + "title": "Detalhes do Compartilhamento", + "subtitle": "Informações detalhadas sobre este compartilhamento", + "basicInfo": "Informações Básicas", + "name": "Nome", + "untitled": "Compartilhamento sem título", + "views": "Visualizações", + "dates": "Datas", + "created": "Criado em: {{date}}", + "expires": "Expira em: {{date}}", + "never": "Nunca", + "security": "Segurança", + "passwordProtected": "Protegido por Senha", + "publicAccess": "Acesso Público", + "maxViews": "Máximo de Visualizações:", + "files": "Arquivos", + "recipients": "Destinatários", + "notAvailable": "N/A", + "invalidDate": "Data inválida", + "loadError": "Falha ao carregar detalhes do compartilhamento" + }, + "shareManager": { + "deleteSuccess": "Compartilhamento excluído com sucesso", + "deleteError": "Falha ao excluir compartilhamento", + "updateSuccess": "Compartilhamento atualizado com sucesso", + "updateError": "Falha ao atualizar compartilhamento", + "filesUpdateSuccess": "Arquivos atualizados com sucesso", + "filesUpdateError": "Falha ao atualizar arquivos", + "recipientsUpdateSuccess": "Destinatários atualizados com sucesso", + "recipientsUpdateError": "Falha ao atualizar destinatários", + "linkGenerateSuccess": "Link de compartilhamento gerado com sucesso", + "linkGenerateError": "Falha ao gerar link de compartilhamento", + "notifyLoading": "Enviando notificações...", + "notifySuccess": "Destinatários notificados com sucesso", + "notifyError": "Falha ao notificar destinatários" + }, "shares": { "errors": { "loadFailed": "Falha ao carregar compartilhamentos", @@ -539,6 +502,64 @@ }, "pageTitle": "Compartilhamentos" }, + "sharesTable": { + "ariaLabel": "Tabela de compartilhamentos", + "never": "Nunca", + "columns": { + "name": "NOME", + "createdAt": "CRIADO EM", + "expiresAt": "EXPIRA EM", + "status": "STATUS", + "security": "SEGURANÇA", + "files": "ARQUIVOS", + "recipients": "DESTINATÁRIOS", + "actions": "AÇÕES" + }, + "status": { + "neverExpires": "Nunca Expira", + "active": "Ativo", + "expired": "Expirado" + }, + "security": { + "protected": "Protegido", + "public": "Público" + }, + "filesCount": "arquivos", + "recipientsCount": "destinatários", + "actions": { + "menu": "Menu de ações do compartilhamento", + "edit": "Editar", + "manageFiles": "Gerenciar Arquivos", + "manageRecipients": "Gerenciar Destinatários", + "viewDetails": "Ver Detalhes", + "generateLink": "Gerar Link", + "editLink": "Editar Link", + "copyLink": "Copiar Link", + "notifyRecipients": "Notificar Destinatários", + "delete": "Excluir" + } + }, + "storageUsage": { + "title": "Uso de Armazenamento", + "ariaLabel": "Barra de progresso do uso de armazenamento", + "used": "usado", + "available": "disponível" + }, + "theme": { + "toggle": "Alternar tema", + "light": "Claro", + "dark": "Escuro", + "system": "Sistema" + }, + "uploadFile": { + "title": "Enviar Arquivo", + "selectFile": "Clique para selecionar um arquivo", + "preview": "Pré-visualização", + "uploadProgress": "Progresso do upload", + "upload": "Enviar", + "success": "Arquivo enviado com sucesso", + "error": "Falha ao enviar arquivo" + }, "users": { "modes": { "create": "criar", @@ -608,29 +629,16 @@ "userr": "Usuário" } }, - "logo": { - "labels": { - "appLogo": "Logo do Aplicativo" - }, - "buttons": { - "upload": "Enviar Logo", - "remove": "Remover Logo" - }, - "messages": { - "uploadSuccess": "Logo enviado com sucesso", - "removeSuccess": "Logo removido com sucesso" - }, - "errors": { - "uploadFailed": "Falha ao enviar logo", - "removeFailed": "Falha ao remover logo" - } - }, - "navbar": { - "logoAlt": "Logo do Aplicativo", - "profileMenu": "Menu do Perfil", - "profile": "Perfil", - "settings": "Configurações", - "usersManagement": "Gerenciar Usuários", - "logout": "Sair" + "validation": { + "invalidEmail": "Endereço de email inválido", + "passwordMinLength": "A senha deve ter pelo menos 6 caracteres", + "firstNameRequired": "Nome é obrigatório", + "lastNameRequired": "Sobrenome é obrigatório", + "usernameLength": "Nome de usuário deve ter pelo menos 3 caracteres", + "usernameSpaces": "Nome de usuário não pode conter espaços", + "passwordLength": "A senha deve ter pelo menos 8 caracteres", + "passwordsMatch": "As senhas não coincidem", + "emailRequired": "Email é obrigatório", + "passwordRequired": "Senha é obrigatória" } -} \ No newline at end of file +} diff --git a/apps/web/src/locales/ru-RU.json b/apps/web/messages/ru-RU.json similarity index 97% rename from apps/web/src/locales/ru-RU.json rename to apps/web/messages/ru-RU.json index 767dfbe..ca62fdd 100644 --- a/apps/web/src/locales/ru-RU.json +++ b/apps/web/messages/ru-RU.json @@ -1,58 +1,4 @@ { - "login": { - "welcome": "Добро пожаловать", - "signInToContinue": "Войдите, чтобы продолжить", - "emailLabel": "Адрес электронной почты", - "emailPlaceholder": "Введите вашу электронную почту", - "passwordLabel": "Пароль", - "passwordPlaceholder": "Введите ваш пароль", - "signIn": "Войти", - "signingIn": "Вход...", - "forgotPassword": "Забыли пароль?", - "pageTitle": "Вход" - }, - "errors": { - "invalidCredentials": "Неверный адрес электронной почты или пароль", - "userNotFound": "Пользователь не найден", - "accountLocked": "Аккаунт заблокирован. Пожалуйста, попробуйте позже", - "unexpectedError": "Произошла непредвиденная ошибка. Пожалуйста, попробуйте еще раз" - }, - "validation": { - "invalidEmail": "Неверный адрес электронной почты", - "passwordMinLength": "Пароль должен содержать не менее 6 символов", - "firstNameRequired": "Имя обязательно", - "lastNameRequired": "Фамилия обязательна", - "usernameLength": "Имя пользователя должно содержать не менее 3 символов", - "usernameSpaces": "Имя пользователя не может содержать пробелов", - "passwordLength": "Пароль должен содержать не менее 8 символов", - "passwordsMatch": "Пароли не совпадают" - }, - "fileSelector": { - "availableFiles": "Доступные файлы ({{count}})", - "shareFiles": "Поделиться файлами ({{count}})", - "searchPlaceholder": "Поиск файлов...", - "noMatchingFiles": "Нет файлов, соответствующих запросу", - "noAvailableFiles": "Нет доступных файлов", - "noFilesInShare": "Нет файлов для совместного использования", - "saveChanges": "Сохранить изменения" - }, - "recipientSelector": { - "emailPlaceholder": "Введите электронную почту получателя", - "add": "Добавить", - "recipients": "Получатели ({{count}})", - "notifyAll": "Уведомить всех", - "noRecipients": "Пока нет добавленных получателей", - "addSuccess": "Получатель успешно добавлен", - "addError": "Не удалось добавить получателя", - "removeSuccess": "Получатель успешно удалён", - "removeError": "Не удалось удалить получателя", - "sendingNotifications": "Отправка уведомлений...", - "notifySuccess": "Получатели успешно уведомлены", - "notifyError": "Не удалось уведомить получателей" - }, - "navigation": { - "dashboard": "Панель управления" - }, "common": { "loading": "Загрузка, пожалуйста, подождите...", "cancel": "Отмена", @@ -78,6 +24,22 @@ "success": "Общий доступ успешно создан", "error": "Не удалось создать общий доступ" }, + "dashboard": { + "loadError": "Ошибка загрузки данных панели управления", + "linkCopied": "Ссылка скопирована в буфер обмена", + "pageTitle": "Панель управления", + "breadcrumb": "Панель управления" + }, + "emptyState": { + "noFiles": "Файлы еще не загружены", + "uploadFile": "Загрузить файл" + }, + "errors": { + "invalidCredentials": "Неверный адрес электронной почты или пароль", + "userNotFound": "Пользователь не найден", + "accountLocked": "Аккаунт заблокирован. Пожалуйста, попробуйте позже", + "unexpectedError": "Произошла непредвиденная ошибка. Пожалуйста, попробуйте еще раз" + }, "fileActions": { "editFile": "Редактировать файл", "nameLabel": "Имя", @@ -86,9 +48,16 @@ "descriptionLabel": "Описание", "descriptionPlaceholder": "Введите описание файла", "deleteFile": "Удалить файл", - "deleteConfirmation": "Вы уверены, что хотите удалить \"{{fileName}}\"?", + "deleteConfirmation": "Вы уверены, что хотите удалить ?", "deleteWarning": "Это действие необратимо." }, + "fileManager": { + "downloadError": "Ошибка скачивания файла", + "updateSuccess": "Файл успешно обновлен", + "updateError": "Ошибка при обновлении файла", + "deleteSuccess": "Файл успешно удален", + "deleteError": "Ошибка при удалении файла" + }, "filePreview": { "loading": "Загрузка предпросмотра...", "notAvailable": "Предпросмотр недоступен", @@ -98,68 +67,21 @@ "loadError": "Ошибка загрузки предпросмотра", "downloadError": "Ошибка скачивания файла" }, - "generateShareLink": { - "generateTitle": "Создать ссылку для общего доступа", - "updateTitle": "Обновить ссылку для общего доступа", - "generateDescription": "Создайте ссылку для обмена файлами", - "updateDescription": "Обновите псевдоним для этой ссылки", - "aliasPlaceholder": "Введите псевдоним", - "linkReady": "Ваша ссылка готова:", - "generateButton": "Создать ссылку", - "updateButton": "Обновить ссылку", - "copyButton": "Скопировать ссылку", - "success": "Ссылка успешно создана", - "error": "Не удалось создать ссылку", - "copied": "Ссылка скопирована в буфер обмена" + "fileSelector": { + "availableFiles": "Доступные файлы ({{count}})", + "shareFiles": "Поделиться файлами ({{count}})", + "searchPlaceholder": "Поиск файлов...", + "noMatchingFiles": "Нет файлов, соответствующих запросу", + "noAvailableFiles": "Нет доступных файлов", + "noFilesInShare": "Нет файлов для совместного использования", + "saveChanges": "Сохранить изменения" }, - "shareActions": { - "deleteTitle": "Удалить общий доступ", - "deleteConfirmation": "Вы уверены, что хотите удалить этот общий доступ? Это действие необратимо.", - "editTitle": "Редактировать общий доступ", - "nameLabel": "Название общего доступа", - "expirationLabel": "Дата истечения", - "expirationPlaceholder": "MM/DD/YYYY ЧЧ:ММ", - "maxViewsLabel": "Максимальное количество просмотров", - "maxViewsPlaceholder": "Оставьте пустым для неограниченного доступа", - "passwordProtection": "Защищено паролем", - "passwordLabel": "Пароль", - "passwordPlaceholder": "Введите пароль", - "newPasswordLabel": "Новый пароль (оставьте пустым, чтобы сохранить текущий)", - "newPasswordPlaceholder": "Введите новый пароль", - "manageFilesTitle": "Управление файлами", - "manageRecipientsTitle": "Управление получателями", - "editSuccess": "Общий доступ успешно обновлён", - "editError": "Ошибка при обновлении общего доступа" - }, - "shareDetails": { - "title": "Детали общего доступа", - "subtitle": "Подробная информация об этом общем доступе", - "basicInfo": "Основная информация", - "name": "Название", - "untitled": "Без названия", - "views": "Просмотры", - "dates": "Даты", - "created": "Создано", - "expires": "Истекает", - "never": "Никогда", - "security": "Безопасность", - "passwordProtected": "Защищено паролем", - "publicAccess": "Публичный доступ", - "maxViews": "Максимум просмотров: {{count}}", - "files": "Файлы ({{count}})", - "recipients": "Получатели ({{count}})", - "notAvailable": "Н/Д", - "invalidDate": "Неверная дата", - "loadError": "Ошибка загрузки деталей общего доступа" - }, - "uploadFile": { - "title": "Загрузить файл", - "selectFile": "Нажмите, чтобы выбрать файл", - "preview": "Предпросмотр", - "uploadProgress": "Прогресс загрузки", - "upload": "Загрузить", - "success": "Файл успешно загружен", - "error": "Не удалось загрузить файл" + "files": { + "title": "Все файлы", + "uploadFile": "Загрузить файл", + "loadError": "Ошибка загрузки файлов", + "pageTitle": "Мои файлы", + "breadcrumb": "Мои файлы" }, "filesTable": { "ariaLabel": "Таблица файлов", @@ -179,119 +101,10 @@ "delete": "Удалить" } }, - "sharesTable": { - "ariaLabel": "Таблица общего доступа", - "never": "Никогда", - "columns": { - "name": "ИМЯ", - "createdAt": "СОЗДАНО", - "expiresAt": "ИСТЕКАЕТ", - "status": "СТАТУС", - "security": "БЕЗОПАСНОСТЬ", - "files": "ФАЙЛЫ", - "recipients": "ПОЛУЧАТЕЛИ", - "actions": "ДЕЙСТВИЯ" - }, - "status": { - "neverExpires": "Не истекает", - "active": "Активно", - "expired": "Истекло" - }, - "security": { - "protected": "Защищено", - "public": "Публично" - }, - "filesCount": "{{count}} файлов", - "recipientsCount": "{{count}} получателей", - "actions": { - "menu": "Меню действий общего доступа", - "edit": "Редактировать", - "manageFiles": "Управление файлами", - "manageRecipients": "Управление получателями", - "viewDetails": "Просмотреть детали", - "generateLink": "Создать ссылку", - "editLink": "Редактировать ссылку", - "copyLink": "Скопировать ссылку", - "notifyRecipients": "Уведомить получателей", - "delete": "Удалить" - } - }, "footer": { "poweredBy": "При поддержке", "kyanHomepage": "Домашняя страница Kyantech" }, - "fileManager": { - "downloadError": "Ошибка скачивания файла", - "updateSuccess": "Файл успешно обновлен", - "updateError": "Ошибка при обновлении файла", - "deleteSuccess": "Файл успешно удален", - "deleteError": "Ошибка при удалении файла" - }, - "shareManager": { - "deleteSuccess": "Общий доступ успешно удален", - "deleteError": "Ошибка при удалении общего доступа", - "updateSuccess": "Общий доступ успешно обновлен", - "updateError": "Ошибка при обновлении общего доступа", - "filesUpdateSuccess": "Файлы успешно обновлены", - "filesUpdateError": "Ошибка при обновлении файлов", - "recipientsUpdateSuccess": "Получатели успешно обновлены", - "recipientsUpdateError": "Ошибка при обновлении получателей", - "linkGenerateSuccess": "Ссылка для общего доступа успешно создана", - "linkGenerateError": "Ошибка при создании ссылки для общего доступа", - "notifyLoading": "Отправка уведомлений...", - "notifySuccess": "Получатели успешно уведомлены", - "notifyError": "Ошибка при уведомлении получателей" - }, - "quickAccess": { - "files": { - "title": "Мои файлы", - "description": "Доступ и управление загруженными файлами" - }, - "shares": { - "title": "Мои общие доступы", - "description": "Просмотр и управление файлами для совместного использования" - } - }, - "recentFiles": { - "title": "Последние загрузки", - "viewAll": "Показать все", - "uploadFile": "Загрузить файл", - "noFiles": "Файлы еще не загружены" - }, - "recentShares": { - "title": "Последние общие доступы", - "viewAll": "Показать все", - "createShare": "Создать общий доступ", - "noShares": "Общие доступы еще не созданы", - "createFirst": "Создайте ваш первый общий доступ" - }, - "storageUsage": { - "title": "Использование хранилища", - "ariaLabel": "Индикатор использования хранилища", - "used": "Использовано: {{size}}", - "available": "Доступно: {{size}}" - }, - "dashboard": { - "loadError": "Ошибка загрузки данных панели управления", - "linkCopied": "Ссылка скопирована в буфер обмена", - "pageTitle": "Панель управления", - "breadcrumb": "Панель управления" - }, - "emptyState": { - "noFiles": "Файлы еще не загружены", - "uploadFile": "Загрузить файл" - }, - "files": { - "title": "Все файлы", - "uploadFile": "Загрузить файл", - "loadError": "Ошибка загрузки файлов", - "pageTitle": "Мои файлы", - "breadcrumb": "Мои файлы" - }, - "searchBar": { - "placeholder": "Поиск файлов...", - "results": "Найдено {{filtered}} из {{total}} файлов" - }, "forgotPassword": { "emailLabel": "Адрес электронной почты", "emailPlaceholder": "Введите ваш адрес электронной почты", @@ -303,6 +116,20 @@ "resetInstructions": "Инструкции по сбросу отправлены на вашу электронную почту", "pageTitle": "Забыли пароль" }, + "generateShareLink": { + "generateTitle": "Создать ссылку для общего доступа", + "updateTitle": "Обновить ссылку для общего доступа", + "generateDescription": "Создайте ссылку для обмена файлами", + "updateDescription": "Обновите псевдоним для этой ссылки", + "aliasPlaceholder": "Введите псевдоним", + "linkReady": "Ваша ссылка готова:", + "generateButton": "Создать ссылку", + "updateButton": "Обновить ссылку", + "copyButton": "Скопировать ссылку", + "success": "Ссылка успешно создана", + "error": "Не удалось создать ссылку", + "copied": "Ссылка скопирована в буфер обмена" + }, "home": { "description": "Открытая альтернатива WeTransfer. Делитесь файлами безопасно, без отслеживания и ограничений.", "documentation": "Документация", @@ -314,6 +141,46 @@ }, "pageTitle": "Главная" }, + "login": { + "welcome": "Добро пожаловать в", + "signInToContinue": "Войдите, чтобы продолжить", + "emailLabel": "Адрес электронной почты", + "emailPlaceholder": "Введите вашу электронную почту", + "passwordLabel": "Пароль", + "passwordPlaceholder": "Введите ваш пароль", + "signIn": "Войти", + "signingIn": "Вход...", + "forgotPassword": "Забыли пароль?", + "pageTitle": "Вход" + }, + "logo": { + "labels": { + "appLogo": "Логотип приложения" + }, + "buttons": { + "upload": "Загрузить логотип", + "remove": "Удалить логотип" + }, + "messages": { + "uploadSuccess": "Логотип успешно загружен", + "removeSuccess": "Логотип успешно удален" + }, + "errors": { + "uploadFailed": "Ошибка загрузки логотипа", + "removeFailed": "Ошибка удаления логотипа" + } + }, + "navbar": { + "logoAlt": "Логотип приложения", + "profileMenu": "Меню профиля", + "profile": "Профиль", + "settings": "Настройки", + "usersManagement": "Управление пользователями", + "logout": "Выйти" + }, + "navigation": { + "dashboard": "Панель управления" + }, "profile": { "password": { "title": "Изменить пароль", @@ -356,6 +223,43 @@ }, "pageTitle": "Профиль" }, + "quickAccess": { + "files": { + "title": "Мои файлы", + "description": "Доступ и управление загруженными файлами" + }, + "shares": { + "title": "Мои общие доступы", + "description": "Просмотр и управление файлами для совместного использования" + } + }, + "recentFiles": { + "title": "Последние загрузки", + "viewAll": "Показать все", + "uploadFile": "Загрузить файл", + "noFiles": "Файлы еще не загружены" + }, + "recentShares": { + "title": "Последние общие доступы", + "viewAll": "Показать все", + "createShare": "Создать общий доступ", + "noShares": "Общие доступы еще не созданы", + "createFirst": "Создайте ваш первый общий доступ" + }, + "recipientSelector": { + "emailPlaceholder": "Введите электронную почту получателя", + "add": "Добавить", + "recipients": "Получатели ({{count}})", + "notifyAll": "Уведомить всех", + "noRecipients": "Пока нет добавленных получателей", + "addSuccess": "Получатель успешно добавлен", + "addError": "Не удалось добавить получателя", + "removeSuccess": "Получатель успешно удалён", + "removeError": "Не удалось удалить получателя", + "sendingNotifications": "Отправка уведомлений...", + "notifySuccess": "Получатели успешно уведомлены", + "notifyError": "Не удалось уведомить получателей" + }, "resetPassword": { "pageTitle": "Сбросить пароль", "header": { @@ -379,6 +283,10 @@ "invalidToken": "Неверный или отсутствующий токен сброса" } }, + "searchBar": { + "placeholder": "Поиск файлов...", + "results": "Найдено {{filtered}} из {{total}} файлов" + }, "settings": { "groups": { "defaultDescription": "Настройки конфигурации", @@ -513,6 +421,61 @@ }, "pageTitle": "Общий доступ" }, + "shareActions": { + "deleteTitle": "Удалить общий доступ", + "deleteConfirmation": "Вы уверены, что хотите удалить этот общий доступ? Это действие необратимо.", + "editTitle": "Редактировать общий доступ", + "nameLabel": "Название общего доступа", + "expirationLabel": "Дата истечения", + "expirationPlaceholder": "MM/DD/YYYY ЧЧ:ММ", + "maxViewsLabel": "Максимальное количество просмотров", + "maxViewsPlaceholder": "Оставьте пустым для неограниченного доступа", + "passwordProtection": "Защищено паролем", + "passwordLabel": "Пароль", + "passwordPlaceholder": "Введите пароль", + "newPasswordLabel": "Новый пароль (оставьте пустым, чтобы сохранить текущий)", + "newPasswordPlaceholder": "Введите новый пароль", + "manageFilesTitle": "Управление файлами", + "manageRecipientsTitle": "Управление получателями", + "editSuccess": "Общий доступ успешно обновлён", + "editError": "Ошибка при обновлении общего доступа" + }, + "shareDetails": { + "title": "Детали общего доступа", + "subtitle": "Подробная информация об этом общем доступе", + "basicInfo": "Основная информация", + "name": "Название", + "untitled": "Без названия", + "views": "Просмотры", + "dates": "Даты", + "created": "Создано", + "expires": "Истекает", + "never": "Никогда", + "security": "Безопасность", + "passwordProtected": "Защищено паролем", + "publicAccess": "Публичный доступ", + "maxViews": "Максимум просмотров:", + "files": "Файлы", + "recipients": "Получатели", + "notAvailable": "Н/Д", + "invalidDate": "Неверная дата", + "loadError": "Ошибка загрузки деталей общего доступа" + }, + "shareManager": { + "deleteSuccess": "Общий доступ успешно удален", + "deleteError": "Ошибка при удалении общего доступа", + "updateSuccess": "Общий доступ успешно обновлен", + "updateError": "Ошибка при обновлении общего доступа", + "filesUpdateSuccess": "Файлы успешно обновлены", + "filesUpdateError": "Ошибка при обновлении файлов", + "recipientsUpdateSuccess": "Получатели успешно обновлены", + "recipientsUpdateError": "Ошибка при обновлении получателей", + "linkGenerateSuccess": "Ссылка для общего доступа успешно создана", + "linkGenerateError": "Ошибка при создании ссылки для общего доступа", + "notifyLoading": "Отправка уведомлений...", + "notifySuccess": "Получатели успешно уведомлены", + "notifyError": "Ошибка при уведомлении получателей" + }, "shares": { "errors": { "loadFailed": "Ошибка загрузки общих доступов", @@ -539,6 +502,64 @@ }, "pageTitle": "Общие доступы" }, + "sharesTable": { + "ariaLabel": "Таблица общего доступа", + "never": "Никогда", + "columns": { + "name": "ИМЯ", + "createdAt": "СОЗДАНО", + "expiresAt": "ИСТЕКАЕТ", + "status": "СТАТУС", + "security": "БЕЗОПАСНОСТЬ", + "files": "ФАЙЛЫ", + "recipients": "ПОЛУЧАТЕЛИ", + "actions": "ДЕЙСТВИЯ" + }, + "status": { + "neverExpires": "Не истекает", + "active": "Активно", + "expired": "Истекло" + }, + "security": { + "protected": "Защищено", + "public": "Публично" + }, + "filesCount": "файлов", + "recipientsCount": "получателей", + "actions": { + "menu": "Меню действий общего доступа", + "edit": "Редактировать", + "manageFiles": "Управление файлами", + "manageRecipients": "Управление получателями", + "viewDetails": "Просмотреть детали", + "generateLink": "Создать ссылку", + "editLink": "Редактировать ссылку", + "copyLink": "Скопировать ссылку", + "notifyRecipients": "Уведомить получателей", + "delete": "Удалить" + } + }, + "storageUsage": { + "title": "Использование хранилища", + "ariaLabel": "Индикатор использования хранилища", + "used": "Использовано", + "available": "Доступно" + }, + "theme": { + "toggle": "Переключить тему", + "light": "Светлая", + "dark": "Тёмная", + "system": "Системная" + }, + "uploadFile": { + "title": "Загрузить файл", + "selectFile": "Нажмите, чтобы выбрать файл", + "preview": "Предпросмотр", + "uploadProgress": "Прогресс загрузки", + "upload": "Загрузить", + "success": "Файл успешно загружен", + "error": "Не удалось загрузить файл" + }, "users": { "modes": { "create": "создать", @@ -608,29 +629,16 @@ "userr": "Пользователь" } }, - "logo": { - "labels": { - "appLogo": "Логотип приложения" - }, - "buttons": { - "upload": "Загрузить логотип", - "remove": "Удалить логотип" - }, - "messages": { - "uploadSuccess": "Логотип успешно загружен", - "removeSuccess": "Логотип успешно удален" - }, - "errors": { - "uploadFailed": "Ошибка загрузки логотипа", - "removeFailed": "Ошибка удаления логотипа" - } - }, - "navbar": { - "logoAlt": "Логотип приложения", - "profileMenu": "Меню профиля", - "profile": "Профиль", - "settings": "Настройки", - "usersManagement": "Управление пользователями", - "logout": "Выйти" + "validation": { + "invalidEmail": "Неверный адрес электронной почты", + "passwordMinLength": "Пароль должен содержать не менее 6 символов", + "firstNameRequired": "Имя обязательно", + "lastNameRequired": "Фамилия обязательна", + "usernameLength": "Имя пользователя должно содержать не менее 3 символов", + "usernameSpaces": "Имя пользователя не может содержать пробелов", + "passwordLength": "Пароль должен содержать не менее 8 символов", + "passwordsMatch": "Пароли не совпадают", + "emailRequired": "Требуется электронная почта", + "passwordRequired": "Требуется пароль" } -} \ No newline at end of file +} diff --git a/apps/web/src/locales/tr-TR.json b/apps/web/messages/tr-TR.json similarity index 97% rename from apps/web/src/locales/tr-TR.json rename to apps/web/messages/tr-TR.json index 81881e7..1bc42ec 100644 --- a/apps/web/src/locales/tr-TR.json +++ b/apps/web/messages/tr-TR.json @@ -1,58 +1,4 @@ { - "login": { - "welcome": "Hoş geldiniz", - "signInToContinue": "Devam etmek için oturum açın", - "emailLabel": "E-posta Adresi", - "emailPlaceholder": "E-posta adresinizi girin", - "passwordLabel": "Şifre", - "passwordPlaceholder": "Şifrenizi girin", - "signIn": "Oturum Aç", - "signingIn": "Oturum açılıyor...", - "forgotPassword": "Şifrenizi mi unuttunuz?", - "pageTitle": "Giriş" - }, - "errors": { - "invalidCredentials": "Geçersiz e-posta veya şifre", - "userNotFound": "Kullanıcı bulunamadı", - "accountLocked": "Hesap kilitlendi. Lütfen daha sonra tekrar deneyin", - "unexpectedError": "Beklenmeyen bir hata oluştu. Lütfen tekrar deneyin" - }, - "validation": { - "invalidEmail": "Geçersiz e-posta adresi", - "passwordMinLength": "Şifre en az 6 karakter olmalıdır", - "firstNameRequired": "Ad gerekli", - "lastNameRequired": "Soyad gerekli", - "usernameLength": "Kullanıcı adı en az 3 karakter olmalıdır", - "usernameSpaces": "Kullanıcı adında boşluk olamaz", - "passwordLength": "Şifre en az 8 karakter olmalıdır", - "passwordsMatch": "Şifreler eşleşmiyor" - }, - "fileSelector": { - "availableFiles": "Kullanılabilir Dosyalar ({{count}})", - "shareFiles": "Dosyaları Paylaş ({{count}})", - "searchPlaceholder": "Dosya ara...", - "noMatchingFiles": "Eşleşen dosya bulunamadı", - "noAvailableFiles": "Kullanılabilir dosya yok", - "noFilesInShare": "Paylaşımda dosya yok", - "saveChanges": "Değişiklikleri Kaydet" - }, - "recipientSelector": { - "emailPlaceholder": "Alıcının e-postasını girin", - "add": "Ekle", - "recipients": "Alıcılar ({{count}})", - "notifyAll": "Hepsini Bildir", - "noRecipients": "Henüz alıcı eklenmedi", - "addSuccess": "Alıcı başarıyla eklendi", - "addError": "Alıcı eklenemedi", - "removeSuccess": "Alıcı başarıyla kaldırıldı", - "removeError": "Alıcı kaldırılamadı", - "sendingNotifications": "Bildirimler gönderiliyor...", - "notifySuccess": "Alıcılar başarıyla bildirildi", - "notifyError": "Alıcılara bildirim gönderilemedi" - }, - "navigation": { - "dashboard": "Gösterge Paneli" - }, "common": { "loading": "Yükleniyor, lütfen bekleyin...", "cancel": "İptal", @@ -78,6 +24,22 @@ "success": "Paylaşım başarıyla oluşturuldu", "error": "Paylaşım oluşturulamadı" }, + "dashboard": { + "loadError": "Gösterge paneli verileri yüklenemedi", + "linkCopied": "Bağlantı panoya kopyalandı", + "pageTitle": "Gösterge Paneli", + "breadcrumb": "Gösterge Paneli" + }, + "emptyState": { + "noFiles": "Henüz dosya yüklenmedi", + "uploadFile": "Dosya Yükle" + }, + "errors": { + "invalidCredentials": "Geçersiz e-posta veya şifre", + "userNotFound": "Kullanıcı bulunamadı", + "accountLocked": "Hesap kilitlendi. Lütfen daha sonra tekrar deneyin", + "unexpectedError": "Beklenmeyen bir hata oluştu. Lütfen tekrar deneyin" + }, "fileActions": { "editFile": "Dosyayı Düzenle", "nameLabel": "Ad", @@ -86,9 +48,16 @@ "descriptionLabel": "Açıklama", "descriptionPlaceholder": "Dosya açıklamasını girin", "deleteFile": "Dosyayı Sil", - "deleteConfirmation": "\"{{fileName}}\" dosyasını silmek istediğinize emin misiniz?", + "deleteConfirmation": " dosyasını silmek istediğinize emin misiniz?", "deleteWarning": "Bu işlem geri alınamaz." }, + "fileManager": { + "downloadError": "Dosya indirilemedi", + "updateSuccess": "Dosya başarıyla güncellendi", + "updateError": "Dosya güncellenemedi", + "deleteSuccess": "Dosya başarıyla silindi", + "deleteError": "Dosya silinemedi" + }, "filePreview": { "loading": "Önizleme yükleniyor...", "notAvailable": "Önizleme mevcut değil", @@ -98,68 +67,21 @@ "loadError": "Önizleme yüklenemedi", "downloadError": "Dosya indirilemedi" }, - "generateShareLink": { - "generateTitle": "Paylaşım Bağlantısı Oluştur", - "updateTitle": "Paylaşım Bağlantısını Güncelle", - "generateDescription": "Dosyalarınızı paylaşmak için bir bağlantı oluşturun", - "updateDescription": "Bu paylaşım bağlantısı için takma ad güncelleyin", - "aliasPlaceholder": "Takma ad girin", - "linkReady": "Paylaşım bağlantınız hazır:", - "generateButton": "Bağlantıyı Oluştur", - "updateButton": "Bağlantıyı Güncelle", - "copyButton": "Bağlantıyı Kopyala", - "success": "Bağlantı başarıyla oluşturuldu", - "error": "Bağlantı oluşturulamadı", - "copied": "Bağlantı panoya kopyalandı" + "fileSelector": { + "availableFiles": "Kullanılabilir Dosyalar ({{count}})", + "shareFiles": "Dosyaları Paylaş ({{count}})", + "searchPlaceholder": "Dosya ara...", + "noMatchingFiles": "Eşleşen dosya bulunamadı", + "noAvailableFiles": "Kullanılabilir dosya yok", + "noFilesInShare": "Paylaşımda dosya yok", + "saveChanges": "Değişiklikleri Kaydet" }, - "shareActions": { - "deleteTitle": "Paylaşımı Sil", - "deleteConfirmation": "Bu paylaşımı silmek istediğinize emin misiniz? Bu işlem geri alınamaz.", - "editTitle": "Paylaşımı Düzenle", - "nameLabel": "Paylaşım Adı", - "expirationLabel": "Son Kullanma Tarihi", - "expirationPlaceholder": "MM/GG/YYYY SS:DD", - "maxViewsLabel": "Maksimum Görüntüleme", - "maxViewsPlaceholder": "Sınırsız için boş bırakın", - "passwordProtection": "Şifre Korumalı", - "passwordLabel": "Şifre", - "passwordPlaceholder": "Şifreyi girin", - "newPasswordLabel": "Yeni Şifre (mevcut şifreyi korumak için boş bırakın)", - "newPasswordPlaceholder": "Yeni şifreyi girin", - "manageFilesTitle": "Dosyaları Yönet", - "manageRecipientsTitle": "Alıcıları Yönet", - "editSuccess": "Paylaşım başarıyla güncellendi", - "editError": "Paylaşım güncellenemedi" - }, - "shareDetails": { - "title": "Paylaşım Detayları", - "subtitle": "Bu paylaşım hakkında ayrıntılı bilgi", - "basicInfo": "Temel Bilgiler", - "name": "Ad", - "untitled": "Adsız", - "views": "Görüntüleme", - "dates": "Tarihler", - "created": "Oluşturuldu", - "expires": "Sona Eriyor", - "never": "Asla", - "security": "Güvenlik", - "passwordProtected": "Şifre ile Korunuyor", - "publicAccess": "Genel Erişim", - "maxViews": "Maksimum Görüntüleme: {{count}}", - "files": "Dosyalar ({{count}})", - "recipients": "Alıcılar ({{count}})", - "notAvailable": "Mevcut Değil", - "invalidDate": "Geçersiz tarih", - "loadError": "Paylaşım detayları yüklenemedi" - }, - "uploadFile": { - "title": "Dosya Yükle", - "selectFile": "Dosya seçmek için tıklayın", - "preview": "Önizleme", - "uploadProgress": "Yükleme İlerlemesi", - "upload": "Yükle", - "success": "Dosya başarıyla yüklendi", - "error": "Dosya yüklenemedi" + "files": { + "title": "Tüm Dosyalar", + "uploadFile": "Dosya Yükle", + "loadError": "Dosyalar yüklenemedi", + "pageTitle": "Benim Dosyalarım", + "breadcrumb": "Benim Dosyalarım" }, "filesTable": { "ariaLabel": "Dosya Tablosu", @@ -179,119 +101,10 @@ "delete": "Sil" } }, - "sharesTable": { - "ariaLabel": "Paylaşım Tablosu", - "never": "Asla", - "columns": { - "name": "Ad", - "createdAt": "Oluşturulma Tarihi", - "expiresAt": "Son Kullanma Tarihi", - "status": "Durum", - "security": "Güvenlik", - "files": "Dosyalar", - "recipients": "Alıcılar", - "actions": "İşlemler" - }, - "status": { - "neverExpires": "Sona Ermez", - "active": "Aktif", - "expired": "Sona Erdi" - }, - "security": { - "protected": "Korunuyor", - "public": "Genel" - }, - "filesCount": "{{count}} dosya", - "recipientsCount": "{{count}} alıcı", - "actions": { - "menu": "Paylaşım İşlem Menüsü", - "edit": "Düzenle", - "manageFiles": "Dosyaları Yönet", - "manageRecipients": "Alıcıları Yönet", - "viewDetails": "Detayları Görüntüle", - "generateLink": "Bağlantı Oluştur", - "editLink": "Bağlantıyı Düzenle", - "copyLink": "Bağlantıyı Kopyala", - "notifyRecipients": "Alıcıları Bildir", - "delete": "Sil" - } - }, "footer": { "poweredBy": "Tarafından destekleniyor:", "kyanHomepage": "Kyantech Ana Sayfası" }, - "fileManager": { - "downloadError": "Dosya indirilemedi", - "updateSuccess": "Dosya başarıyla güncellendi", - "updateError": "Dosya güncellenemedi", - "deleteSuccess": "Dosya başarıyla silindi", - "deleteError": "Dosya silinemedi" - }, - "shareManager": { - "deleteSuccess": "Paylaşım başarıyla silindi", - "deleteError": "Paylaşım silinemedi", - "updateSuccess": "Paylaşım başarıyla güncellendi", - "updateError": "Paylaşım güncellenemedi", - "filesUpdateSuccess": "Dosyalar başarıyla güncellendi", - "filesUpdateError": "Dosyalar güncellenemedi", - "recipientsUpdateSuccess": "Alıcılar başarıyla güncellendi", - "recipientsUpdateError": "Alıcılar güncellenemedi", - "linkGenerateSuccess": "Paylaşım bağlantısı başarıyla oluşturuldu", - "linkGenerateError": "Paylaşım bağlantısı oluşturulamadı", - "notifyLoading": "Bildirimler gönderiliyor...", - "notifySuccess": "Alıcılara başarıyla bildirildi", - "notifyError": "Alıcılara bildirim gönderilemedi" - }, - "quickAccess": { - "files": { - "title": "Benim Dosyalarım", - "description": "Yüklenen dosyalara erişin ve yönetin" - }, - "shares": { - "title": "Benim Paylaşımlarım", - "description": "Paylaşılan dosyaları görüntüleyin ve yönetin" - } - }, - "recentFiles": { - "title": "Son Yüklemeler", - "viewAll": "Tümünü Görüntüle", - "uploadFile": "Dosya Yükle", - "noFiles": "Henüz dosya yüklenmedi" - }, - "recentShares": { - "title": "Son Paylaşımlar", - "viewAll": "Tümünü Görüntüle", - "createShare": "Paylaşım Oluştur", - "noShares": "Henüz paylaşım oluşturulmadı", - "createFirst": "İlk paylaşımınızı oluşturun" - }, - "storageUsage": { - "title": "Depolama Kullanımı", - "ariaLabel": "Depolama kullanım ilerleme çubuğu", - "used": "{{size}} kullanıldı", - "available": "{{size}} kullanılabilir" - }, - "dashboard": { - "loadError": "Gösterge paneli verileri yüklenemedi", - "linkCopied": "Bağlantı panoya kopyalandı", - "pageTitle": "Gösterge Paneli", - "breadcrumb": "Gösterge Paneli" - }, - "emptyState": { - "noFiles": "Henüz dosya yüklenmedi", - "uploadFile": "Dosya Yükle" - }, - "files": { - "title": "Tüm Dosyalar", - "uploadFile": "Dosya Yükle", - "loadError": "Dosyalar yüklenemedi", - "pageTitle": "Benim Dosyalarım", - "breadcrumb": "Benim Dosyalarım" - }, - "searchBar": { - "placeholder": "Dosya ara...", - "results": "Toplam {{total}} dosya içinde {{filtered}} dosya bulundu" - }, "forgotPassword": { "emailLabel": "E-posta Adresi", "emailPlaceholder": "E-posta adresinizi girin", @@ -303,6 +116,20 @@ "resetInstructions": "Şifre sıfırlama talimatları e-posta adresinize gönderildi", "pageTitle": "Şifrenizi mi Unuttunuz?" }, + "generateShareLink": { + "generateTitle": "Paylaşım Bağlantısı Oluştur", + "updateTitle": "Paylaşım Bağlantısını Güncelle", + "generateDescription": "Dosyalarınızı paylaşmak için bir bağlantı oluşturun", + "updateDescription": "Bu paylaşım bağlantısı için takma ad güncelleyin", + "aliasPlaceholder": "Takma ad girin", + "linkReady": "Paylaşım bağlantınız hazır:", + "generateButton": "Bağlantıyı Oluştur", + "updateButton": "Bağlantıyı Güncelle", + "copyButton": "Bağlantıyı Kopyala", + "success": "Bağlantı başarıyla oluşturuldu", + "error": "Bağlantı oluşturulamadı", + "copied": "Bağlantı panoya kopyalandı" + }, "home": { "description": "WeTransfer'e açık kaynaklı alternatif. Takip veya kısıtlama olmadan dosyalarınızı güvenle paylaşın.", "documentation": "Belgelendirme", @@ -314,6 +141,46 @@ }, "pageTitle": "Ana Sayfa" }, + "login": { + "welcome": "Hoş geldiniz'e", + "signInToContinue": "Devam etmek için oturum açın", + "emailLabel": "E-posta Adresi", + "emailPlaceholder": "E-posta adresinizi girin", + "passwordLabel": "Şifre", + "passwordPlaceholder": "Şifrenizi girin", + "signIn": "Oturum Aç", + "signingIn": "Oturum açılıyor...", + "forgotPassword": "Şifrenizi mi unuttunuz?", + "pageTitle": "Giriş" + }, + "logo": { + "labels": { + "appLogo": "Uygulama Logosu" + }, + "buttons": { + "upload": "Logoyu Yükle", + "remove": "Logoyu Kaldır" + }, + "messages": { + "uploadSuccess": "Logo başarıyla yüklendi", + "removeSuccess": "Logo başarıyla kaldırıldı" + }, + "errors": { + "uploadFailed": "Logo yüklenemedi", + "removeFailed": "Logo kaldırılamadı" + } + }, + "navbar": { + "logoAlt": "Uygulama Logosu", + "profileMenu": "Profil Menüsü", + "profile": "Profil", + "settings": "Ayarlar", + "usersManagement": "Kullanıcı Yönetimi", + "logout": "Oturumu Kapat" + }, + "navigation": { + "dashboard": "Gösterge Paneli" + }, "profile": { "password": { "title": "Şifreyi Değiştir", @@ -356,6 +223,43 @@ }, "pageTitle": "Profil" }, + "quickAccess": { + "files": { + "title": "Benim Dosyalarım", + "description": "Yüklenen dosyalara erişin ve yönetin" + }, + "shares": { + "title": "Benim Paylaşımlarım", + "description": "Paylaşılan dosyaları görüntüleyin ve yönetin" + } + }, + "recentFiles": { + "title": "Son Yüklemeler", + "viewAll": "Tümünü Görüntüle", + "uploadFile": "Dosya Yükle", + "noFiles": "Henüz dosya yüklenmedi" + }, + "recentShares": { + "title": "Son Paylaşımlar", + "viewAll": "Tümünü Görüntüle", + "createShare": "Paylaşım Oluştur", + "noShares": "Henüz paylaşım oluşturulmadı", + "createFirst": "İlk paylaşımınızı oluşturun" + }, + "recipientSelector": { + "emailPlaceholder": "Alıcının e-postasını girin", + "add": "Ekle", + "recipients": "Alıcılar ({{count}})", + "notifyAll": "Hepsini Bildir", + "noRecipients": "Henüz alıcı eklenmedi", + "addSuccess": "Alıcı başarıyla eklendi", + "addError": "Alıcı eklenemedi", + "removeSuccess": "Alıcı başarıyla kaldırıldı", + "removeError": "Alıcı kaldırılamadı", + "sendingNotifications": "Bildirimler gönderiliyor...", + "notifySuccess": "Alıcılar başarıyla bildirildi", + "notifyError": "Alıcılara bildirim gönderilemedi" + }, "resetPassword": { "pageTitle": "Şifreyi Sıfırla", "header": { @@ -379,6 +283,10 @@ "invalidToken": "Geçersiz veya eksik sıfırlama belirteci" } }, + "searchBar": { + "placeholder": "Dosya ara...", + "results": "Toplam {{total}} dosya içinde {{filtered}} dosya bulundu" + }, "settings": { "groups": { "defaultDescription": "Yapılandırma seçenekleri", @@ -513,6 +421,61 @@ }, "pageTitle": "Paylaşım" }, + "shareActions": { + "deleteTitle": "Paylaşımı Sil", + "deleteConfirmation": "Bu paylaşımı silmek istediğinize emin misiniz? Bu işlem geri alınamaz.", + "editTitle": "Paylaşımı Düzenle", + "nameLabel": "Paylaşım Adı", + "expirationLabel": "Son Kullanma Tarihi", + "expirationPlaceholder": "MM/GG/YYYY SS:DD", + "maxViewsLabel": "Maksimum Görüntüleme", + "maxViewsPlaceholder": "Sınırsız için boş bırakın", + "passwordProtection": "Şifre Korumalı", + "passwordLabel": "Şifre", + "passwordPlaceholder": "Şifreyi girin", + "newPasswordLabel": "Yeni Şifre (mevcut şifreyi korumak için boş bırakın)", + "newPasswordPlaceholder": "Yeni şifreyi girin", + "manageFilesTitle": "Dosyaları Yönet", + "manageRecipientsTitle": "Alıcıları Yönet", + "editSuccess": "Paylaşım başarıyla güncellendi", + "editError": "Paylaşım güncellenemedi" + }, + "shareDetails": { + "title": "Paylaşım Detayları", + "subtitle": "Bu paylaşım hakkında ayrıntılı bilgi", + "basicInfo": "Temel Bilgiler", + "name": "Ad", + "untitled": "Adsız", + "views": "Görüntüleme", + "dates": "Tarihler", + "created": "Oluşturuldu", + "expires": "Sona Eriyor", + "never": "Asla", + "security": "Güvenlik", + "passwordProtected": "Şifre ile Korunuyor", + "publicAccess": "Genel Erişim", + "maxViews": "Maksimum Görüntüleme:", + "files": "Dosyala", + "recipients": "Alıcıla", + "notAvailable": "Mevcut Değil", + "invalidDate": "Geçersiz tarih", + "loadError": "Paylaşım detayları yüklenemedi" + }, + "shareManager": { + "deleteSuccess": "Paylaşım başarıyla silindi", + "deleteError": "Paylaşım silinemedi", + "updateSuccess": "Paylaşım başarıyla güncellendi", + "updateError": "Paylaşım güncellenemedi", + "filesUpdateSuccess": "Dosyalar başarıyla güncellendi", + "filesUpdateError": "Dosyalar güncellenemedi", + "recipientsUpdateSuccess": "Alıcılar başarıyla güncellendi", + "recipientsUpdateError": "Alıcılar güncellenemedi", + "linkGenerateSuccess": "Paylaşım bağlantısı başarıyla oluşturuldu", + "linkGenerateError": "Paylaşım bağlantısı oluşturulamadı", + "notifyLoading": "Bildirimler gönderiliyor...", + "notifySuccess": "Alıcılara başarıyla bildirildi", + "notifyError": "Alıcılara bildirim gönderilemedi" + }, "shares": { "errors": { "loadFailed": "Paylaşımlar yüklenemedi", @@ -539,6 +502,64 @@ }, "pageTitle": "Paylaşımlar" }, + "sharesTable": { + "ariaLabel": "Paylaşım Tablosu", + "never": "Asla", + "columns": { + "name": "Ad", + "createdAt": "Oluşturulma Tarihi", + "expiresAt": "Son Kullanma Tarihi", + "status": "Durum", + "security": "Güvenlik", + "files": "Dosyalar", + "recipients": "Alıcılar", + "actions": "İşlemler" + }, + "status": { + "neverExpires": "Sona Ermez", + "active": "Aktif", + "expired": "Sona Erdi" + }, + "security": { + "protected": "Korunuyor", + "public": "Genel" + }, + "filesCount": "dosya", + "recipientsCount": "alıcı", + "actions": { + "menu": "Paylaşım İşlem Menüsü", + "edit": "Düzenle", + "manageFiles": "Dosyaları Yönet", + "manageRecipients": "Alıcıları Yönet", + "viewDetails": "Detayları Görüntüle", + "generateLink": "Bağlantı Oluştur", + "editLink": "Bağlantıyı Düzenle", + "copyLink": "Bağlantıyı Kopyala", + "notifyRecipients": "Alıcıları Bildir", + "delete": "Sil" + } + }, + "storageUsage": { + "title": "Depolama Kullanımı", + "ariaLabel": "Depolama kullanım ilerleme çubuğu", + "used": "kullanıldı", + "available": "kullanılabilir" + }, + "theme": { + "toggle": "Temayı değiştir", + "light": "Açık", + "dark": "Koyu", + "system": "Sistem" + }, + "uploadFile": { + "title": "Dosya Yükle", + "selectFile": "Dosya seçmek için tıklayın", + "preview": "Önizleme", + "uploadProgress": "Yükleme İlerlemesi", + "upload": "Yükle", + "success": "Dosya başarıyla yüklendi", + "error": "Dosya yüklenemedi" + }, "users": { "modes": { "create": "Oluştur", @@ -608,29 +629,16 @@ "userr": "Kullanıcı" } }, - "logo": { - "labels": { - "appLogo": "Uygulama Logosu" - }, - "buttons": { - "upload": "Logoyu Yükle", - "remove": "Logoyu Kaldır" - }, - "messages": { - "uploadSuccess": "Logo başarıyla yüklendi", - "removeSuccess": "Logo başarıyla kaldırıldı" - }, - "errors": { - "uploadFailed": "Logo yüklenemedi", - "removeFailed": "Logo kaldırılamadı" - } - }, - "navbar": { - "logoAlt": "Uygulama Logosu", - "profileMenu": "Profil Menüsü", - "profile": "Profil", - "settings": "Ayarlar", - "usersManagement": "Kullanıcı Yönetimi", - "logout": "Oturumu Kapat" + "validation": { + "invalidEmail": "Geçersiz e-posta adresi", + "passwordMinLength": "Şifre en az 6 karakter olmalıdır", + "firstNameRequired": "Ad gerekli", + "lastNameRequired": "Soyad gerekli", + "usernameLength": "Kullanıcı adı en az 3 karakter olmalıdır", + "usernameSpaces": "Kullanıcı adında boşluk olamaz", + "passwordLength": "Şifre en az 8 karakter olmalıdır", + "passwordsMatch": "Şifreler eşleşmiyor", + "emailRequired": "E-posta gerekli", + "passwordRequired": "Şifre gerekli" } -} \ No newline at end of file +} diff --git a/apps/web/src/locales/zh-CN.json b/apps/web/messages/zh-CN.json similarity index 97% rename from apps/web/src/locales/zh-CN.json rename to apps/web/messages/zh-CN.json index 19a4394..f6d4aaf 100644 --- a/apps/web/src/locales/zh-CN.json +++ b/apps/web/messages/zh-CN.json @@ -1,58 +1,4 @@ { - "login": { - "welcome": "欢迎", - "signInToContinue": "请登录以继续", - "emailLabel": "电子邮件地址", - "emailPlaceholder": "请输入您的电子邮件", - "passwordLabel": "密码", - "passwordPlaceholder": "请输入您的密码", - "signIn": "登录", - "signingIn": "正在登录...", - "forgotPassword": "忘记密码?", - "pageTitle": "登录" - }, - "errors": { - "invalidCredentials": "电子邮件或密码错误", - "userNotFound": "未找到用户", - "accountLocked": "账户已锁定。请稍后再试", - "unexpectedError": "发生意外错误。请重试" - }, - "validation": { - "invalidEmail": "无效的电子邮件地址", - "passwordMinLength": "密码至少需要6个字符", - "firstNameRequired": "名字为必填项", - "lastNameRequired": "姓氏为必填项", - "usernameLength": "用户名至少需要3个字符", - "usernameSpaces": "用户名不能包含空格", - "passwordLength": "密码至少需要8个字符", - "passwordsMatch": "密码不匹配" - }, - "fileSelector": { - "availableFiles": "可用文件 ({{count}})", - "shareFiles": "共享文件 ({{count}})", - "searchPlaceholder": "搜索文件...", - "noMatchingFiles": "没有匹配的文件", - "noAvailableFiles": "没有可用的文件", - "noFilesInShare": "共享中没有文件", - "saveChanges": "保存更改" - }, - "recipientSelector": { - "emailPlaceholder": "请输入收件人电子邮件", - "add": "添加", - "recipients": "收件人 ({{count}})", - "notifyAll": "通知所有人", - "noRecipients": "还没有添加收件人", - "addSuccess": "收件人添加成功", - "addError": "添加收件人失败", - "removeSuccess": "收件人删除成功", - "removeError": "删除收件人失败", - "sendingNotifications": "正在发送通知...", - "notifySuccess": "收件人通知成功", - "notifyError": "通知收件人失败" - }, - "navigation": { - "dashboard": "仪表盘" - }, "common": { "loading": "加载中,请稍候...", "cancel": "取消", @@ -78,6 +24,22 @@ "success": "共享创建成功", "error": "创建共享失败" }, + "dashboard": { + "loadError": "加载仪表盘数据失败", + "linkCopied": "链接已复制到剪贴板", + "pageTitle": "仪表盘", + "breadcrumb": "仪表盘" + }, + "emptyState": { + "noFiles": "尚未上传任何文件", + "uploadFile": "上传文件" + }, + "errors": { + "invalidCredentials": "电子邮件或密码错误", + "userNotFound": "未找到用户", + "accountLocked": "账户已锁定。请稍后再试", + "unexpectedError": "发生意外错误。请重试" + }, "fileActions": { "editFile": "编辑文件", "nameLabel": "名称", @@ -89,6 +51,13 @@ "deleteConfirmation": "您确定要删除“{{fileName}}”吗?", "deleteWarning": "此操作不可撤销。" }, + "fileManager": { + "downloadError": "文件下载失败", + "updateSuccess": "文件更新成功", + "updateError": "文件更新失败", + "deleteSuccess": "文件删除成功", + "deleteError": "文件删除失败" + }, "filePreview": { "loading": "正在加载预览...", "notAvailable": "预览不可用", @@ -98,68 +67,21 @@ "loadError": "加载预览失败", "downloadError": "下载文件失败" }, - "generateShareLink": { - "generateTitle": "生成共享链接", - "updateTitle": "更新共享链接", - "generateDescription": "生成用于共享文件的链接", - "updateDescription": "更新此共享链接的别名", - "aliasPlaceholder": "请输入别名", - "linkReady": "您的共享链接已准备好:", - "generateButton": "生成链接", - "updateButton": "更新链接", - "copyButton": "复制链接", - "success": "链接生成成功", - "error": "生成链接失败", - "copied": "链接已复制到剪贴板" + "fileSelector": { + "availableFiles": "可用文件 ({{count}})", + "shareFiles": "共享文件 ({{count}})", + "searchPlaceholder": "搜索文件...", + "noMatchingFiles": "没有匹配的文件", + "noAvailableFiles": "没有可用的文件", + "noFilesInShare": "共享中没有文件", + "saveChanges": "保存更改" }, - "shareActions": { - "deleteTitle": "删除共享", - "deleteConfirmation": "您确定要删除此共享吗?此操作不可撤销。", - "editTitle": "编辑共享", - "nameLabel": "共享名称", - "expirationLabel": "过期日期", - "expirationPlaceholder": "MM/DD/YYYY HH:MM", - "maxViewsLabel": "最大查看次数", - "maxViewsPlaceholder": "留空表示无限", - "passwordProtection": "密码保护", - "passwordLabel": "密码", - "passwordPlaceholder": "请输入密码", - "newPasswordLabel": "新密码(留空表示保持当前密码)", - "newPasswordPlaceholder": "请输入新密码", - "manageFilesTitle": "管理文件", - "manageRecipientsTitle": "管理收件人", - "editSuccess": "共享更新成功", - "editError": "更新共享失败" - }, - "shareDetails": { - "title": "共享详情", - "subtitle": "关于此共享的详细信息", - "basicInfo": "基本信息", - "name": "名称", - "untitled": "未命名", - "views": "查看次数", - "dates": "日期", - "created": "创建于", - "expires": "过期于", - "never": "从不", - "security": "安全性", - "passwordProtected": "受密码保护", - "publicAccess": "公开访问", - "maxViews": "最大查看次数:{{count}}", - "files": "文件 ({{count}})", - "recipients": "收件人 ({{count}})", - "notAvailable": "不适用", - "invalidDate": "无效的日期", - "loadError": "加载共享详情失败" - }, - "uploadFile": { - "title": "上传文件", - "selectFile": "点击选择文件", - "preview": "预览", - "uploadProgress": "上传进度", - "upload": "上传", - "success": "文件上传成功", - "error": "文件上传失败" + "files": { + "title": "所有文件", + "uploadFile": "上传文件", + "loadError": "加载文件失败", + "pageTitle": "我的文件", + "breadcrumb": "我的文件" }, "filesTable": { "ariaLabel": "文件表格", @@ -179,119 +101,10 @@ "delete": "删除" } }, - "sharesTable": { - "ariaLabel": "共享表格", - "never": "从不", - "columns": { - "name": "名称", - "createdAt": "创建时间", - "expiresAt": "过期时间", - "status": "状态", - "security": "安全性", - "files": "文件", - "recipients": "收件人", - "actions": "操作" - }, - "status": { - "neverExpires": "永不过期", - "active": "活跃", - "expired": "已过期" - }, - "security": { - "protected": "受保护", - "public": "公开" - }, - "filesCount": "{{count}} 个文件", - "recipientsCount": "{{count}} 个收件人", - "actions": { - "menu": "共享操作菜单", - "edit": "编辑", - "manageFiles": "管理文件", - "manageRecipients": "管理收件人", - "viewDetails": "查看详情", - "generateLink": "生成链接", - "editLink": "编辑链接", - "copyLink": "复制链接", - "notifyRecipients": "通知收件人", - "delete": "删除" - } - }, "footer": { "poweredBy": "技术支持:", "kyanHomepage": "Kyantech 主页" }, - "fileManager": { - "downloadError": "文件下载失败", - "updateSuccess": "文件更新成功", - "updateError": "文件更新失败", - "deleteSuccess": "文件删除成功", - "deleteError": "文件删除失败" - }, - "shareManager": { - "deleteSuccess": "共享删除成功", - "deleteError": "共享删除失败", - "updateSuccess": "共享更新成功", - "updateError": "共享更新失败", - "filesUpdateSuccess": "文件更新成功", - "filesUpdateError": "文件更新失败", - "recipientsUpdateSuccess": "收件人更新成功", - "recipientsUpdateError": "收件人更新失败", - "linkGenerateSuccess": "共享链接生成成功", - "linkGenerateError": "共享链接生成失败", - "notifyLoading": "正在发送通知...", - "notifySuccess": "通知收件人成功", - "notifyError": "通知收件人失败" - }, - "quickAccess": { - "files": { - "title": "我的文件", - "description": "访问和管理您上传的文件" - }, - "shares": { - "title": "我的共享", - "description": "查看和管理您共享的文件" - } - }, - "recentFiles": { - "title": "最近上传", - "viewAll": "查看全部", - "uploadFile": "上传文件", - "noFiles": "尚未上传文件" - }, - "recentShares": { - "title": "最近共享", - "viewAll": "查看全部", - "createShare": "创建共享", - "noShares": "尚未创建共享", - "createFirst": "请创建您的第一个共享" - }, - "storageUsage": { - "title": "存储使用情况", - "ariaLabel": "存储使用进度条", - "used": "已使用:{{size}}", - "available": "可用:{{size}}" - }, - "dashboard": { - "loadError": "加载仪表盘数据失败", - "linkCopied": "链接已复制到剪贴板", - "pageTitle": "仪表盘", - "breadcrumb": "仪表盘" - }, - "emptyState": { - "noFiles": "尚未上传任何文件", - "uploadFile": "上传文件" - }, - "files": { - "title": "所有文件", - "uploadFile": "上传文件", - "loadError": "加载文件失败", - "pageTitle": "我的文件", - "breadcrumb": "我的文件" - }, - "searchBar": { - "placeholder": "搜索文件...", - "results": "共{{total}}个文件,找到{{filtered}}个" - }, "forgotPassword": { "emailLabel": "电子邮件地址", "emailPlaceholder": "请输入您的电子邮件", @@ -303,6 +116,20 @@ "resetInstructions": "密码重置指令已发送到您的电子邮件", "pageTitle": "忘记密码?" }, + "generateShareLink": { + "generateTitle": "生成共享链接", + "updateTitle": "更新共享链接", + "generateDescription": "生成用于共享文件的链接", + "updateDescription": "更新此共享链接的别名", + "aliasPlaceholder": "请输入别名", + "linkReady": "您的共享链接已准备好:", + "generateButton": "生成链接", + "updateButton": "更新链接", + "copyButton": "复制链接", + "success": "链接生成成功", + "error": "生成链接失败", + "copied": "链接已复制到剪贴板" + }, "home": { "description": "WeTransfer的开源替代方案。安全分享文件,无需跟踪或限制。", "documentation": "文档", @@ -314,6 +141,46 @@ }, "pageTitle": "首页" }, + "login": { + "welcome": "欢迎您", + "signInToContinue": "请登录以继续", + "emailLabel": "电子邮件地址", + "emailPlaceholder": "请输入您的电子邮件", + "passwordLabel": "密码", + "passwordPlaceholder": "请输入您的密码", + "signIn": "登录", + "signingIn": "正在登录...", + "forgotPassword": "忘记密码?", + "pageTitle": "登录" + }, + "logo": { + "labels": { + "appLogo": "应用Logo" + }, + "buttons": { + "upload": "上传Logo", + "remove": "删除Logo" + }, + "messages": { + "uploadSuccess": "Logo上传成功", + "removeSuccess": "Logo删除成功" + }, + "errors": { + "uploadFailed": "Logo上传失败", + "removeFailed": "Logo删除失败" + } + }, + "navbar": { + "logoAlt": "应用Logo", + "profileMenu": "个人菜单", + "profile": "个人资料", + "settings": "设置", + "usersManagement": "用户管理", + "logout": "退出登录" + }, + "navigation": { + "dashboard": "仪表盘" + }, "profile": { "password": { "title": "修改密码", @@ -356,6 +223,43 @@ }, "pageTitle": "个人资料" }, + "quickAccess": { + "files": { + "title": "我的文件", + "description": "访问和管理您上传的文件" + }, + "shares": { + "title": "我的共享", + "description": "查看和管理您共享的文件" + } + }, + "recentFiles": { + "title": "最近上传", + "viewAll": "查看全部", + "uploadFile": "上传文件", + "noFiles": "尚未上传文件" + }, + "recentShares": { + "title": "最近共享", + "viewAll": "查看全部", + "createShare": "创建共享", + "noShares": "尚未创建共享", + "createFirst": "请创建您的第一个共享" + }, + "recipientSelector": { + "emailPlaceholder": "请输入收件人电子邮件", + "add": "添加", + "recipients": "收件人 ({{count}})", + "notifyAll": "通知所有人", + "noRecipients": "还没有添加收件人", + "addSuccess": "收件人添加成功", + "addError": "添加收件人失败", + "removeSuccess": "收件人删除成功", + "removeError": "删除收件人失败", + "sendingNotifications": "正在发送通知...", + "notifySuccess": "收件人通知成功", + "notifyError": "通知收件人失败" + }, "resetPassword": { "pageTitle": "重置密码", "header": { @@ -379,6 +283,10 @@ "invalidToken": "无效或缺失重置令牌" } }, + "searchBar": { + "placeholder": "搜索文件...", + "results": "共{{total}}个文件,找到{{filtered}}个" + }, "settings": { "groups": { "defaultDescription": "配置选项", @@ -513,6 +421,61 @@ }, "pageTitle": "共享" }, + "shareActions": { + "deleteTitle": "删除共享", + "deleteConfirmation": "您确定要删除此共享吗?此操作不可撤销。", + "editTitle": "编辑共享", + "nameLabel": "共享名称", + "expirationLabel": "过期日期", + "expirationPlaceholder": "MM/DD/YYYY HH:MM", + "maxViewsLabel": "最大查看次数", + "maxViewsPlaceholder": "留空表示无限", + "passwordProtection": "密码保护", + "passwordLabel": "密码", + "passwordPlaceholder": "请输入密码", + "newPasswordLabel": "新密码(留空表示保持当前密码)", + "newPasswordPlaceholder": "请输入新密码", + "manageFilesTitle": "管理文件", + "manageRecipientsTitle": "管理收件人", + "editSuccess": "共享更新成功", + "editError": "更新共享失败" + }, + "shareDetails": { + "title": "共享详情", + "subtitle": "关于此共享的详细信息", + "basicInfo": "基本信息", + "name": "名称", + "untitled": "未命名", + "views": "查看次数", + "dates": "日期", + "created": "创建于", + "expires": "过期于", + "never": "从不", + "security": "安全性", + "passwordProtected": "受密码保护", + "publicAccess": "公开访问", + "maxViews": "最大查看次数:", + "files": "文件", + "recipients": "收件人", + "notAvailable": "不适用", + "invalidDate": "无效的日期", + "loadError": "加载共享详情失败" + }, + "shareManager": { + "deleteSuccess": "共享删除成功", + "deleteError": "共享删除失败", + "updateSuccess": "共享更新成功", + "updateError": "共享更新失败", + "filesUpdateSuccess": "文件更新成功", + "filesUpdateError": "文件更新失败", + "recipientsUpdateSuccess": "收件人更新成功", + "recipientsUpdateError": "收件人更新失败", + "linkGenerateSuccess": "共享链接生成成功", + "linkGenerateError": "共享链接生成失败", + "notifyLoading": "正在发送通知...", + "notifySuccess": "通知收件人成功", + "notifyError": "通知收件人失败" + }, "shares": { "errors": { "loadFailed": "加载共享失败", @@ -539,6 +502,64 @@ }, "pageTitle": "共享" }, + "sharesTable": { + "ariaLabel": "共享表格", + "never": "从不", + "columns": { + "name": "名称", + "createdAt": "创建时间", + "expiresAt": "过期时间", + "status": "状态", + "security": "安全性", + "files": "文件", + "recipients": "收件人", + "actions": "操作" + }, + "status": { + "neverExpires": "永不过期", + "active": "活跃", + "expired": "已过期" + }, + "security": { + "protected": "受保护", + "public": "公开" + }, + "filesCount": "个文件", + "recipientsCount": "个收件人", + "actions": { + "menu": "共享操作菜单", + "edit": "编辑", + "manageFiles": "管理文件", + "manageRecipients": "管理收件人", + "viewDetails": "查看详情", + "generateLink": "生成链接", + "editLink": "编辑链接", + "copyLink": "复制链接", + "notifyRecipients": "通知收件人", + "delete": "删除" + } + }, + "storageUsage": { + "title": "存储使用情况", + "ariaLabel": "存储使用进度条", + "used": "已使用:", + "available": "可用:" + }, + "theme": { + "toggle": "切换主题", + "light": "明亮", + "dark": "暗黑", + "system": "系统" + }, + "uploadFile": { + "title": "上传文件", + "selectFile": "点击选择文件", + "preview": "预览", + "uploadProgress": "上传进度", + "upload": "上传", + "success": "文件上传成功", + "error": "文件上传失败" + }, "users": { "modes": { "create": "创建", @@ -608,29 +629,16 @@ "userr": "用户" } }, - "logo": { - "labels": { - "appLogo": "应用Logo" - }, - "buttons": { - "upload": "上传Logo", - "remove": "删除Logo" - }, - "messages": { - "uploadSuccess": "Logo上传成功", - "removeSuccess": "Logo删除成功" - }, - "errors": { - "uploadFailed": "Logo上传失败", - "removeFailed": "Logo删除失败" - } - }, - "navbar": { - "logoAlt": "应用Logo", - "profileMenu": "个人菜单", - "profile": "个人资料", - "settings": "设置", - "usersManagement": "用户管理", - "logout": "退出登录" + "validation": { + "invalidEmail": "无效的电子邮件地址", + "passwordMinLength": "密码至少需要6个字符", + "firstNameRequired": "名字为必填项", + "lastNameRequired": "姓氏为必填项", + "usernameLength": "用户名至少需要3个字符", + "usernameSpaces": "用户名不能包含空格", + "passwordLength": "密码至少需要8个字符", + "passwordsMatch": "密码不匹配", + "emailRequired": "电子邮件为必填项", + "passwordRequired": "密码为必填项" } -} \ No newline at end of file +} diff --git a/apps/web/next.config.ts b/apps/web/next.config.ts new file mode 100644 index 0000000..1747441 --- /dev/null +++ b/apps/web/next.config.ts @@ -0,0 +1,27 @@ +import { NextConfig } from "next"; +import createNextIntlPlugin from "next-intl/plugin"; + +const nextConfig: NextConfig = { + output: "standalone", + eslint: { + ignoreDuringBuilds: true, + }, + typescript: { + ignoreBuildErrors: true, + }, + images: { + remotePatterns: [ + { + protocol: 'https', + hostname: '**', + }, + { + protocol: 'http', + hostname: '**', + }, + ], + } +}; + +const withNextIntl = createNextIntlPlugin(); +export default withNextIntl(nextConfig); diff --git a/apps/web/orval.config.ts b/apps/web/orval.config.ts deleted file mode 100644 index fd62abd..0000000 --- a/apps/web/orval.config.ts +++ /dev/null @@ -1,10 +0,0 @@ -module.exports = { - "palmr-file": { - input: "./routes.json", - output: { - mode: "single", - target: "./src/http/endpoints/palmrAPI.ts", - schemas: "./src/http/models", - }, - }, -}; diff --git a/apps/web/package.json b/apps/web/package.json index 9f4fe4f..2b63acb 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -1,87 +1,68 @@ { - "name": "vite-template", + "name": "palmr-app-v2", + "version": "2.0.0", "private": true, - "version": "1.1.5", - "type": "module", "scripts": { - "dev": "vite", - "build": "tsc && vite build", - "lint": "eslint -c .eslintrc.json ./src/**/**/*.{ts,tsx} --fix", - "preview": "vite preview", - "format": "prettier --write ." + "dev": "next dev --turbopack", + "build": "next build", + "start": "next start", + "lint": "eslint \"src/**/*.+(ts|tsx)\"", + "lint:fix": "eslint \"src/**/*.+(ts|tsx)\" --fix", + "format": "prettier . --write", + "format:check": "prettier . --check" }, "dependencies": { - "@heroui/avatar": "^2.2.7", - "@heroui/badge": "^2.2.6", - "@heroui/breadcrumbs": "^2.2.7", - "@heroui/button": "2.2.10", - "@heroui/card": "^2.2.10", - "@heroui/chip": "^2.2.7", - "@heroui/code": "2.2.7", - "@heroui/divider": "^2.2.6", - "@heroui/dropdown": "2.3.10", - "@heroui/form": "^2.1.14", - "@heroui/image": "^2.2.6", - "@heroui/input": "2.4.10", - "@heroui/kbd": "2.2.7", - "@heroui/link": "2.2.8", - "@heroui/modal": "^2.2.8", - "@heroui/navbar": "2.2.9", - "@heroui/progress": "^2.2.7", - "@heroui/select": "2.4.9", - "@heroui/snippet": "2.2.11", - "@heroui/spinner": "^2.2.12", - "@heroui/switch": "2.2.9", - "@heroui/system": "2.4.6", - "@heroui/table": "^2.2.9", - "@heroui/theme": "2.4.6", - "@hookform/resolvers": "^4.0.0", - "@react-aria/selection": "3.21.0", - "@react-aria/utils": "3.27.0", - "@react-aria/visually-hidden": "3.8.19", - "@react-types/shared": "3.27.0", - "axios": "^1.7.9", - "clsx": "2.1.1", + "@hookform/resolvers": "^5.0.1", + "@radix-ui/react-aspect-ratio": "^1.1.3", + "@radix-ui/react-avatar": "^1.1.4", + "@radix-ui/react-dialog": "^1.1.6", + "@radix-ui/react-dropdown-menu": "^2.1.6", + "@radix-ui/react-label": "^2.1.2", + "@radix-ui/react-progress": "^1.1.3", + "@radix-ui/react-scroll-area": "^1.2.4", + "@radix-ui/react-select": "^2.1.7", + "@radix-ui/react-separator": "^1.1.3", + "@radix-ui/react-slot": "^1.1.2", + "@radix-ui/react-switch": "^1.1.4", + "@tabler/icons-react": "^3.31.0", + "axios": "^1.8.4", + "class-variance-authority": "^0.7.1", + "clsx": "^2.1.1", "date-fns": "^4.1.0", - "framer-motion": "12.4.1", - "i18next": "^24.2.2", - "i18next-browser-languagedetector": "^8.0.3", - "nanoid": "^5.0.9", - "react": "18.3.1", + "framer-motion": "^12.6.3", + "lucide-react": "^0.487.0", + "nanoid": "^5.1.5", + "next": "15.2.4", + "next-intl": "^4.0.2", + "next-themes": "^0.4.6", + "nookies": "^2.5.2", + "react": "^19.1.0", "react-country-flag": "^3.1.0", - "react-dom": "18.3.1", - "react-hook-form": "^7.54.2", - "react-i18next": "^15.4.1", - "react-icons": "^5.4.0", - "react-router-dom": "6.23.0", - "sonner": "^1.7.4", - "tailwind-variants": "0.3.1", - "tailwindcss": "3.4.16", - "zod": "^3.24.1" + "react-dom": "^19.1.0", + "react-hook-form": "^7.55.0", + "sonner": "^2.0.3", + "tailwind-merge": "^3.1.0", + "tw-animate-css": "^1.2.5", + "zod": "^3.24.2", + "zustand": "^5.0.3" }, "devDependencies": { - "@trivago/prettier-plugin-sort-imports": "^5.2.2", - "@types/node": "22.13.1", - "@types/react": "18.3.3", - "@types/react-dom": "18.3.0", - "@typescript-eslint/eslint-plugin": "8.23.0", - "@typescript-eslint/parser": "8.23.0", - "@vitejs/plugin-react": "^4.3.4", - "autoprefixer": "10.4.20", - "eslint": "^8.57.0", + "@eslint/eslintrc": "3.3.1", + "@eslint/js": "9.23.0", + "@ianvs/prettier-plugin-sort-imports": "4.4.1", + "@tailwindcss/postcss": "4.1.2", + "@types/node": "22.14.0", + "@types/react": "19.1.0", + "@types/react-dom": "19.1.1", + "@typescript-eslint/eslint-plugin": "8.29.0", + "@typescript-eslint/parser": "8.29.0", + "eslint": "9.23.0", + "eslint-config-next": "15.2.4", "eslint-config-prettier": "9.1.0", - "eslint-plugin-import": "^2.31.0", - "eslint-plugin-jsx-a11y": "^6.10.2", - "eslint-plugin-node": "^11.1.0", - "eslint-plugin-prettier": "5.2.3", - "eslint-plugin-react": "^7.37.4", - "eslint-plugin-react-hooks": "^4.6.0", - "eslint-plugin-unused-imports": "4.1.4", - "orval": "^7.5.0", - "postcss": "8.5.1", - "prettier": "3.4.2", - "typescript": "5.7.3", - "vite": "^6.1.0", - "vite-tsconfig-paths": "^4.3.2" + "eslint-plugin-prettier": "5.2.6", + "prettier": "3.5.3", + "prettier-plugin-sort-json": "4.1.1", + "tailwindcss": "4.1.2", + "typescript": "5.8.2" } -} \ No newline at end of file +} diff --git a/apps/web/pnpm-lock.yaml b/apps/web/pnpm-lock.yaml new file mode 100644 index 0000000..d1a0b15 --- /dev/null +++ b/apps/web/pnpm-lock.yaml @@ -0,0 +1,5687 @@ +lockfileVersion: "9.0" + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + .: + dependencies: + "@hookform/resolvers": + specifier: ^5.0.1 + version: 5.0.1(react-hook-form@7.55.0(react@19.1.0)) + "@radix-ui/react-aspect-ratio": + specifier: ^1.1.3 + version: 1.1.3(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + "@radix-ui/react-avatar": + specifier: ^1.1.4 + version: 1.1.4(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + "@radix-ui/react-dialog": + specifier: ^1.1.6 + version: 1.1.7(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + "@radix-ui/react-dropdown-menu": + specifier: ^2.1.6 + version: 2.1.7(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + "@radix-ui/react-label": + specifier: ^2.1.2 + version: 2.1.3(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + "@radix-ui/react-progress": + specifier: ^1.1.3 + version: 1.1.3(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + "@radix-ui/react-scroll-area": + specifier: ^1.2.4 + version: 1.2.4(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + "@radix-ui/react-select": + specifier: ^2.1.7 + version: 2.1.7(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + "@radix-ui/react-separator": + specifier: ^1.1.3 + version: 1.1.3(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + "@radix-ui/react-slot": + specifier: ^1.1.2 + version: 1.2.0(@types/react@19.1.0)(react@19.1.0) + "@radix-ui/react-switch": + specifier: ^1.1.4 + version: 1.1.4(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + "@tabler/icons-react": + specifier: ^3.31.0 + version: 3.31.0(react@19.1.0) + axios: + specifier: ^1.8.4 + version: 1.8.4 + class-variance-authority: + specifier: ^0.7.1 + version: 0.7.1 + clsx: + specifier: ^2.1.1 + version: 2.1.1 + date-fns: + specifier: ^4.1.0 + version: 4.1.0 + framer-motion: + specifier: ^12.6.3 + version: 12.7.3(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + lucide-react: + specifier: ^0.487.0 + version: 0.487.0(react@19.1.0) + nanoid: + specifier: ^5.1.5 + version: 5.1.5 + next: + specifier: 15.2.4 + version: 15.2.4(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + next-intl: + specifier: ^4.0.2 + version: 4.0.2(next@15.2.4(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react@19.1.0)(typescript@5.8.2) + next-themes: + specifier: ^0.4.6 + version: 0.4.6(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + nookies: + specifier: ^2.5.2 + version: 2.5.2 + react: + specifier: ^19.1.0 + version: 19.1.0 + react-country-flag: + specifier: ^3.1.0 + version: 3.1.0(react@19.1.0) + react-dom: + specifier: ^19.1.0 + version: 19.1.0(react@19.1.0) + react-hook-form: + specifier: ^7.55.0 + version: 7.55.0(react@19.1.0) + sonner: + specifier: ^2.0.3 + version: 2.0.3(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + tailwind-merge: + specifier: ^3.1.0 + version: 3.2.0 + tw-animate-css: + specifier: ^1.2.5 + version: 1.2.5 + zod: + specifier: ^3.24.2 + version: 3.24.2 + zustand: + specifier: ^5.0.3 + version: 5.0.3(@types/react@19.1.0)(react@19.1.0) + devDependencies: + "@eslint/eslintrc": + specifier: 3.3.1 + version: 3.3.1 + "@eslint/js": + specifier: 9.23.0 + version: 9.23.0 + "@ianvs/prettier-plugin-sort-imports": + specifier: 4.4.1 + version: 4.4.1(prettier@3.5.3) + "@tailwindcss/postcss": + specifier: 4.1.2 + version: 4.1.2 + "@types/node": + specifier: 22.14.0 + version: 22.14.0 + "@types/react": + specifier: 19.1.0 + version: 19.1.0 + "@types/react-dom": + specifier: 19.1.1 + version: 19.1.1(@types/react@19.1.0) + "@typescript-eslint/eslint-plugin": + specifier: 8.29.0 + version: 8.29.0(@typescript-eslint/parser@8.29.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2) + "@typescript-eslint/parser": + specifier: 8.29.0 + version: 8.29.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2) + eslint: + specifier: 9.23.0 + version: 9.23.0(jiti@2.4.2) + eslint-config-next: + specifier: 15.2.4 + version: 15.2.4(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2) + eslint-config-prettier: + specifier: 9.1.0 + version: 9.1.0(eslint@9.23.0(jiti@2.4.2)) + eslint-plugin-prettier: + specifier: 5.2.6 + version: 5.2.6(eslint-config-prettier@9.1.0(eslint@9.23.0(jiti@2.4.2)))(eslint@9.23.0(jiti@2.4.2))(prettier@3.5.3) + prettier: + specifier: 3.5.3 + version: 3.5.3 + prettier-plugin-sort-json: + specifier: 4.1.1 + version: 4.1.1(prettier@3.5.3) + tailwindcss: + specifier: 4.1.2 + version: 4.1.2 + typescript: + specifier: 5.8.2 + version: 5.8.2 + +packages: + "@alloc/quick-lru@5.2.0": + resolution: + { integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw== } + engines: { node: ">=10" } + + "@babel/code-frame@7.26.2": + resolution: + { integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ== } + engines: { node: ">=6.9.0" } + + "@babel/generator@7.27.0": + resolution: + { integrity: sha512-VybsKvpiN1gU1sdMZIp7FcqphVVKEwcuj02x73uvcHE0PTihx1nlBcowYWhDwjpoAXRv43+gDzyggGnn1XZhVw== } + engines: { node: ">=6.9.0" } + + "@babel/helper-string-parser@7.25.9": + resolution: + { integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA== } + engines: { node: ">=6.9.0" } + + "@babel/helper-validator-identifier@7.25.9": + resolution: + { integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ== } + engines: { node: ">=6.9.0" } + + "@babel/parser@7.27.0": + resolution: + { integrity: sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg== } + engines: { node: ">=6.0.0" } + hasBin: true + + "@babel/template@7.27.0": + resolution: + { integrity: sha512-2ncevenBqXI6qRMukPlXwHKHchC7RyMuu4xv5JBXRfOGVcTy1mXCD12qrp7Jsoxll1EV3+9sE4GugBVRjT2jFA== } + engines: { node: ">=6.9.0" } + + "@babel/traverse@7.27.0": + resolution: + { integrity: sha512-19lYZFzYVQkkHkl4Cy4WrAVcqBkgvV2YM2TU3xG6DIwO7O3ecbDPfW3yM3bjAGcqcQHi+CCtjMR3dIEHxsd6bA== } + engines: { node: ">=6.9.0" } + + "@babel/types@7.27.0": + resolution: + { integrity: sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg== } + engines: { node: ">=6.9.0" } + + "@emnapi/core@1.4.3": + resolution: + { integrity: sha512-4m62DuCE07lw01soJwPiBGC0nAww0Q+RY70VZ+n49yDIO13yyinhbWCeNnaob0lakDtWQzSdtNWzJeOJt2ma+g== } + + "@emnapi/runtime@1.4.3": + resolution: + { integrity: sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ== } + + "@emnapi/wasi-threads@1.0.2": + resolution: + { integrity: sha512-5n3nTJblwRi8LlXkJ9eBzu+kZR8Yxcc7ubakyQTFzPMtIhFpUBRbsnc2Dv88IZDIbCDlBiWrknhB4Lsz7mg6BA== } + + "@eslint-community/eslint-utils@4.6.1": + resolution: + { integrity: sha512-KTsJMmobmbrFLe3LDh0PC2FXpcSYJt/MLjlkh/9LEnmKYLSYmT/0EW9JWANjeoemiuZrmogti0tW5Ch+qNUYDw== } + engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 } + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + "@eslint-community/regexpp@4.12.1": + resolution: + { integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ== } + engines: { node: ^12.0.0 || ^14.0.0 || >=16.0.0 } + + "@eslint/config-array@0.19.2": + resolution: + { integrity: sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + + "@eslint/config-helpers@0.2.1": + resolution: + { integrity: sha512-RI17tsD2frtDu/3dmI7QRrD4bedNKPM08ziRYaC5AhkGrzIAJelm9kJU1TznK+apx6V+cqRz8tfpEeG3oIyjxw== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + + "@eslint/core@0.12.0": + resolution: + { integrity: sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + + "@eslint/core@0.13.0": + resolution: + { integrity: sha512-yfkgDw1KR66rkT5A8ci4irzDysN7FRpq3ttJolR88OqQikAWqwA8j5VZyas+vjyBNFIJ7MfybJ9plMILI2UrCw== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + + "@eslint/eslintrc@3.3.1": + resolution: + { integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + + "@eslint/js@9.23.0": + resolution: + { integrity: sha512-35MJ8vCPU0ZMxo7zfev2pypqTwWTofFZO6m4KAtdoFhRpLJUpHTZZ+KB3C7Hb1d7bULYwO4lJXGCi5Se+8OMbw== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + + "@eslint/object-schema@2.1.6": + resolution: + { integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + + "@eslint/plugin-kit@0.2.8": + resolution: + { integrity: sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + + "@floating-ui/core@1.6.9": + resolution: + { integrity: sha512-uMXCuQ3BItDUbAMhIXw7UPXRfAlOAvZzdK9BWpE60MCn+Svt3aLn9jsPTi/WNGlRUu2uI0v5S7JiIUsbsvh3fw== } + + "@floating-ui/dom@1.6.13": + resolution: + { integrity: sha512-umqzocjDgNRGTuO7Q8CU32dkHkECqI8ZdMZ5Swb6QAM0t5rnlrN3lGo1hdpscRd3WS8T6DKYK4ephgIH9iRh3w== } + + "@floating-ui/react-dom@2.1.2": + resolution: + { integrity: sha512-06okr5cgPzMNBy+Ycse2A6udMi4bqwW/zgBF/rwjcNqWkyr82Mcg8b0vjX8OJpZFy/FKjJmw6wV7t44kK6kW7A== } + peerDependencies: + react: ">=16.8.0" + react-dom: ">=16.8.0" + + "@floating-ui/utils@0.2.9": + resolution: + { integrity: sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg== } + + "@formatjs/ecma402-abstract@2.3.4": + resolution: + { integrity: sha512-qrycXDeaORzIqNhBOx0btnhpD1c+/qFIHAN9znofuMJX6QBwtbrmlpWfD4oiUUD2vJUOIYFA/gYtg2KAMGG7sA== } + + "@formatjs/fast-memoize@2.2.7": + resolution: + { integrity: sha512-Yabmi9nSvyOMrlSeGGWDiH7rf3a7sIwplbvo/dlz9WCIjzIQAfy1RMf4S0X3yG724n5Ghu2GmEl5NJIV6O9sZQ== } + + "@formatjs/icu-messageformat-parser@2.11.2": + resolution: + { integrity: sha512-AfiMi5NOSo2TQImsYAg8UYddsNJ/vUEv/HaNqiFjnI3ZFfWihUtD5QtuX6kHl8+H+d3qvnE/3HZrfzgdWpsLNA== } + + "@formatjs/icu-skeleton-parser@1.8.14": + resolution: + { integrity: sha512-i4q4V4qslThK4Ig8SxyD76cp3+QJ3sAqr7f6q9VVfeGtxG9OhiAk3y9XF6Q41OymsKzsGQ6OQQoJNY4/lI8TcQ== } + + "@formatjs/intl-localematcher@0.5.10": + resolution: + { integrity: sha512-af3qATX+m4Rnd9+wHcjJ4w2ijq+rAVP3CCinJQvFv1kgSu1W6jypUmvleJxcewdxmutM8dmIRZFxO/IQBZmP2Q== } + + "@formatjs/intl-localematcher@0.6.1": + resolution: + { integrity: sha512-ePEgLgVCqi2BBFnTMWPfIghu6FkbZnnBVhO2sSxvLfrdFw7wCHAHiDoM2h4NRgjbaY7+B7HgOLZGkK187pZTZg== } + + "@hookform/resolvers@5.0.1": + resolution: + { integrity: sha512-u/+Jp83luQNx9AdyW2fIPGY6Y7NG68eN2ZW8FOJYL+M0i4s49+refdJdOp/A9n9HFQtQs3HIDHQvX3ZET2o7YA== } + peerDependencies: + react-hook-form: ^7.55.0 + + "@humanfs/core@0.19.1": + resolution: + { integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA== } + engines: { node: ">=18.18.0" } + + "@humanfs/node@0.16.6": + resolution: + { integrity: sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw== } + engines: { node: ">=18.18.0" } + + "@humanwhocodes/module-importer@1.0.1": + resolution: + { integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== } + engines: { node: ">=12.22" } + + "@humanwhocodes/retry@0.3.1": + resolution: + { integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA== } + engines: { node: ">=18.18" } + + "@humanwhocodes/retry@0.4.2": + resolution: + { integrity: sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ== } + engines: { node: ">=18.18" } + + "@ianvs/prettier-plugin-sort-imports@4.4.1": + resolution: + { integrity: sha512-F0/Hrcfpy8WuxlQyAWJTEren/uxKhYonOGY4OyWmwRdeTvkh9mMSCxowZLjNkhwi/2ipqCgtXwwOk7tW0mWXkA== } + peerDependencies: + "@vue/compiler-sfc": 2.7.x || 3.x + prettier: 2 || 3 + peerDependenciesMeta: + "@vue/compiler-sfc": + optional: true + + "@img/sharp-darwin-arm64@0.33.5": + resolution: + { integrity: sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ== } + engines: { node: ^18.17.0 || ^20.3.0 || >=21.0.0 } + cpu: [arm64] + os: [darwin] + + "@img/sharp-darwin-x64@0.33.5": + resolution: + { integrity: sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q== } + engines: { node: ^18.17.0 || ^20.3.0 || >=21.0.0 } + cpu: [x64] + os: [darwin] + + "@img/sharp-libvips-darwin-arm64@1.0.4": + resolution: + { integrity: sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg== } + cpu: [arm64] + os: [darwin] + + "@img/sharp-libvips-darwin-x64@1.0.4": + resolution: + { integrity: sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ== } + cpu: [x64] + os: [darwin] + + "@img/sharp-libvips-linux-arm64@1.0.4": + resolution: + { integrity: sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA== } + cpu: [arm64] + os: [linux] + + "@img/sharp-libvips-linux-arm@1.0.5": + resolution: + { integrity: sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g== } + cpu: [arm] + os: [linux] + + "@img/sharp-libvips-linux-s390x@1.0.4": + resolution: + { integrity: sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA== } + cpu: [s390x] + os: [linux] + + "@img/sharp-libvips-linux-x64@1.0.4": + resolution: + { integrity: sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw== } + cpu: [x64] + os: [linux] + + "@img/sharp-libvips-linuxmusl-arm64@1.0.4": + resolution: + { integrity: sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA== } + cpu: [arm64] + os: [linux] + + "@img/sharp-libvips-linuxmusl-x64@1.0.4": + resolution: + { integrity: sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw== } + cpu: [x64] + os: [linux] + + "@img/sharp-linux-arm64@0.33.5": + resolution: + { integrity: sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA== } + engines: { node: ^18.17.0 || ^20.3.0 || >=21.0.0 } + cpu: [arm64] + os: [linux] + + "@img/sharp-linux-arm@0.33.5": + resolution: + { integrity: sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ== } + engines: { node: ^18.17.0 || ^20.3.0 || >=21.0.0 } + cpu: [arm] + os: [linux] + + "@img/sharp-linux-s390x@0.33.5": + resolution: + { integrity: sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q== } + engines: { node: ^18.17.0 || ^20.3.0 || >=21.0.0 } + cpu: [s390x] + os: [linux] + + "@img/sharp-linux-x64@0.33.5": + resolution: + { integrity: sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA== } + engines: { node: ^18.17.0 || ^20.3.0 || >=21.0.0 } + cpu: [x64] + os: [linux] + + "@img/sharp-linuxmusl-arm64@0.33.5": + resolution: + { integrity: sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g== } + engines: { node: ^18.17.0 || ^20.3.0 || >=21.0.0 } + cpu: [arm64] + os: [linux] + + "@img/sharp-linuxmusl-x64@0.33.5": + resolution: + { integrity: sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw== } + engines: { node: ^18.17.0 || ^20.3.0 || >=21.0.0 } + cpu: [x64] + os: [linux] + + "@img/sharp-wasm32@0.33.5": + resolution: + { integrity: sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg== } + engines: { node: ^18.17.0 || ^20.3.0 || >=21.0.0 } + cpu: [wasm32] + + "@img/sharp-win32-ia32@0.33.5": + resolution: + { integrity: sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ== } + engines: { node: ^18.17.0 || ^20.3.0 || >=21.0.0 } + cpu: [ia32] + os: [win32] + + "@img/sharp-win32-x64@0.33.5": + resolution: + { integrity: sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg== } + engines: { node: ^18.17.0 || ^20.3.0 || >=21.0.0 } + cpu: [x64] + os: [win32] + + "@jridgewell/gen-mapping@0.3.8": + resolution: + { integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA== } + engines: { node: ">=6.0.0" } + + "@jridgewell/resolve-uri@3.1.2": + resolution: + { integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== } + engines: { node: ">=6.0.0" } + + "@jridgewell/set-array@1.2.1": + resolution: + { integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A== } + engines: { node: ">=6.0.0" } + + "@jridgewell/sourcemap-codec@1.5.0": + resolution: + { integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ== } + + "@jridgewell/trace-mapping@0.3.25": + resolution: + { integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ== } + + "@napi-rs/wasm-runtime@0.2.9": + resolution: + { integrity: sha512-OKRBiajrrxB9ATokgEQoG87Z25c67pCpYcCwmXYX8PBftC9pBfN18gnm/fh1wurSLEKIAt+QRFLFCQISrb66Jg== } + + "@next/env@15.2.4": + resolution: + { integrity: sha512-+SFtMgoiYP3WoSswuNmxJOCwi06TdWE733D+WPjpXIe4LXGULwEaofiiAy6kbS0+XjM5xF5n3lKuBwN2SnqD9g== } + + "@next/eslint-plugin-next@15.2.4": + resolution: + { integrity: sha512-O8ScvKtnxkp8kL9TpJTTKnMqlkZnS+QxwoQnJwPGBxjBbzd6OVVPEJ5/pMNrktSyXQD/chEfzfFzYLM6JANOOQ== } + + "@next/swc-darwin-arm64@15.2.4": + resolution: + { integrity: sha512-1AnMfs655ipJEDC/FHkSr0r3lXBgpqKo4K1kiwfUf3iE68rDFXZ1TtHdMvf7D0hMItgDZ7Vuq3JgNMbt/+3bYw== } + engines: { node: ">= 10" } + cpu: [arm64] + os: [darwin] + + "@next/swc-darwin-x64@15.2.4": + resolution: + { integrity: sha512-3qK2zb5EwCwxnO2HeO+TRqCubeI/NgCe+kL5dTJlPldV/uwCnUgC7VbEzgmxbfrkbjehL4H9BPztWOEtsoMwew== } + engines: { node: ">= 10" } + cpu: [x64] + os: [darwin] + + "@next/swc-linux-arm64-gnu@15.2.4": + resolution: + { integrity: sha512-HFN6GKUcrTWvem8AZN7tT95zPb0GUGv9v0d0iyuTb303vbXkkbHDp/DxufB04jNVD+IN9yHy7y/6Mqq0h0YVaQ== } + engines: { node: ">= 10" } + cpu: [arm64] + os: [linux] + + "@next/swc-linux-arm64-musl@15.2.4": + resolution: + { integrity: sha512-Oioa0SORWLwi35/kVB8aCk5Uq+5/ZIumMK1kJV+jSdazFm2NzPDztsefzdmzzpx5oGCJ6FkUC7vkaUseNTStNA== } + engines: { node: ">= 10" } + cpu: [arm64] + os: [linux] + + "@next/swc-linux-x64-gnu@15.2.4": + resolution: + { integrity: sha512-yb5WTRaHdkgOqFOZiu6rHV1fAEK0flVpaIN2HB6kxHVSy/dIajWbThS7qON3W9/SNOH2JWkVCyulgGYekMePuw== } + engines: { node: ">= 10" } + cpu: [x64] + os: [linux] + + "@next/swc-linux-x64-musl@15.2.4": + resolution: + { integrity: sha512-Dcdv/ix6srhkM25fgXiyOieFUkz+fOYkHlydWCtB0xMST6X9XYI3yPDKBZt1xuhOytONsIFJFB08xXYsxUwJLw== } + engines: { node: ">= 10" } + cpu: [x64] + os: [linux] + + "@next/swc-win32-arm64-msvc@15.2.4": + resolution: + { integrity: sha512-dW0i7eukvDxtIhCYkMrZNQfNicPDExt2jPb9AZPpL7cfyUo7QSNl1DjsHjmmKp6qNAqUESyT8YFl/Aw91cNJJg== } + engines: { node: ">= 10" } + cpu: [arm64] + os: [win32] + + "@next/swc-win32-x64-msvc@15.2.4": + resolution: + { integrity: sha512-SbnWkJmkS7Xl3kre8SdMF6F/XDh1DTFEhp0jRTj/uB8iPKoU2bb2NDfcu+iifv1+mxQEd1g2vvSxcZbXSKyWiQ== } + engines: { node: ">= 10" } + cpu: [x64] + os: [win32] + + "@nodelib/fs.scandir@2.1.5": + resolution: + { integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== } + engines: { node: ">= 8" } + + "@nodelib/fs.stat@2.0.5": + resolution: + { integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== } + engines: { node: ">= 8" } + + "@nodelib/fs.walk@1.2.8": + resolution: + { integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== } + engines: { node: ">= 8" } + + "@nolyfill/is-core-module@1.0.39": + resolution: + { integrity: sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA== } + engines: { node: ">=12.4.0" } + + "@pkgr/core@0.2.4": + resolution: + { integrity: sha512-ROFF39F6ZrnzSUEmQQZUar0Jt4xVoP9WnDRdWwF4NNcXs3xBTLgBUDoOwW141y1jP+S8nahIbdxbFC7IShw9Iw== } + engines: { node: ^12.20.0 || ^14.18.0 || >=16.0.0 } + + "@radix-ui/number@1.1.1": + resolution: + { integrity: sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g== } + + "@radix-ui/primitive@1.1.2": + resolution: + { integrity: sha512-XnbHrrprsNqZKQhStrSwgRUQzoCI1glLzdw79xiZPoofhGICeZRSQ3dIxAKH1gb3OHfNf4d6f+vAv3kil2eggA== } + + "@radix-ui/react-arrow@1.1.3": + resolution: + { integrity: sha512-2dvVU4jva0qkNZH6HHWuSz5FN5GeU5tymvCgutF8WaXz9WnD1NgUhy73cqzkjkN4Zkn8lfTPv5JIfrC221W+Nw== } + 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-aspect-ratio@1.1.3": + resolution: + { integrity: sha512-yIrYZUc2e/JtRkDpuJCmaR6kj/jzekDfQLcPFdEWzSOygCPy8poR4YcszaHP5A7mh25ncofHEpeTwfhxEuBv8Q== } + 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-avatar@1.1.4": + resolution: + { integrity: sha512-+kBesLBzwqyDiYCtYFK+6Ktf+N7+Y6QOTUueLGLIbLZ/YeyFW6bsBGDsN+5HxHpM55C90u5fxsg0ErxzXTcwKA== } + 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-collection@1.1.3": + resolution: + { integrity: sha512-mM2pxoQw5HJ49rkzwOs7Y6J4oYH22wS8BfK2/bBxROlI4xuR0c4jEenQP63LlTlDkO6Buj2Vt+QYAYcOgqtrXA== } + 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": + resolution: + { integrity: sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg== } + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + + "@radix-ui/react-context@1.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.7": + resolution: + { integrity: sha512-EIdma8C0C/I6kL6sO02avaCRqi3fmWJpxH6mqbVScorW6nNktzKJT/le7VPho3o/7wCsyRg3z0+Q+Obr0Gy/VQ== } + 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-direction@1.1.1": + resolution: + { integrity: sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw== } + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + + "@radix-ui/react-dismissable-layer@1.1.6": + resolution: + { integrity: sha512-7gpgMT2gyKym9Jz2ZhlRXSg2y6cNQIK8d/cqBZ0RBCaps8pFryCWXiUKI+uHGFrhMrbGUP7U6PWgiXzIxoyF3Q== } + 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-dropdown-menu@2.1.7": + resolution: + { integrity: sha512-7/1LiuNZuCQE3IzdicGoHdQOHkS2Q08+7p8w6TXZ6ZjgAULaCI85ZY15yPl4o4FVgoKLRT43/rsfNVN8osClQQ== } + 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.2": + resolution: + { integrity: sha512-fyjAACV62oPV925xFCrH8DR5xWhg9KYtJT4s3u54jxp+L/hbpTY2kIeEFFbFe+a/HCE94zGQMZLIpVTPVZDhaA== } + 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.3": + resolution: + { integrity: sha512-4XaDlq0bPt7oJwR+0k0clCiCO/7lO7NKZTAaJBYxDNQT/vj4ig0/UvctrRscZaFREpRvUTkpKR96ov1e6jptQg== } + 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-label@2.1.3": + resolution: + { integrity: sha512-zwSQ1NzSKG95yA0tvBMgv6XPHoqapJCcg9nsUBaQQ66iRBhZNhlpaQG2ERYYX4O4stkYFK5rxj5NsWfO9CS+Hg== } + 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-menu@2.1.7": + resolution: + { integrity: sha512-tBODsrk68rOi1/iQzbM54toFF+gSw/y+eQgttFflqlGekuSebNqvFNHjJgjqPhiMb4Fw9A0zNFly1QT6ZFdQ+Q== } + peerDependencies: + "@types/react": "*" + "@types/react-dom": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-dom": + optional: true + + "@radix-ui/react-popper@1.2.3": + resolution: + { integrity: sha512-iNb9LYUMkne9zIahukgQmHlSBp9XWGeQQ7FvUGNk45ywzOb6kQa+Ca38OphXlWDiKvyneo9S+KSJsLfLt8812A== } + 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.5": + resolution: + { integrity: sha512-ps/67ZqsFm+Mb6lSPJpfhRLrVL2i2fntgCmGMqqth4eaGUf+knAuuRtWVJrNjUhExgmdRqftSgzpf0DF0n6yXA== } + 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.3": + resolution: + { integrity: sha512-IrVLIhskYhH3nLvtcBLQFZr61tBG7wx7O3kEmdzcYwRGAEBmBicGGL7ATzNgruYJ3xBTbuzEEq9OXJM3PAX3tA== } + 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.0.3": + resolution: + { integrity: sha512-Pf/t/GkndH7CQ8wE2hbkXA+WyZ83fhQQn5DDmwDiDo6AwN/fhaH8oqZ0jRjMrO2iaMhDi6P1HRx6AZwyMinY1g== } + 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-progress@1.1.3": + resolution: + { integrity: sha512-F56aZPGTPb4qJQ/vDjnAq63oTu/DRoIG/Asb5XKOWj8rpefNLtUllR969j5QDN2sRrTk9VXIqQDRj5VvAuquaw== } + 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-roving-focus@1.1.3": + resolution: + { integrity: sha512-ufbpLUjZiOg4iYgb2hQrWXEPYX6jOLBbR27bDyAff5GYMRrCzcze8lukjuXVUQvJ6HZe8+oL+hhswDcjmcgVyg== } + 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-scroll-area@1.2.4": + resolution: + { integrity: sha512-G9rdWTQjOR4sk76HwSdROhPU0jZWpfozn9skU1v4N0/g9k7TmswrJn8W8WMU+aYktnLLpk5LX6fofj2bGe5NFQ== } + 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-select@2.1.7": + resolution: + { integrity: sha512-exzGIRtc7S8EIM2KjFg+7lJZsH7O7tpaBaJbBNVDnOZNhtoQ2iV+iSNfi2Wth0m6h3trJkMVvzAehB3c6xj/3Q== } + 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.3": + resolution: + { integrity: sha512-2omrWKJvxR0U/tkIXezcc1nFMwtLU0+b/rDK40gnzJqTLWQ/TD/D5IYVefp9sC3QWfeQbpSbEA6op9MQKyaALQ== } + 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.0": + resolution: + { integrity: sha512-ujc+V6r0HNDviYqIK3rW4ffgYiZ8g5DEHrGJVk4x7kTlLXRDILnKX9vAUYeIsLOoDpDJ0ujpqMkjH4w2ofuo6w== } + peerDependencies: + "@types/react": "*" + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + "@types/react": + optional: true + + "@radix-ui/react-switch@1.1.4": + resolution: + { integrity: sha512-zGP6W8plLeogoeGMiTHJ/uvf+TE1C2chVsEwfP8YlvpQKJHktG+iCkUtCLGPAuDV8/qDSmIRPm4NggaTxFMVBQ== } + 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.1.1": + resolution: + { integrity: sha512-YnEXIy8/ga01Y1PN0VfaNH//MhA91JlEGVBDxDzROqwrAtG5Yr2QGEPz8A/rJA3C7ZAHryOYGaUv8fLSW2H/mg== } + 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-previous@1.1.1": + resolution: + { integrity: sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ== } + 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.1.3": + resolution: + { integrity: sha512-oXSF3ZQRd5fvomd9hmUCb2EHSZbPp3ZSHAHJJU/DlF9XoFkJBBW8RHU/E8WEH+RbSfJd/QFA0sl8ClJXknBwHQ== } + 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== } + + "@rtsao/scc@1.1.0": + resolution: + { integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g== } + + "@rushstack/eslint-patch@1.11.0": + resolution: + { integrity: sha512-zxnHvoMQVqewTJr/W4pKjF0bMGiKJv1WX7bSrkl46Hg0QjESbzBROWK0Wg4RphzSOS5Jiy7eFimmM3UgMrMZbQ== } + + "@schummar/icu-type-parser@1.21.5": + resolution: + { integrity: sha512-bXHSaW5jRTmke9Vd0h5P7BtWZG9Znqb8gSDxZnxaGSJnGwPLDPfS+3g0BKzeWqzgZPsIVZkM7m2tbo18cm5HBw== } + + "@standard-schema/utils@0.3.0": + resolution: + { integrity: sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g== } + + "@swc/counter@0.1.3": + resolution: + { integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ== } + + "@swc/helpers@0.5.15": + resolution: + { integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g== } + + "@tabler/icons-react@3.31.0": + resolution: + { integrity: sha512-2rrCM5y/VnaVKnORpDdAua9SEGuJKVqPtWxeQ/vUVsgaUx30LDgBZph7/lterXxDY1IKR6NO//HDhWiifXTi3w== } + peerDependencies: + react: ">= 16" + + "@tabler/icons@3.31.0": + resolution: + { integrity: sha512-dblAdeKY3+GA1U+Q9eziZ0ooVlZMHsE8dqP0RkwvRtEsAULoKOYaCUOcJ4oW1DjWegdxk++UAt2SlQVnmeHv+g== } + + "@tailwindcss/node@4.1.2": + resolution: + { integrity: sha512-ZwFnxH+1z8Ehh8bNTMX3YFrYdzAv7JLY5X5X7XSFY+G9QGJVce/P9xb2mh+j5hKt8NceuHmdtllJvAHWKtsNrQ== } + + "@tailwindcss/oxide-android-arm64@4.1.2": + resolution: + { integrity: sha512-IxkXbntHX8lwGmwURUj4xTr6nezHhLYqeiJeqa179eihGv99pRlKV1W69WByPJDQgSf4qfmwx904H6MkQqTA8w== } + engines: { node: ">= 10" } + cpu: [arm64] + os: [android] + + "@tailwindcss/oxide-darwin-arm64@4.1.2": + resolution: + { integrity: sha512-ZRtiHSnFYHb4jHKIdzxlFm6EDfijTCOT4qwUhJ3GWxfDoW2yT3z/y8xg0nE7e72unsmSj6dtfZ9Y5r75FIrlpA== } + engines: { node: ">= 10" } + cpu: [arm64] + os: [darwin] + + "@tailwindcss/oxide-darwin-x64@4.1.2": + resolution: + { integrity: sha512-BiKUNZf1A0pBNzndBvnPnBxonCY49mgbOsPfILhcCE5RM7pQlRoOgN7QnwNhY284bDbfQSEOWnFR0zbPo6IDTw== } + engines: { node: ">= 10" } + cpu: [x64] + os: [darwin] + + "@tailwindcss/oxide-freebsd-x64@4.1.2": + resolution: + { integrity: sha512-Z30VcpUfRGkiddj4l5NRCpzbSGjhmmklVoqkVQdkEC0MOelpY+fJrVhzSaXHmWrmSvnX8yiaEqAbdDScjVujYQ== } + engines: { node: ">= 10" } + cpu: [x64] + os: [freebsd] + + "@tailwindcss/oxide-linux-arm-gnueabihf@4.1.2": + resolution: + { integrity: sha512-w3wsK1ChOLeQ3gFOiwabtWU5e8fY3P1Ss8jR3IFIn/V0va3ir//hZ8AwURveS4oK1Pu6b8i+yxesT4qWnLVUow== } + engines: { node: ">= 10" } + cpu: [arm] + os: [linux] + + "@tailwindcss/oxide-linux-arm64-gnu@4.1.2": + resolution: + { integrity: sha512-oY/u+xJHpndTj7B5XwtmXGk8mQ1KALMfhjWMMpE8pdVAznjJsF5KkCceJ4Fmn5lS1nHMCwZum5M3/KzdmwDMdw== } + engines: { node: ">= 10" } + cpu: [arm64] + os: [linux] + + "@tailwindcss/oxide-linux-arm64-musl@4.1.2": + resolution: + { integrity: sha512-k7G6vcRK/D+JOWqnKzKN/yQq1q4dCkI49fMoLcfs2pVcaUAXEqCP9NmA8Jv+XahBv5DtDjSAY3HJbjosEdKczg== } + engines: { node: ">= 10" } + cpu: [arm64] + os: [linux] + + "@tailwindcss/oxide-linux-x64-gnu@4.1.2": + resolution: + { integrity: sha512-fLL+c678TkYKgkDLLNxSjPPK/SzTec7q/E5pTwvpTqrth867dftV4ezRyhPM5PaiCqX651Y8Yk0wRQMcWUGnmQ== } + engines: { node: ">= 10" } + cpu: [x64] + os: [linux] + + "@tailwindcss/oxide-linux-x64-musl@4.1.2": + resolution: + { integrity: sha512-0tU1Vjd1WucZ2ooq6y4nI9xyTSaH2g338bhrqk+2yzkMHskBm+pMsOCfY7nEIvALkA1PKPOycR4YVdlV7Czo+A== } + engines: { node: ">= 10" } + cpu: [x64] + os: [linux] + + "@tailwindcss/oxide-win32-arm64-msvc@4.1.2": + resolution: + { integrity: sha512-r8QaMo3QKiHqUcn+vXYCypCEha+R0sfYxmaZSgZshx9NfkY+CHz91aS2xwNV/E4dmUDkTPUag7sSdiCHPzFVTg== } + engines: { node: ">= 10" } + cpu: [arm64] + os: [win32] + + "@tailwindcss/oxide-win32-x64-msvc@4.1.2": + resolution: + { integrity: sha512-lYCdkPxh9JRHXoBsPE8Pu/mppUsC2xihYArNAESub41PKhHTnvn6++5RpmFM+GLSt3ewyS8fwCVvht7ulWm6cw== } + engines: { node: ">= 10" } + cpu: [x64] + os: [win32] + + "@tailwindcss/oxide@4.1.2": + resolution: + { integrity: sha512-Zwz//1QKo6+KqnCKMT7lA4bspGfwEgcPAHlSthmahtgrpKDfwRGk8PKQrW8Zg/ofCDIlg6EtjSTKSxxSufC+CQ== } + engines: { node: ">= 10" } + + "@tailwindcss/postcss@4.1.2": + resolution: + { integrity: sha512-vgkMo6QRhG6uv97im6Y4ExDdq71y9v2IGZc+0wn7lauQFYJM/1KdUVhrOkexbUso8tUsMOWALxyHVkQEbsM7gw== } + + "@tybys/wasm-util@0.9.0": + resolution: + { integrity: sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw== } + + "@types/estree@1.0.7": + resolution: + { integrity: sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ== } + + "@types/json-schema@7.0.15": + resolution: + { integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== } + + "@types/json5@0.0.29": + resolution: + { integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== } + + "@types/node@22.14.0": + resolution: + { integrity: sha512-Kmpl+z84ILoG+3T/zQFyAJsU6EPTmOCj8/2+83fSN6djd6I4o7uOuGIH6vq3PrjY5BGitSbFuMN18j3iknubbA== } + + "@types/react-dom@19.1.1": + resolution: + { integrity: sha512-jFf/woGTVTjUJsl2O7hcopJ1r0upqoq/vIOoCj0yLh3RIXxWcljlpuZ+vEBRXsymD1jhfeJrlyTy/S1UW+4y1w== } + peerDependencies: + "@types/react": ^19.0.0 + + "@types/react@19.1.0": + resolution: + { integrity: sha512-UaicktuQI+9UKyA4njtDOGBD/67t8YEBt2xdfqu8+gP9hqPUPsiXlNPcpS2gVdjmis5GKPG3fCxbQLVgxsQZ8w== } + + "@typescript-eslint/eslint-plugin@8.29.0": + resolution: + { integrity: sha512-PAIpk/U7NIS6H7TEtN45SPGLQaHNgB7wSjsQV/8+KYokAb2T/gloOA/Bee2yd4/yKVhPKe5LlaUGhAZk5zmSaQ== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + peerDependencies: + "@typescript-eslint/parser": ^8.0.0 || ^8.0.0-alpha.0 + eslint: ^8.57.0 || ^9.0.0 + typescript: ">=4.8.4 <5.9.0" + + "@typescript-eslint/parser@8.29.0": + resolution: + { integrity: sha512-8C0+jlNJOwQso2GapCVWWfW/rzaq7Lbme+vGUFKE31djwNncIpgXD7Cd4weEsDdkoZDjH0lwwr3QDQFuyrMg9g== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: ">=4.8.4 <5.9.0" + + "@typescript-eslint/scope-manager@8.29.0": + resolution: + { integrity: sha512-aO1PVsq7Gm+tcghabUpzEnVSFMCU4/nYIgC2GOatJcllvWfnhrgW0ZEbnTxm36QsikmCN1K/6ZgM7fok2I7xNw== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + + "@typescript-eslint/type-utils@8.29.0": + resolution: + { integrity: sha512-ahaWQ42JAOx+NKEf5++WC/ua17q5l+j1GFrbbpVKzFL/tKVc0aYY8rVSYUpUvt2hUP1YBr7mwXzx+E/DfUWI9Q== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: ">=4.8.4 <5.9.0" + + "@typescript-eslint/types@8.29.0": + resolution: + { integrity: sha512-wcJL/+cOXV+RE3gjCyl/V2G877+2faqvlgtso/ZRbTCnZazh0gXhe+7gbAnfubzN2bNsBtZjDvlh7ero8uIbzg== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + + "@typescript-eslint/typescript-estree@8.29.0": + resolution: + { integrity: sha512-yOfen3jE9ISZR/hHpU/bmNvTtBW1NjRbkSFdZOksL1N+ybPEE7UVGMwqvS6CP022Rp00Sb0tdiIkhSCe6NI8ow== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + peerDependencies: + typescript: ">=4.8.4 <5.9.0" + + "@typescript-eslint/utils@8.29.0": + resolution: + { integrity: sha512-gX/A0Mz9Bskm8avSWFcK0gP7cZpbY4AIo6B0hWYFCaIsz750oaiWR4Jr2CI+PQhfW1CpcQr9OlfPS+kMFegjXA== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: ">=4.8.4 <5.9.0" + + "@typescript-eslint/visitor-keys@8.29.0": + resolution: + { integrity: sha512-Sne/pVz8ryR03NFK21VpN88dZ2FdQXOlq3VIklbrTYEt8yXtRFr9tvUhqvCeKjqYk5FSim37sHbooT6vzBTZcg== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + + "@unrs/resolver-binding-darwin-arm64@1.5.0": + resolution: + { integrity: sha512-YmocNlEcX/AgJv8gI41bhjMOTcKcea4D2nRIbZj+MhRtSH5+vEU8r/pFuTuoF+JjVplLsBueU+CILfBPVISyGQ== } + cpu: [arm64] + os: [darwin] + + "@unrs/resolver-binding-darwin-x64@1.5.0": + resolution: + { integrity: sha512-qpUrXgH4e/0xu1LOhPEdfgSY3vIXOxDQv370NEL8npN8h40HcQDA+Pl2r4HBW6tTXezWIjxUFcP7tj529RZtDw== } + cpu: [x64] + os: [darwin] + + "@unrs/resolver-binding-freebsd-x64@1.5.0": + resolution: + { integrity: sha512-3tX8r8vgjvZzaJZB4jvxUaaFCDCb3aWDCpZN3EjhGnnwhztslI05KSG5NY/jNjlcZ5QWZ7dEZZ/rNBFsmTaSPw== } + cpu: [x64] + os: [freebsd] + + "@unrs/resolver-binding-linux-arm-gnueabihf@1.5.0": + resolution: + { integrity: sha512-FH+ixzBKaUU9fWOj3TYO+Yn/eO6kYvMLV9eNJlJlkU7OgrxkCmiMS6wUbyT0KA3FOZGxnEQ2z3/BHgYm2jqeLA== } + cpu: [arm] + os: [linux] + + "@unrs/resolver-binding-linux-arm-musleabihf@1.5.0": + resolution: + { integrity: sha512-pxCgXMgwB/4PfqFQg73lMhmWwcC0j5L+dNXhZoz/0ek0iS/oAWl65fxZeT/OnU7fVs52MgdP2q02EipqJJXHSg== } + cpu: [arm] + os: [linux] + + "@unrs/resolver-binding-linux-arm64-gnu@1.5.0": + resolution: + { integrity: sha512-FX2FV7vpLE/+Z0NZX9/1pwWud5Wocm/2PgpUXbT5aSV3QEB10kBPJAzssOQylvdj8mOHoKl5pVkXpbCwww/T2g== } + cpu: [arm64] + os: [linux] + + "@unrs/resolver-binding-linux-arm64-musl@1.5.0": + resolution: + { integrity: sha512-+gF97xst1BZb28T3nwwzEtq2ewCoMDGKsenYsZuvpmNrW0019G1iUAunZN+FG55L21y+uP7zsGX06OXDQ/viKw== } + cpu: [arm64] + os: [linux] + + "@unrs/resolver-binding-linux-ppc64-gnu@1.5.0": + resolution: + { integrity: sha512-5bEmVcQw9js8JYM2LkUBw5SeELSIxX+qKf9bFrfFINKAp4noZ//hUxLpbF7u/3gTBN1GsER6xOzIZlw/VTdXtA== } + cpu: [ppc64] + os: [linux] + + "@unrs/resolver-binding-linux-riscv64-gnu@1.5.0": + resolution: + { integrity: sha512-GGk/8TPUsf1Q99F+lzMdjE6sGL26uJCwQ9TlvBs8zR3cLQNw/MIumPN7zrs3GFGySjnwXc8gA6J3HKbejywmqA== } + cpu: [riscv64] + os: [linux] + + "@unrs/resolver-binding-linux-s390x-gnu@1.5.0": + resolution: + { integrity: sha512-5uRkFYYVNAeVaA4W/CwugjFN3iDOHCPqsBLCCOoJiMfFMMz4evBRsg+498OFa9w6VcTn2bD5aI+RRayaIgk2Sw== } + cpu: [s390x] + os: [linux] + + "@unrs/resolver-binding-linux-x64-gnu@1.5.0": + resolution: + { integrity: sha512-j905CZH3nehYy6NimNqC2B14pxn4Ltd7guKMyPTzKehbFXTUgihQS/ZfHQTdojkMzbSwBOSgq1dOrY+IpgxDsA== } + cpu: [x64] + os: [linux] + + "@unrs/resolver-binding-linux-x64-musl@1.5.0": + resolution: + { integrity: sha512-dmLevQTuzQRwu5A+mvj54R5aye5I4PVKiWqGxg8tTaYP2k2oTs/3Mo8mgnhPk28VoYCi0fdFYpgzCd4AJndQvQ== } + cpu: [x64] + os: [linux] + + "@unrs/resolver-binding-wasm32-wasi@1.5.0": + resolution: + { integrity: sha512-LtJMhwu7avhoi+kKfAZOKN773RtzLBVVF90YJbB0wyMpUj9yQPeA+mteVUI9P70OG/opH47FeV5AWeaNWWgqJg== } + engines: { node: ">=14.0.0" } + cpu: [wasm32] + + "@unrs/resolver-binding-win32-arm64-msvc@1.5.0": + resolution: + { integrity: sha512-FTZBxLL4SO1mgIM86KykzJmPeTPisBDHQV6xtfDXbTMrentuZ6SdQKJUV5BWaoUK3p8kIULlrCcucqdCnk8Npg== } + cpu: [arm64] + os: [win32] + + "@unrs/resolver-binding-win32-ia32-msvc@1.5.0": + resolution: + { integrity: sha512-i5bB7vJ1waUsFciU/FKLd4Zw0VnAkvhiJ4//jYQXyDUuiLKodmtQZVTcOPU7pp97RrNgCFtXfC1gnvj/DHPJTw== } + cpu: [ia32] + os: [win32] + + "@unrs/resolver-binding-win32-x64-msvc@1.5.0": + resolution: + { integrity: sha512-wAvXp4k7jhioi4SebXW/yfzzYwsUCr9kIX4gCsUFKpCTUf8Mi7vScJXI3S+kupSUf0LbVHudR8qBbe2wFMSNUw== } + cpu: [x64] + os: [win32] + + acorn-jsx@5.3.2: + resolution: + { integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== } + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn@8.14.1: + resolution: + { integrity: sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg== } + engines: { node: ">=0.4.0" } + hasBin: true + + ajv@6.12.6: + resolution: + { integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== } + + ansi-styles@4.3.0: + resolution: + { integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== } + engines: { node: ">=8" } + + argparse@2.0.1: + resolution: + { integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== } + + aria-hidden@1.2.4: + resolution: + { integrity: sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A== } + engines: { node: ">=10" } + + aria-query@5.3.2: + resolution: + { integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw== } + engines: { node: ">= 0.4" } + + array-buffer-byte-length@1.0.2: + resolution: + { integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw== } + engines: { node: ">= 0.4" } + + array-includes@3.1.8: + resolution: + { integrity: sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ== } + engines: { node: ">= 0.4" } + + array.prototype.findlast@1.2.5: + resolution: + { integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ== } + engines: { node: ">= 0.4" } + + array.prototype.findlastindex@1.2.6: + resolution: + { integrity: sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ== } + engines: { node: ">= 0.4" } + + array.prototype.flat@1.3.3: + resolution: + { integrity: sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg== } + engines: { node: ">= 0.4" } + + array.prototype.flatmap@1.3.3: + resolution: + { integrity: sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg== } + engines: { node: ">= 0.4" } + + array.prototype.tosorted@1.1.4: + resolution: + { integrity: sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA== } + engines: { node: ">= 0.4" } + + arraybuffer.prototype.slice@1.0.4: + resolution: + { integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ== } + engines: { node: ">= 0.4" } + + ast-types-flow@0.0.8: + resolution: + { integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ== } + + async-function@1.0.0: + resolution: + { integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA== } + engines: { node: ">= 0.4" } + + asynckit@0.4.0: + resolution: + { integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== } + + available-typed-arrays@1.0.7: + resolution: + { integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ== } + engines: { node: ">= 0.4" } + + axe-core@4.10.3: + resolution: + { integrity: sha512-Xm7bpRXnDSX2YE2YFfBk2FnF0ep6tmG7xPh8iHee8MIcrgq762Nkce856dYtJYLkuIoYZvGfTs/PbZhideTcEg== } + engines: { node: ">=4" } + + axios@1.8.4: + resolution: + { integrity: sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw== } + + axobject-query@4.1.0: + resolution: + { integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ== } + engines: { node: ">= 0.4" } + + balanced-match@1.0.2: + resolution: + { integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== } + + brace-expansion@1.1.11: + resolution: + { integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== } + + brace-expansion@2.0.1: + resolution: + { integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== } + + braces@3.0.3: + resolution: + { integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== } + engines: { node: ">=8" } + + busboy@1.6.0: + resolution: + { integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA== } + engines: { node: ">=10.16.0" } + + call-bind-apply-helpers@1.0.2: + resolution: + { integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ== } + engines: { node: ">= 0.4" } + + call-bind@1.0.8: + resolution: + { integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww== } + engines: { node: ">= 0.4" } + + call-bound@1.0.4: + resolution: + { integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg== } + engines: { node: ">= 0.4" } + + callsites@3.1.0: + resolution: + { integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== } + engines: { node: ">=6" } + + caniuse-lite@1.0.30001714: + resolution: + { integrity: sha512-mtgapdwDLSSBnCI3JokHM7oEQBLxiJKVRtg10AxM1AyeiKcM96f0Mkbqeq+1AbiCtvMcHRulAAEMu693JrSWqg== } + + chalk@4.1.2: + resolution: + { integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== } + engines: { node: ">=10" } + + class-variance-authority@0.7.1: + resolution: + { integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg== } + + client-only@0.0.1: + resolution: + { integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA== } + + clsx@2.1.1: + resolution: + { integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA== } + engines: { node: ">=6" } + + color-convert@2.0.1: + resolution: + { integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== } + engines: { node: ">=7.0.0" } + + color-name@1.1.4: + resolution: + { integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== } + + color-string@1.9.1: + resolution: + { integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg== } + + color@4.2.3: + resolution: + { integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A== } + engines: { node: ">=12.5.0" } + + combined-stream@1.0.8: + resolution: + { integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== } + engines: { node: ">= 0.8" } + + concat-map@0.0.1: + resolution: + { integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== } + + cookie@0.4.2: + resolution: + { integrity: sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== } + engines: { node: ">= 0.6" } + + cross-spawn@7.0.6: + resolution: + { integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA== } + engines: { node: ">= 8" } + + csstype@3.1.3: + resolution: + { integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw== } + + damerau-levenshtein@1.0.8: + resolution: + { integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA== } + + data-view-buffer@1.0.2: + resolution: + { integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ== } + engines: { node: ">= 0.4" } + + data-view-byte-length@1.0.2: + resolution: + { integrity: sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ== } + engines: { node: ">= 0.4" } + + data-view-byte-offset@1.0.1: + resolution: + { integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ== } + engines: { node: ">= 0.4" } + + date-fns@4.1.0: + resolution: + { integrity: sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg== } + + debug@3.2.7: + resolution: + { integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== } + peerDependencies: + supports-color: "*" + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.4.0: + resolution: + { integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA== } + engines: { node: ">=6.0" } + peerDependencies: + supports-color: "*" + peerDependenciesMeta: + supports-color: + optional: true + + decimal.js@10.5.0: + resolution: + { integrity: sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw== } + + deep-is@0.1.4: + resolution: + { integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== } + + define-data-property@1.1.4: + resolution: + { integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A== } + engines: { node: ">= 0.4" } + + define-properties@1.2.1: + resolution: + { integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg== } + engines: { node: ">= 0.4" } + + delayed-stream@1.0.0: + resolution: + { integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== } + engines: { node: ">=0.4.0" } + + detect-libc@2.0.3: + resolution: + { integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw== } + engines: { node: ">=8" } + + detect-node-es@1.1.0: + resolution: + { integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ== } + + doctrine@2.1.0: + resolution: + { integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== } + engines: { node: ">=0.10.0" } + + dunder-proto@1.0.1: + resolution: + { integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A== } + engines: { node: ">= 0.4" } + + emoji-regex@9.2.2: + resolution: + { integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== } + + enhanced-resolve@5.18.1: + resolution: + { integrity: sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg== } + engines: { node: ">=10.13.0" } + + es-abstract@1.23.9: + resolution: + { integrity: sha512-py07lI0wjxAC/DcfK1S6G7iANonniZwTISvdPzk9hzeH0IZIshbuuFxLIU96OyF89Yb9hiqWn8M/bY83KY5vzA== } + engines: { node: ">= 0.4" } + + es-define-property@1.0.1: + resolution: + { integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g== } + engines: { node: ">= 0.4" } + + es-errors@1.3.0: + resolution: + { integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== } + engines: { node: ">= 0.4" } + + es-iterator-helpers@1.2.1: + resolution: + { integrity: sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w== } + engines: { node: ">= 0.4" } + + es-object-atoms@1.1.1: + resolution: + { integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA== } + engines: { node: ">= 0.4" } + + es-set-tostringtag@2.1.0: + resolution: + { integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA== } + engines: { node: ">= 0.4" } + + es-shim-unscopables@1.1.0: + resolution: + { integrity: sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw== } + engines: { node: ">= 0.4" } + + es-to-primitive@1.3.0: + resolution: + { integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g== } + engines: { node: ">= 0.4" } + + escape-string-regexp@4.0.0: + resolution: + { integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== } + engines: { node: ">=10" } + + eslint-config-next@15.2.4: + resolution: + { integrity: sha512-v4gYjd4eYIme8qzaJItpR5MMBXJ0/YV07u7eb50kEnlEmX7yhOjdUdzz70v4fiINYRjLf8X8TbogF0k7wlz6sA== } + peerDependencies: + eslint: ^7.23.0 || ^8.0.0 || ^9.0.0 + typescript: ">=3.3.1" + peerDependenciesMeta: + typescript: + optional: true + + eslint-config-prettier@9.1.0: + resolution: + { integrity: sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw== } + hasBin: true + peerDependencies: + eslint: ">=7.0.0" + + eslint-import-resolver-node@0.3.9: + resolution: + { integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g== } + + eslint-import-resolver-typescript@3.10.0: + resolution: + { integrity: sha512-aV3/dVsT0/H9BtpNwbaqvl+0xGMRGzncLyhm793NFGvbwGGvzyAykqWZ8oZlZuGwuHkwJjhWJkG1cM3ynvd2pQ== } + engines: { node: ^14.18.0 || >=16.0.0 } + peerDependencies: + eslint: "*" + eslint-plugin-import: "*" + eslint-plugin-import-x: "*" + peerDependenciesMeta: + eslint-plugin-import: + optional: true + eslint-plugin-import-x: + optional: true + + eslint-module-utils@2.12.0: + resolution: + { integrity: sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg== } + engines: { node: ">=4" } + peerDependencies: + "@typescript-eslint/parser": "*" + eslint: "*" + eslint-import-resolver-node: "*" + eslint-import-resolver-typescript: "*" + eslint-import-resolver-webpack: "*" + peerDependenciesMeta: + "@typescript-eslint/parser": + optional: true + eslint: + optional: true + eslint-import-resolver-node: + optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true + + eslint-plugin-import@2.31.0: + resolution: + { integrity: sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A== } + engines: { node: ">=4" } + peerDependencies: + "@typescript-eslint/parser": "*" + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9 + peerDependenciesMeta: + "@typescript-eslint/parser": + optional: true + + eslint-plugin-jsx-a11y@6.10.2: + resolution: + { integrity: sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q== } + engines: { node: ">=4.0" } + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9 + + eslint-plugin-prettier@5.2.6: + resolution: + { integrity: sha512-mUcf7QG2Tjk7H055Jk0lGBjbgDnfrvqjhXh9t2xLMSCjZVcw9Rb1V6sVNXO0th3jgeO7zllWPTNRil3JW94TnQ== } + engines: { node: ^14.18.0 || >=16.0.0 } + peerDependencies: + "@types/eslint": ">=8.0.0" + eslint: ">=8.0.0" + eslint-config-prettier: ">= 7.0.0 <10.0.0 || >=10.1.0" + prettier: ">=3.0.0" + peerDependenciesMeta: + "@types/eslint": + optional: true + eslint-config-prettier: + optional: true + + eslint-plugin-react-hooks@5.2.0: + resolution: + { integrity: sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg== } + engines: { node: ">=10" } + peerDependencies: + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 + + eslint-plugin-react@7.37.5: + resolution: + { integrity: sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA== } + engines: { node: ">=4" } + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7 + + eslint-scope@8.3.0: + resolution: + { integrity: sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + + eslint-visitor-keys@3.4.3: + resolution: + { integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== } + engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 } + + eslint-visitor-keys@4.2.0: + resolution: + { integrity: sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + + eslint@9.23.0: + resolution: + { integrity: sha512-jV7AbNoFPAY1EkFYpLq5bslU9NLNO8xnEeQXwErNibVryjk67wHVmddTBilc5srIttJDBrB0eMHKZBFbSIABCw== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + hasBin: true + peerDependencies: + jiti: "*" + peerDependenciesMeta: + jiti: + optional: true + + espree@10.3.0: + resolution: + { integrity: sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + + esquery@1.6.0: + resolution: + { integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg== } + engines: { node: ">=0.10" } + + esrecurse@4.3.0: + resolution: + { integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== } + engines: { node: ">=4.0" } + + estraverse@5.3.0: + resolution: + { integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== } + engines: { node: ">=4.0" } + + esutils@2.0.3: + resolution: + { integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== } + engines: { node: ">=0.10.0" } + + fast-deep-equal@3.1.3: + resolution: + { integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== } + + fast-diff@1.3.0: + resolution: + { integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw== } + + fast-glob@3.3.1: + resolution: + { integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg== } + engines: { node: ">=8.6.0" } + + fast-glob@3.3.3: + resolution: + { integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg== } + engines: { node: ">=8.6.0" } + + fast-json-stable-stringify@2.1.0: + resolution: + { integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== } + + fast-levenshtein@2.0.6: + resolution: + { integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== } + + fastq@1.19.1: + resolution: + { integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ== } + + fdir@6.4.3: + resolution: + { integrity: sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw== } + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + file-entry-cache@8.0.0: + resolution: + { integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ== } + engines: { node: ">=16.0.0" } + + fill-range@7.1.1: + resolution: + { integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg== } + engines: { node: ">=8" } + + find-up@5.0.0: + resolution: + { integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== } + engines: { node: ">=10" } + + flat-cache@4.0.1: + resolution: + { integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw== } + engines: { node: ">=16" } + + flatted@3.3.3: + resolution: + { integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg== } + + follow-redirects@1.15.9: + resolution: + { integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ== } + engines: { node: ">=4.0" } + peerDependencies: + debug: "*" + peerDependenciesMeta: + debug: + optional: true + + for-each@0.3.5: + resolution: + { integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg== } + engines: { node: ">= 0.4" } + + form-data@4.0.2: + resolution: + { integrity: sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w== } + engines: { node: ">= 6" } + + framer-motion@12.7.3: + resolution: + { integrity: sha512-dNT4l5gEnUo2ytXLUBUf6AI21dZ77TMclDKE3ElaIHZ8m90nJ/NCcExW51zdSIaS0RhAS5iXcF7bEIxZe8XG2g== } + peerDependencies: + "@emotion/is-prop-valid": "*" + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + "@emotion/is-prop-valid": + optional: true + react: + optional: true + react-dom: + optional: true + + function-bind@1.1.2: + resolution: + { integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== } + + function.prototype.name@1.1.8: + resolution: + { integrity: sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q== } + engines: { node: ">= 0.4" } + + functions-have-names@1.2.3: + resolution: + { integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== } + + get-intrinsic@1.3.0: + resolution: + { integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ== } + engines: { node: ">= 0.4" } + + get-nonce@1.0.1: + resolution: + { integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q== } + engines: { node: ">=6" } + + get-proto@1.0.1: + resolution: + { integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g== } + engines: { node: ">= 0.4" } + + get-symbol-description@1.1.0: + resolution: + { integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg== } + engines: { node: ">= 0.4" } + + get-tsconfig@4.10.0: + resolution: + { integrity: sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A== } + + glob-parent@5.1.2: + resolution: + { integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== } + engines: { node: ">= 6" } + + glob-parent@6.0.2: + resolution: + { integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== } + engines: { node: ">=10.13.0" } + + globals@11.12.0: + resolution: + { integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== } + engines: { node: ">=4" } + + globals@14.0.0: + resolution: + { integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ== } + engines: { node: ">=18" } + + globalthis@1.0.4: + resolution: + { integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ== } + engines: { node: ">= 0.4" } + + gopd@1.2.0: + resolution: + { integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg== } + engines: { node: ">= 0.4" } + + graceful-fs@4.2.11: + resolution: + { integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== } + + graphemer@1.4.0: + resolution: + { integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== } + + has-bigints@1.1.0: + resolution: + { integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg== } + engines: { node: ">= 0.4" } + + has-flag@4.0.0: + resolution: + { integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== } + engines: { node: ">=8" } + + has-property-descriptors@1.0.2: + resolution: + { integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg== } + + has-proto@1.2.0: + resolution: + { integrity: sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ== } + engines: { node: ">= 0.4" } + + has-symbols@1.1.0: + resolution: + { integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ== } + engines: { node: ">= 0.4" } + + has-tostringtag@1.0.2: + resolution: + { integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw== } + engines: { node: ">= 0.4" } + + hasown@2.0.2: + resolution: + { integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== } + engines: { node: ">= 0.4" } + + ignore@5.3.2: + resolution: + { integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g== } + engines: { node: ">= 4" } + + import-fresh@3.3.1: + resolution: + { integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ== } + engines: { node: ">=6" } + + imurmurhash@0.1.4: + resolution: + { integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== } + engines: { node: ">=0.8.19" } + + internal-slot@1.1.0: + resolution: + { integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw== } + engines: { node: ">= 0.4" } + + intl-messageformat@10.7.16: + resolution: + { integrity: sha512-UmdmHUmp5CIKKjSoE10la5yfU+AYJAaiYLsodbjL4lji83JNvgOQUjGaGhGrpFCb0Uh7sl7qfP1IyILa8Z40ug== } + + is-array-buffer@3.0.5: + resolution: + { integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A== } + engines: { node: ">= 0.4" } + + is-arrayish@0.3.2: + resolution: + { integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== } + + is-async-function@2.1.1: + resolution: + { integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ== } + engines: { node: ">= 0.4" } + + is-bigint@1.1.0: + resolution: + { integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ== } + engines: { node: ">= 0.4" } + + is-boolean-object@1.2.2: + resolution: + { integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A== } + engines: { node: ">= 0.4" } + + is-bun-module@2.0.0: + resolution: + { integrity: sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ== } + + is-callable@1.2.7: + resolution: + { integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== } + engines: { node: ">= 0.4" } + + is-core-module@2.16.1: + resolution: + { integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w== } + engines: { node: ">= 0.4" } + + is-data-view@1.0.2: + resolution: + { integrity: sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw== } + engines: { node: ">= 0.4" } + + is-date-object@1.1.0: + resolution: + { integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg== } + engines: { node: ">= 0.4" } + + is-extglob@2.1.1: + resolution: + { integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== } + engines: { node: ">=0.10.0" } + + is-finalizationregistry@1.1.1: + resolution: + { integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg== } + engines: { node: ">= 0.4" } + + is-generator-function@1.1.0: + resolution: + { integrity: sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ== } + engines: { node: ">= 0.4" } + + is-glob@4.0.3: + resolution: + { integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== } + engines: { node: ">=0.10.0" } + + is-map@2.0.3: + resolution: + { integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw== } + engines: { node: ">= 0.4" } + + is-number-object@1.1.1: + resolution: + { integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw== } + engines: { node: ">= 0.4" } + + is-number@7.0.0: + resolution: + { integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== } + engines: { node: ">=0.12.0" } + + is-regex@1.2.1: + resolution: + { integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g== } + engines: { node: ">= 0.4" } + + is-set@2.0.3: + resolution: + { integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg== } + engines: { node: ">= 0.4" } + + is-shared-array-buffer@1.0.4: + resolution: + { integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A== } + engines: { node: ">= 0.4" } + + is-string@1.1.1: + resolution: + { integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA== } + engines: { node: ">= 0.4" } + + is-symbol@1.1.1: + resolution: + { integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w== } + engines: { node: ">= 0.4" } + + is-typed-array@1.1.15: + resolution: + { integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ== } + engines: { node: ">= 0.4" } + + is-weakmap@2.0.2: + resolution: + { integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w== } + engines: { node: ">= 0.4" } + + is-weakref@1.1.1: + resolution: + { integrity: sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew== } + engines: { node: ">= 0.4" } + + is-weakset@2.0.4: + resolution: + { integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ== } + engines: { node: ">= 0.4" } + + isarray@2.0.5: + resolution: + { integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== } + + isexe@2.0.0: + resolution: + { integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== } + + iterator.prototype@1.1.5: + resolution: + { integrity: sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g== } + engines: { node: ">= 0.4" } + + jiti@2.4.2: + resolution: + { integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A== } + hasBin: true + + js-tokens@4.0.0: + resolution: + { integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== } + + js-yaml@4.1.0: + resolution: + { integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== } + hasBin: true + + jsesc@3.1.0: + resolution: + { integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA== } + engines: { node: ">=6" } + hasBin: true + + json-buffer@3.0.1: + resolution: + { integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== } + + json-schema-traverse@0.4.1: + resolution: + { integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== } + + json-stable-stringify-without-jsonify@1.0.1: + resolution: + { integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== } + + json5@1.0.2: + resolution: + { integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA== } + hasBin: true + + jsx-ast-utils@3.3.5: + resolution: + { integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ== } + engines: { node: ">=4.0" } + + keyv@4.5.4: + resolution: + { integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw== } + + language-subtag-registry@0.3.23: + resolution: + { integrity: sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ== } + + language-tags@1.0.9: + resolution: + { integrity: sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA== } + engines: { node: ">=0.10" } + + levn@0.4.1: + resolution: + { integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== } + engines: { node: ">= 0.8.0" } + + lightningcss-darwin-arm64@1.29.2: + resolution: + { integrity: sha512-cK/eMabSViKn/PG8U/a7aCorpeKLMlK0bQeNHmdb7qUnBkNPnL+oV5DjJUo0kqWsJUapZsM4jCfYItbqBDvlcA== } + engines: { node: ">= 12.0.0" } + cpu: [arm64] + os: [darwin] + + lightningcss-darwin-x64@1.29.2: + resolution: + { integrity: sha512-j5qYxamyQw4kDXX5hnnCKMf3mLlHvG44f24Qyi2965/Ycz829MYqjrVg2H8BidybHBp9kom4D7DR5VqCKDXS0w== } + engines: { node: ">= 12.0.0" } + cpu: [x64] + os: [darwin] + + lightningcss-freebsd-x64@1.29.2: + resolution: + { integrity: sha512-wDk7M2tM78Ii8ek9YjnY8MjV5f5JN2qNVO+/0BAGZRvXKtQrBC4/cn4ssQIpKIPP44YXw6gFdpUF+Ps+RGsCwg== } + engines: { node: ">= 12.0.0" } + cpu: [x64] + os: [freebsd] + + lightningcss-linux-arm-gnueabihf@1.29.2: + resolution: + { integrity: sha512-IRUrOrAF2Z+KExdExe3Rz7NSTuuJ2HvCGlMKoquK5pjvo2JY4Rybr+NrKnq0U0hZnx5AnGsuFHjGnNT14w26sg== } + engines: { node: ">= 12.0.0" } + cpu: [arm] + os: [linux] + + lightningcss-linux-arm64-gnu@1.29.2: + resolution: + { integrity: sha512-KKCpOlmhdjvUTX/mBuaKemp0oeDIBBLFiU5Fnqxh1/DZ4JPZi4evEH7TKoSBFOSOV3J7iEmmBaw/8dpiUvRKlQ== } + engines: { node: ">= 12.0.0" } + cpu: [arm64] + os: [linux] + + lightningcss-linux-arm64-musl@1.29.2: + resolution: + { integrity: sha512-Q64eM1bPlOOUgxFmoPUefqzY1yV3ctFPE6d/Vt7WzLW4rKTv7MyYNky+FWxRpLkNASTnKQUaiMJ87zNODIrrKQ== } + engines: { node: ">= 12.0.0" } + cpu: [arm64] + os: [linux] + + lightningcss-linux-x64-gnu@1.29.2: + resolution: + { integrity: sha512-0v6idDCPG6epLXtBH/RPkHvYx74CVziHo6TMYga8O2EiQApnUPZsbR9nFNrg2cgBzk1AYqEd95TlrsL7nYABQg== } + engines: { node: ">= 12.0.0" } + cpu: [x64] + os: [linux] + + lightningcss-linux-x64-musl@1.29.2: + resolution: + { integrity: sha512-rMpz2yawkgGT8RULc5S4WiZopVMOFWjiItBT7aSfDX4NQav6M44rhn5hjtkKzB+wMTRlLLqxkeYEtQ3dd9696w== } + engines: { node: ">= 12.0.0" } + cpu: [x64] + os: [linux] + + lightningcss-win32-arm64-msvc@1.29.2: + resolution: + { integrity: sha512-nL7zRW6evGQqYVu/bKGK+zShyz8OVzsCotFgc7judbt6wnB2KbiKKJwBE4SGoDBQ1O94RjW4asrCjQL4i8Fhbw== } + engines: { node: ">= 12.0.0" } + cpu: [arm64] + os: [win32] + + lightningcss-win32-x64-msvc@1.29.2: + resolution: + { integrity: sha512-EdIUW3B2vLuHmv7urfzMI/h2fmlnOQBk1xlsDxkN1tCWKjNFjfLhGxYk8C8mzpSfr+A6jFFIi8fU6LbQGsRWjA== } + engines: { node: ">= 12.0.0" } + cpu: [x64] + os: [win32] + + lightningcss@1.29.2: + resolution: + { integrity: sha512-6b6gd/RUXKaw5keVdSEtqFVdzWnU5jMxTUjA2bVcMNPLwSQ08Sv/UodBVtETLCn7k4S1Ibxwh7k68IwLZPgKaA== } + engines: { node: ">= 12.0.0" } + + locate-path@6.0.0: + resolution: + { integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== } + engines: { node: ">=10" } + + lodash.merge@4.6.2: + resolution: + { integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== } + + loose-envify@1.4.0: + resolution: + { integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== } + hasBin: true + + lucide-react@0.487.0: + resolution: + { integrity: sha512-aKqhOQ+YmFnwq8dWgGjOuLc8V1R9/c/yOd+zDY4+ohsR2Jo05lSGc3WsstYPIzcTpeosN7LoCkLReUUITvaIvw== } + peerDependencies: + react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + math-intrinsics@1.1.0: + resolution: + { integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g== } + engines: { node: ">= 0.4" } + + merge2@1.4.1: + resolution: + { integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== } + engines: { node: ">= 8" } + + micromatch@4.0.8: + resolution: + { integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA== } + engines: { node: ">=8.6" } + + mime-db@1.52.0: + resolution: + { integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== } + engines: { node: ">= 0.6" } + + mime-types@2.1.35: + resolution: + { integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== } + engines: { node: ">= 0.6" } + + minimatch@3.1.2: + resolution: + { integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== } + + minimatch@9.0.5: + resolution: + { integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow== } + engines: { node: ">=16 || 14 >=14.17" } + + minimist@1.2.8: + resolution: + { integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== } + + motion-dom@12.7.3: + resolution: + { integrity: sha512-IjMt1YJHrvyvruFvmpmd6bGXXGCvmygrnvSb3aZ8KhOzF4H3PulU+cMBzH+U8TBJHjC/mnmJFRIA1Cu4vBfcBA== } + + motion-utils@12.7.2: + resolution: + { integrity: sha512-XhZwqctxyJs89oX00zn3OGCuIIpVevbTa+u82usWBC6pSHUd2AoNWiYa7Du8tJxJy9TFbZ82pcn5t7NOm1PHAw== } + + ms@2.1.3: + resolution: + { integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== } + + nanoid@3.3.11: + resolution: + { integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w== } + engines: { node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1 } + hasBin: true + + nanoid@5.1.5: + resolution: + { integrity: sha512-Ir/+ZpE9fDsNH0hQ3C68uyThDXzYcim2EqcZ8zn8Chtt1iylPT9xXJB0kPCnqzgcEGikO9RxSrh63MsmVCU7Fw== } + engines: { node: ^18 || >=20 } + hasBin: true + + natural-compare@1.4.0: + resolution: + { integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== } + + negotiator@1.0.0: + resolution: + { integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg== } + engines: { node: ">= 0.6" } + + next-intl@4.0.2: + resolution: + { integrity: sha512-3cKVflwdrqxCOvAL+DtGN68qR802i0PEj0dttkAD5IK5XxOjugQs4yU8aSakvPMbkOrhEJ+89z5lG2EAqi7Gkw== } + peerDependencies: + next: ^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || >=19.0.0-rc <19.0.0 || ^19.0.0 + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + + 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 + + next@15.2.4: + resolution: + { integrity: sha512-VwL+LAaPSxEkd3lU2xWbgEOtrM8oedmyhBqaVNmgKB+GvZlCy9rgaEc+y2on0wv+l0oSFqLtYD6dcC1eAedUaQ== } + engines: { node: ^18.18.0 || ^19.8.0 || >= 20.0.0 } + hasBin: true + peerDependencies: + "@opentelemetry/api": ^1.1.0 + "@playwright/test": ^1.41.2 + babel-plugin-react-compiler: "*" + react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 + react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 + sass: ^1.3.0 + peerDependenciesMeta: + "@opentelemetry/api": + optional: true + "@playwright/test": + optional: true + babel-plugin-react-compiler: + optional: true + sass: + optional: true + + nookies@2.5.2: + resolution: + { integrity: sha512-x0TRSaosAEonNKyCrShoUaJ5rrT5KHRNZ5DwPCuizjgrnkpE5DRf3VL7AyyQin4htict92X1EQ7ejDbaHDVdYA== } + + object-assign@4.1.1: + resolution: + { integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== } + engines: { node: ">=0.10.0" } + + object-inspect@1.13.4: + resolution: + { integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew== } + engines: { node: ">= 0.4" } + + object-keys@1.1.1: + resolution: + { integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== } + engines: { node: ">= 0.4" } + + object.assign@4.1.7: + resolution: + { integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw== } + engines: { node: ">= 0.4" } + + object.entries@1.1.9: + resolution: + { integrity: sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw== } + engines: { node: ">= 0.4" } + + object.fromentries@2.0.8: + resolution: + { integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ== } + engines: { node: ">= 0.4" } + + object.groupby@1.0.3: + resolution: + { integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ== } + engines: { node: ">= 0.4" } + + object.values@1.2.1: + resolution: + { integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA== } + engines: { node: ">= 0.4" } + + optionator@0.9.4: + resolution: + { integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g== } + engines: { node: ">= 0.8.0" } + + own-keys@1.0.1: + resolution: + { integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg== } + engines: { node: ">= 0.4" } + + p-limit@3.1.0: + resolution: + { integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== } + engines: { node: ">=10" } + + p-locate@5.0.0: + resolution: + { integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== } + engines: { node: ">=10" } + + parent-module@1.0.1: + resolution: + { integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== } + engines: { node: ">=6" } + + path-exists@4.0.0: + resolution: + { integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== } + engines: { node: ">=8" } + + path-key@3.1.1: + resolution: + { integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== } + engines: { node: ">=8" } + + path-parse@1.0.7: + resolution: + { integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== } + + picocolors@1.1.1: + resolution: + { integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== } + + picomatch@2.3.1: + resolution: + { integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== } + engines: { node: ">=8.6" } + + picomatch@4.0.2: + resolution: + { integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg== } + engines: { node: ">=12" } + + possible-typed-array-names@1.1.0: + resolution: + { integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg== } + engines: { node: ">= 0.4" } + + postcss@8.4.31: + resolution: + { integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ== } + engines: { node: ^10 || ^12 || >=14 } + + postcss@8.5.3: + resolution: + { integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A== } + engines: { node: ^10 || ^12 || >=14 } + + prelude-ls@1.2.1: + resolution: + { integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== } + engines: { node: ">= 0.8.0" } + + prettier-linter-helpers@1.0.0: + resolution: + { integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== } + engines: { node: ">=6.0.0" } + + prettier-plugin-sort-json@4.1.1: + resolution: + { integrity: sha512-uJ49wCzwJ/foKKV4tIPxqi4jFFvwUzw4oACMRG2dcmDhBKrxBv0L2wSKkAqHCmxKCvj0xcCZS4jO2kSJO/tRJw== } + engines: { node: ">=18.0.0" } + peerDependencies: + prettier: ^3.0.0 + + prettier@3.5.3: + resolution: + { integrity: sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw== } + engines: { node: ">=14" } + hasBin: true + + prop-types@15.8.1: + resolution: + { integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== } + + proxy-from-env@1.1.0: + resolution: + { integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== } + + punycode@2.3.1: + resolution: + { integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== } + engines: { node: ">=6" } + + queue-microtask@1.2.3: + resolution: + { integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== } + + react-country-flag@3.1.0: + resolution: + { integrity: sha512-JWQFw1efdv9sTC+TGQvTKXQg1NKbDU2mBiAiRWcKM9F1sK+/zjhP2yGmm8YDddWyZdXVkR8Md47rPMJmo4YO5g== } + engines: { node: ">=12" } + peerDependencies: + react: ">=16" + + react-dom@19.1.0: + resolution: + { integrity: sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g== } + peerDependencies: + react: ^19.1.0 + + react-hook-form@7.55.0: + resolution: + { integrity: sha512-XRnjsH3GVMQz1moZTW53MxfoWN7aDpUg/GpVNc4A3eXRVNdGXfbzJ4vM4aLQ8g6XCUh1nIbx70aaNCl7kxnjog== } + engines: { node: ">=18.0.0" } + peerDependencies: + react: ^16.8.0 || ^17 || ^18 || ^19 + + react-is@16.13.1: + resolution: + { integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== } + + 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.6.3: + resolution: + { integrity: sha512-pnAi91oOk8g8ABQKGF5/M9qxmmOPxaAnopyTHYfqYEwJhyFrbbBtHuSgtKEoH0jpcxx5o3hXqH1mNd9/Oi+8iQ== } + 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-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.1.0: + resolution: + { integrity: sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg== } + engines: { node: ">=0.10.0" } + + reflect.getprototypeof@1.0.10: + resolution: + { integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw== } + engines: { node: ">= 0.4" } + + regexp.prototype.flags@1.5.4: + resolution: + { integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA== } + engines: { node: ">= 0.4" } + + resolve-from@4.0.0: + resolution: + { integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== } + engines: { node: ">=4" } + + resolve-pkg-maps@1.0.0: + resolution: + { integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw== } + + resolve@1.22.10: + resolution: + { integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w== } + engines: { node: ">= 0.4" } + hasBin: true + + resolve@2.0.0-next.5: + resolution: + { integrity: sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA== } + hasBin: true + + reusify@1.1.0: + resolution: + { integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw== } + engines: { iojs: ">=1.0.0", node: ">=0.10.0" } + + run-parallel@1.2.0: + resolution: + { integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== } + + safe-array-concat@1.1.3: + resolution: + { integrity: sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q== } + engines: { node: ">=0.4" } + + safe-push-apply@1.0.0: + resolution: + { integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA== } + engines: { node: ">= 0.4" } + + safe-regex-test@1.1.0: + resolution: + { integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw== } + engines: { node: ">= 0.4" } + + scheduler@0.26.0: + resolution: + { integrity: sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA== } + + semver@6.3.1: + resolution: + { integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== } + hasBin: true + + semver@7.7.1: + resolution: + { integrity: sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA== } + engines: { node: ">=10" } + hasBin: true + + set-cookie-parser@2.7.1: + resolution: + { integrity: sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ== } + + set-function-length@1.2.2: + resolution: + { integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg== } + engines: { node: ">= 0.4" } + + set-function-name@2.0.2: + resolution: + { integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ== } + engines: { node: ">= 0.4" } + + set-proto@1.0.0: + resolution: + { integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw== } + engines: { node: ">= 0.4" } + + sharp@0.33.5: + resolution: + { integrity: sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw== } + engines: { node: ^18.17.0 || ^20.3.0 || >=21.0.0 } + + shebang-command@2.0.0: + resolution: + { integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== } + engines: { node: ">=8" } + + shebang-regex@3.0.0: + resolution: + { integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== } + engines: { node: ">=8" } + + side-channel-list@1.0.0: + resolution: + { integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA== } + engines: { node: ">= 0.4" } + + side-channel-map@1.0.1: + resolution: + { integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA== } + engines: { node: ">= 0.4" } + + side-channel-weakmap@1.0.2: + resolution: + { integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A== } + engines: { node: ">= 0.4" } + + side-channel@1.1.0: + resolution: + { integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw== } + engines: { node: ">= 0.4" } + + simple-swizzle@0.2.2: + resolution: + { integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg== } + + sonner@2.0.3: + resolution: + { integrity: sha512-njQ4Hht92m0sMqqHVDL32V2Oun9W1+PHO9NDv9FHfJjT3JT22IG4Jpo3FPQy+mouRKCXFWO+r67v6MrHX2zeIA== } + 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: + resolution: + { integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA== } + engines: { node: ">=0.10.0" } + + stable-hash@0.0.5: + resolution: + { integrity: sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA== } + + streamsearch@1.1.0: + resolution: + { integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg== } + engines: { node: ">=10.0.0" } + + string.prototype.includes@2.0.1: + resolution: + { integrity: sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg== } + engines: { node: ">= 0.4" } + + string.prototype.matchall@4.0.12: + resolution: + { integrity: sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA== } + engines: { node: ">= 0.4" } + + string.prototype.repeat@1.0.0: + resolution: + { integrity: sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w== } + + string.prototype.trim@1.2.10: + resolution: + { integrity: sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA== } + engines: { node: ">= 0.4" } + + string.prototype.trimend@1.0.9: + resolution: + { integrity: sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ== } + engines: { node: ">= 0.4" } + + string.prototype.trimstart@1.0.8: + resolution: + { integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg== } + engines: { node: ">= 0.4" } + + strip-bom@3.0.0: + resolution: + { integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== } + engines: { node: ">=4" } + + strip-json-comments@3.1.1: + resolution: + { integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== } + engines: { node: ">=8" } + + styled-jsx@5.1.6: + resolution: + { integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA== } + engines: { node: ">= 12.0.0" } + peerDependencies: + "@babel/core": "*" + babel-plugin-macros: "*" + react: ">= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0" + peerDependenciesMeta: + "@babel/core": + optional: true + babel-plugin-macros: + optional: true + + supports-color@7.2.0: + resolution: + { integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== } + engines: { node: ">=8" } + + supports-preserve-symlinks-flag@1.0.0: + resolution: + { integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== } + engines: { node: ">= 0.4" } + + synckit@0.11.4: + resolution: + { integrity: sha512-Q/XQKRaJiLiFIBNN+mndW7S/RHxvwzuZS6ZwmRzUBqJBv/5QIKCEwkBC8GBf8EQJKYnaFs0wOZbKTXBPj8L9oQ== } + engines: { node: ^14.18.0 || >=16.0.0 } + + tailwind-merge@3.2.0: + resolution: + { integrity: sha512-FQT/OVqCD+7edmmJpsgCsY820RTD5AkBryuG5IUqR5YQZSdj5xlH5nLgH7YPths7WsLPSpSBNneJdM8aS8aeFA== } + + tailwindcss@4.1.2: + resolution: + { integrity: sha512-VCsK+fitIbQF7JlxXaibFhxrPq4E2hDcG8apzHUdWFMCQWD8uLdlHg4iSkZ53cgLCCcZ+FZK7vG8VjvLcnBgKw== } + + tapable@2.2.1: + resolution: + { integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== } + engines: { node: ">=6" } + + tinyglobby@0.2.12: + resolution: + { integrity: sha512-qkf4trmKSIiMTs/E63cxH+ojC2unam7rJ0WrauAzpT3ECNTxGRMlaXxVbfxMUC/w0LaYk6jQ4y/nGR9uBO3tww== } + engines: { node: ">=12.0.0" } + + to-regex-range@5.0.1: + resolution: + { integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== } + engines: { node: ">=8.0" } + + ts-api-utils@2.1.0: + resolution: + { integrity: sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ== } + engines: { node: ">=18.12" } + peerDependencies: + typescript: ">=4.8.4" + + tsconfig-paths@3.15.0: + resolution: + { integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg== } + + tslib@2.8.1: + resolution: + { integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== } + + tw-animate-css@1.2.5: + resolution: + { integrity: sha512-ABzjfgVo+fDbhRREGL4KQZUqqdPgvc5zVrLyeW9/6mVqvaDepXc7EvedA+pYmMnIOsUAQMwcWzNvom26J2qYvQ== } + + type-check@0.4.0: + resolution: + { integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== } + engines: { node: ">= 0.8.0" } + + typed-array-buffer@1.0.3: + resolution: + { integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw== } + engines: { node: ">= 0.4" } + + typed-array-byte-length@1.0.3: + resolution: + { integrity: sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg== } + engines: { node: ">= 0.4" } + + typed-array-byte-offset@1.0.4: + resolution: + { integrity: sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ== } + engines: { node: ">= 0.4" } + + typed-array-length@1.0.7: + resolution: + { integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg== } + engines: { node: ">= 0.4" } + + typescript@5.8.2: + resolution: + { integrity: sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ== } + engines: { node: ">=14.17" } + hasBin: true + + unbox-primitive@1.1.0: + resolution: + { integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw== } + engines: { node: ">= 0.4" } + + undici-types@6.21.0: + resolution: + { integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ== } + + unrs-resolver@1.5.0: + resolution: + { integrity: sha512-6aia3Oy7SEe0MuUGQm2nsyob0L2+g57w178K5SE/3pvSGAIp28BB2O921fKx424Ahc/gQ6v0DXFbhcpyhGZdOA== } + + uri-js@4.4.1: + 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-intl@4.0.2: + resolution: + { integrity: sha512-6RAP/5KJMRzLMLS25/BVh2u09cRK8S6HRGc1RnZvqR547qAKZCpjYylOqMPU9eNIirAiKoGmsoUPa7JrlaA/yg== } + peerDependencies: + react: ^17.0.0 || ^18.0.0 || >=19.0.0-rc <19.0.0 || ^19.0.0 + + 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 + + which-boxed-primitive@1.1.1: + resolution: + { integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA== } + engines: { node: ">= 0.4" } + + which-builtin-type@1.2.1: + resolution: + { integrity: sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q== } + engines: { node: ">= 0.4" } + + which-collection@1.0.2: + resolution: + { integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw== } + engines: { node: ">= 0.4" } + + which-typed-array@1.1.19: + resolution: + { integrity: sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw== } + engines: { node: ">= 0.4" } + + which@2.0.2: + resolution: + { integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== } + engines: { node: ">= 8" } + hasBin: true + + word-wrap@1.2.5: + resolution: + { integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA== } + engines: { node: ">=0.10.0" } + + yocto-queue@0.1.0: + resolution: + { integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== } + engines: { node: ">=10" } + + zod@3.24.2: + resolution: + { integrity: sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ== } + + zustand@5.0.3: + resolution: + { integrity: sha512-14fwWQtU3pH4dE0dOpdMiWjddcH+QzKIgk1cl8epwSE7yag43k/AD/m4L6+K7DytAOr9gGBe3/EXj9g7cdostg== } + engines: { node: ">=12.20.0" } + peerDependencies: + "@types/react": ">=18.0.0" + immer: ">=9.0.6" + react: ">=18.0.0" + use-sync-external-store: ">=1.2.0" + peerDependenciesMeta: + "@types/react": + optional: true + immer: + optional: true + react: + optional: true + use-sync-external-store: + optional: true + +snapshots: + "@alloc/quick-lru@5.2.0": {} + + "@babel/code-frame@7.26.2": + dependencies: + "@babel/helper-validator-identifier": 7.25.9 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + "@babel/generator@7.27.0": + dependencies: + "@babel/parser": 7.27.0 + "@babel/types": 7.27.0 + "@jridgewell/gen-mapping": 0.3.8 + "@jridgewell/trace-mapping": 0.3.25 + jsesc: 3.1.0 + + "@babel/helper-string-parser@7.25.9": {} + + "@babel/helper-validator-identifier@7.25.9": {} + + "@babel/parser@7.27.0": + dependencies: + "@babel/types": 7.27.0 + + "@babel/template@7.27.0": + dependencies: + "@babel/code-frame": 7.26.2 + "@babel/parser": 7.27.0 + "@babel/types": 7.27.0 + + "@babel/traverse@7.27.0": + dependencies: + "@babel/code-frame": 7.26.2 + "@babel/generator": 7.27.0 + "@babel/parser": 7.27.0 + "@babel/template": 7.27.0 + "@babel/types": 7.27.0 + debug: 4.4.0 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + + "@babel/types@7.27.0": + dependencies: + "@babel/helper-string-parser": 7.25.9 + "@babel/helper-validator-identifier": 7.25.9 + + "@emnapi/core@1.4.3": + dependencies: + "@emnapi/wasi-threads": 1.0.2 + tslib: 2.8.1 + optional: true + + "@emnapi/runtime@1.4.3": + dependencies: + tslib: 2.8.1 + optional: true + + "@emnapi/wasi-threads@1.0.2": + dependencies: + tslib: 2.8.1 + optional: true + + "@eslint-community/eslint-utils@4.6.1(eslint@9.23.0(jiti@2.4.2))": + dependencies: + eslint: 9.23.0(jiti@2.4.2) + eslint-visitor-keys: 3.4.3 + + "@eslint-community/regexpp@4.12.1": {} + + "@eslint/config-array@0.19.2": + dependencies: + "@eslint/object-schema": 2.1.6 + debug: 4.4.0 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + + "@eslint/config-helpers@0.2.1": {} + + "@eslint/core@0.12.0": + dependencies: + "@types/json-schema": 7.0.15 + + "@eslint/core@0.13.0": + dependencies: + "@types/json-schema": 7.0.15 + + "@eslint/eslintrc@3.3.1": + dependencies: + ajv: 6.12.6 + debug: 4.4.0 + espree: 10.3.0 + globals: 14.0.0 + ignore: 5.3.2 + import-fresh: 3.3.1 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + "@eslint/js@9.23.0": {} + + "@eslint/object-schema@2.1.6": {} + + "@eslint/plugin-kit@0.2.8": + dependencies: + "@eslint/core": 0.13.0 + levn: 0.4.1 + + "@floating-ui/core@1.6.9": + dependencies: + "@floating-ui/utils": 0.2.9 + + "@floating-ui/dom@1.6.13": + dependencies: + "@floating-ui/core": 1.6.9 + "@floating-ui/utils": 0.2.9 + + "@floating-ui/react-dom@2.1.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0)": + dependencies: + "@floating-ui/dom": 1.6.13 + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + + "@floating-ui/utils@0.2.9": {} + + "@formatjs/ecma402-abstract@2.3.4": + dependencies: + "@formatjs/fast-memoize": 2.2.7 + "@formatjs/intl-localematcher": 0.6.1 + decimal.js: 10.5.0 + tslib: 2.8.1 + + "@formatjs/fast-memoize@2.2.7": + dependencies: + tslib: 2.8.1 + + "@formatjs/icu-messageformat-parser@2.11.2": + dependencies: + "@formatjs/ecma402-abstract": 2.3.4 + "@formatjs/icu-skeleton-parser": 1.8.14 + tslib: 2.8.1 + + "@formatjs/icu-skeleton-parser@1.8.14": + dependencies: + "@formatjs/ecma402-abstract": 2.3.4 + tslib: 2.8.1 + + "@formatjs/intl-localematcher@0.5.10": + dependencies: + tslib: 2.8.1 + + "@formatjs/intl-localematcher@0.6.1": + dependencies: + tslib: 2.8.1 + + "@hookform/resolvers@5.0.1(react-hook-form@7.55.0(react@19.1.0))": + dependencies: + "@standard-schema/utils": 0.3.0 + react-hook-form: 7.55.0(react@19.1.0) + + "@humanfs/core@0.19.1": {} + + "@humanfs/node@0.16.6": + dependencies: + "@humanfs/core": 0.19.1 + "@humanwhocodes/retry": 0.3.1 + + "@humanwhocodes/module-importer@1.0.1": {} + + "@humanwhocodes/retry@0.3.1": {} + + "@humanwhocodes/retry@0.4.2": {} + + "@ianvs/prettier-plugin-sort-imports@4.4.1(prettier@3.5.3)": + dependencies: + "@babel/generator": 7.27.0 + "@babel/parser": 7.27.0 + "@babel/traverse": 7.27.0 + "@babel/types": 7.27.0 + prettier: 3.5.3 + semver: 7.7.1 + transitivePeerDependencies: + - supports-color + + "@img/sharp-darwin-arm64@0.33.5": + optionalDependencies: + "@img/sharp-libvips-darwin-arm64": 1.0.4 + optional: true + + "@img/sharp-darwin-x64@0.33.5": + optionalDependencies: + "@img/sharp-libvips-darwin-x64": 1.0.4 + optional: true + + "@img/sharp-libvips-darwin-arm64@1.0.4": + optional: true + + "@img/sharp-libvips-darwin-x64@1.0.4": + optional: true + + "@img/sharp-libvips-linux-arm64@1.0.4": + optional: true + + "@img/sharp-libvips-linux-arm@1.0.5": + optional: true + + "@img/sharp-libvips-linux-s390x@1.0.4": + optional: true + + "@img/sharp-libvips-linux-x64@1.0.4": + optional: true + + "@img/sharp-libvips-linuxmusl-arm64@1.0.4": + optional: true + + "@img/sharp-libvips-linuxmusl-x64@1.0.4": + optional: true + + "@img/sharp-linux-arm64@0.33.5": + optionalDependencies: + "@img/sharp-libvips-linux-arm64": 1.0.4 + optional: true + + "@img/sharp-linux-arm@0.33.5": + optionalDependencies: + "@img/sharp-libvips-linux-arm": 1.0.5 + optional: true + + "@img/sharp-linux-s390x@0.33.5": + optionalDependencies: + "@img/sharp-libvips-linux-s390x": 1.0.4 + optional: true + + "@img/sharp-linux-x64@0.33.5": + optionalDependencies: + "@img/sharp-libvips-linux-x64": 1.0.4 + optional: true + + "@img/sharp-linuxmusl-arm64@0.33.5": + optionalDependencies: + "@img/sharp-libvips-linuxmusl-arm64": 1.0.4 + optional: true + + "@img/sharp-linuxmusl-x64@0.33.5": + optionalDependencies: + "@img/sharp-libvips-linuxmusl-x64": 1.0.4 + optional: true + + "@img/sharp-wasm32@0.33.5": + dependencies: + "@emnapi/runtime": 1.4.3 + optional: true + + "@img/sharp-win32-ia32@0.33.5": + optional: true + + "@img/sharp-win32-x64@0.33.5": + optional: true + + "@jridgewell/gen-mapping@0.3.8": + dependencies: + "@jridgewell/set-array": 1.2.1 + "@jridgewell/sourcemap-codec": 1.5.0 + "@jridgewell/trace-mapping": 0.3.25 + + "@jridgewell/resolve-uri@3.1.2": {} + + "@jridgewell/set-array@1.2.1": {} + + "@jridgewell/sourcemap-codec@1.5.0": {} + + "@jridgewell/trace-mapping@0.3.25": + dependencies: + "@jridgewell/resolve-uri": 3.1.2 + "@jridgewell/sourcemap-codec": 1.5.0 + + "@napi-rs/wasm-runtime@0.2.9": + dependencies: + "@emnapi/core": 1.4.3 + "@emnapi/runtime": 1.4.3 + "@tybys/wasm-util": 0.9.0 + optional: true + + "@next/env@15.2.4": {} + + "@next/eslint-plugin-next@15.2.4": + dependencies: + fast-glob: 3.3.1 + + "@next/swc-darwin-arm64@15.2.4": + optional: true + + "@next/swc-darwin-x64@15.2.4": + optional: true + + "@next/swc-linux-arm64-gnu@15.2.4": + optional: true + + "@next/swc-linux-arm64-musl@15.2.4": + optional: true + + "@next/swc-linux-x64-gnu@15.2.4": + optional: true + + "@next/swc-linux-x64-musl@15.2.4": + optional: true + + "@next/swc-win32-arm64-msvc@15.2.4": + optional: true + + "@next/swc-win32-x64-msvc@15.2.4": + optional: true + + "@nodelib/fs.scandir@2.1.5": + dependencies: + "@nodelib/fs.stat": 2.0.5 + run-parallel: 1.2.0 + + "@nodelib/fs.stat@2.0.5": {} + + "@nodelib/fs.walk@1.2.8": + dependencies: + "@nodelib/fs.scandir": 2.1.5 + fastq: 1.19.1 + + "@nolyfill/is-core-module@1.0.39": {} + + "@pkgr/core@0.2.4": {} + + "@radix-ui/number@1.1.1": {} + + "@radix-ui/primitive@1.1.2": {} + + "@radix-ui/react-arrow@1.1.3(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)": + dependencies: + "@radix-ui/react-primitive": 2.0.3(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + "@types/react": 19.1.0 + "@types/react-dom": 19.1.1(@types/react@19.1.0) + + "@radix-ui/react-aspect-ratio@1.1.3(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)": + dependencies: + "@radix-ui/react-primitive": 2.0.3(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + "@types/react": 19.1.0 + "@types/react-dom": 19.1.1(@types/react@19.1.0) + + "@radix-ui/react-avatar@1.1.4(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)": + dependencies: + "@radix-ui/react-context": 1.1.2(@types/react@19.1.0)(react@19.1.0) + "@radix-ui/react-primitive": 2.0.3(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + "@radix-ui/react-use-callback-ref": 1.1.1(@types/react@19.1.0)(react@19.1.0) + "@radix-ui/react-use-layout-effect": 1.1.1(@types/react@19.1.0)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + "@types/react": 19.1.0 + "@types/react-dom": 19.1.1(@types/react@19.1.0) + + "@radix-ui/react-collection@1.1.3(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)": + dependencies: + "@radix-ui/react-compose-refs": 1.1.2(@types/react@19.1.0)(react@19.1.0) + "@radix-ui/react-context": 1.1.2(@types/react@19.1.0)(react@19.1.0) + "@radix-ui/react-primitive": 2.0.3(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + "@radix-ui/react-slot": 1.2.0(@types/react@19.1.0)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + "@types/react": 19.1.0 + "@types/react-dom": 19.1.1(@types/react@19.1.0) + + "@radix-ui/react-compose-refs@1.1.2(@types/react@19.1.0)(react@19.1.0)": + dependencies: + react: 19.1.0 + optionalDependencies: + "@types/react": 19.1.0 + + "@radix-ui/react-context@1.1.2(@types/react@19.1.0)(react@19.1.0)": + dependencies: + react: 19.1.0 + optionalDependencies: + "@types/react": 19.1.0 + + "@radix-ui/react-dialog@1.1.7(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)": + dependencies: + "@radix-ui/primitive": 1.1.2 + "@radix-ui/react-compose-refs": 1.1.2(@types/react@19.1.0)(react@19.1.0) + "@radix-ui/react-context": 1.1.2(@types/react@19.1.0)(react@19.1.0) + "@radix-ui/react-dismissable-layer": 1.1.6(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + "@radix-ui/react-focus-guards": 1.1.2(@types/react@19.1.0)(react@19.1.0) + "@radix-ui/react-focus-scope": 1.1.3(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + "@radix-ui/react-id": 1.1.1(@types/react@19.1.0)(react@19.1.0) + "@radix-ui/react-portal": 1.1.5(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + "@radix-ui/react-presence": 1.1.3(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + "@radix-ui/react-primitive": 2.0.3(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + "@radix-ui/react-slot": 1.2.0(@types/react@19.1.0)(react@19.1.0) + "@radix-ui/react-use-controllable-state": 1.1.1(@types/react@19.1.0)(react@19.1.0) + aria-hidden: 1.2.4 + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + react-remove-scroll: 2.6.3(@types/react@19.1.0)(react@19.1.0) + optionalDependencies: + "@types/react": 19.1.0 + "@types/react-dom": 19.1.1(@types/react@19.1.0) + + "@radix-ui/react-direction@1.1.1(@types/react@19.1.0)(react@19.1.0)": + dependencies: + react: 19.1.0 + optionalDependencies: + "@types/react": 19.1.0 + + "@radix-ui/react-dismissable-layer@1.1.6(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)": + dependencies: + "@radix-ui/primitive": 1.1.2 + "@radix-ui/react-compose-refs": 1.1.2(@types/react@19.1.0)(react@19.1.0) + "@radix-ui/react-primitive": 2.0.3(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + "@radix-ui/react-use-callback-ref": 1.1.1(@types/react@19.1.0)(react@19.1.0) + "@radix-ui/react-use-escape-keydown": 1.1.1(@types/react@19.1.0)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + "@types/react": 19.1.0 + "@types/react-dom": 19.1.1(@types/react@19.1.0) + + "@radix-ui/react-dropdown-menu@2.1.7(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)": + dependencies: + "@radix-ui/primitive": 1.1.2 + "@radix-ui/react-compose-refs": 1.1.2(@types/react@19.1.0)(react@19.1.0) + "@radix-ui/react-context": 1.1.2(@types/react@19.1.0)(react@19.1.0) + "@radix-ui/react-id": 1.1.1(@types/react@19.1.0)(react@19.1.0) + "@radix-ui/react-menu": 2.1.7(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + "@radix-ui/react-primitive": 2.0.3(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + "@radix-ui/react-use-controllable-state": 1.1.1(@types/react@19.1.0)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + "@types/react": 19.1.0 + "@types/react-dom": 19.1.1(@types/react@19.1.0) + + "@radix-ui/react-focus-guards@1.1.2(@types/react@19.1.0)(react@19.1.0)": + dependencies: + react: 19.1.0 + optionalDependencies: + "@types/react": 19.1.0 + + "@radix-ui/react-focus-scope@1.1.3(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)": + dependencies: + "@radix-ui/react-compose-refs": 1.1.2(@types/react@19.1.0)(react@19.1.0) + "@radix-ui/react-primitive": 2.0.3(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + "@radix-ui/react-use-callback-ref": 1.1.1(@types/react@19.1.0)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + "@types/react": 19.1.0 + "@types/react-dom": 19.1.1(@types/react@19.1.0) + + "@radix-ui/react-id@1.1.1(@types/react@19.1.0)(react@19.1.0)": + dependencies: + "@radix-ui/react-use-layout-effect": 1.1.1(@types/react@19.1.0)(react@19.1.0) + react: 19.1.0 + optionalDependencies: + "@types/react": 19.1.0 + + "@radix-ui/react-label@2.1.3(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)": + dependencies: + "@radix-ui/react-primitive": 2.0.3(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + "@types/react": 19.1.0 + "@types/react-dom": 19.1.1(@types/react@19.1.0) + + "@radix-ui/react-menu@2.1.7(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)": + dependencies: + "@radix-ui/primitive": 1.1.2 + "@radix-ui/react-collection": 1.1.3(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + "@radix-ui/react-compose-refs": 1.1.2(@types/react@19.1.0)(react@19.1.0) + "@radix-ui/react-context": 1.1.2(@types/react@19.1.0)(react@19.1.0) + "@radix-ui/react-direction": 1.1.1(@types/react@19.1.0)(react@19.1.0) + "@radix-ui/react-dismissable-layer": 1.1.6(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + "@radix-ui/react-focus-guards": 1.1.2(@types/react@19.1.0)(react@19.1.0) + "@radix-ui/react-focus-scope": 1.1.3(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + "@radix-ui/react-id": 1.1.1(@types/react@19.1.0)(react@19.1.0) + "@radix-ui/react-popper": 1.2.3(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + "@radix-ui/react-portal": 1.1.5(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + "@radix-ui/react-presence": 1.1.3(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + "@radix-ui/react-primitive": 2.0.3(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + "@radix-ui/react-roving-focus": 1.1.3(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + "@radix-ui/react-slot": 1.2.0(@types/react@19.1.0)(react@19.1.0) + "@radix-ui/react-use-callback-ref": 1.1.1(@types/react@19.1.0)(react@19.1.0) + aria-hidden: 1.2.4 + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + react-remove-scroll: 2.6.3(@types/react@19.1.0)(react@19.1.0) + optionalDependencies: + "@types/react": 19.1.0 + "@types/react-dom": 19.1.1(@types/react@19.1.0) + + "@radix-ui/react-popper@1.2.3(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)": + dependencies: + "@floating-ui/react-dom": 2.1.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + "@radix-ui/react-arrow": 1.1.3(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + "@radix-ui/react-compose-refs": 1.1.2(@types/react@19.1.0)(react@19.1.0) + "@radix-ui/react-context": 1.1.2(@types/react@19.1.0)(react@19.1.0) + "@radix-ui/react-primitive": 2.0.3(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + "@radix-ui/react-use-callback-ref": 1.1.1(@types/react@19.1.0)(react@19.1.0) + "@radix-ui/react-use-layout-effect": 1.1.1(@types/react@19.1.0)(react@19.1.0) + "@radix-ui/react-use-rect": 1.1.1(@types/react@19.1.0)(react@19.1.0) + "@radix-ui/react-use-size": 1.1.1(@types/react@19.1.0)(react@19.1.0) + "@radix-ui/rect": 1.1.1 + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + "@types/react": 19.1.0 + "@types/react-dom": 19.1.1(@types/react@19.1.0) + + "@radix-ui/react-portal@1.1.5(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)": + dependencies: + "@radix-ui/react-primitive": 2.0.3(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + "@radix-ui/react-use-layout-effect": 1.1.1(@types/react@19.1.0)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + "@types/react": 19.1.0 + "@types/react-dom": 19.1.1(@types/react@19.1.0) + + "@radix-ui/react-presence@1.1.3(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)": + dependencies: + "@radix-ui/react-compose-refs": 1.1.2(@types/react@19.1.0)(react@19.1.0) + "@radix-ui/react-use-layout-effect": 1.1.1(@types/react@19.1.0)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + "@types/react": 19.1.0 + "@types/react-dom": 19.1.1(@types/react@19.1.0) + + "@radix-ui/react-primitive@2.0.3(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)": + dependencies: + "@radix-ui/react-slot": 1.2.0(@types/react@19.1.0)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + "@types/react": 19.1.0 + "@types/react-dom": 19.1.1(@types/react@19.1.0) + + "@radix-ui/react-progress@1.1.3(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)": + dependencies: + "@radix-ui/react-context": 1.1.2(@types/react@19.1.0)(react@19.1.0) + "@radix-ui/react-primitive": 2.0.3(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + "@types/react": 19.1.0 + "@types/react-dom": 19.1.1(@types/react@19.1.0) + + "@radix-ui/react-roving-focus@1.1.3(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)": + dependencies: + "@radix-ui/primitive": 1.1.2 + "@radix-ui/react-collection": 1.1.3(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + "@radix-ui/react-compose-refs": 1.1.2(@types/react@19.1.0)(react@19.1.0) + "@radix-ui/react-context": 1.1.2(@types/react@19.1.0)(react@19.1.0) + "@radix-ui/react-direction": 1.1.1(@types/react@19.1.0)(react@19.1.0) + "@radix-ui/react-id": 1.1.1(@types/react@19.1.0)(react@19.1.0) + "@radix-ui/react-primitive": 2.0.3(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + "@radix-ui/react-use-callback-ref": 1.1.1(@types/react@19.1.0)(react@19.1.0) + "@radix-ui/react-use-controllable-state": 1.1.1(@types/react@19.1.0)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + "@types/react": 19.1.0 + "@types/react-dom": 19.1.1(@types/react@19.1.0) + + "@radix-ui/react-scroll-area@1.2.4(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)": + dependencies: + "@radix-ui/number": 1.1.1 + "@radix-ui/primitive": 1.1.2 + "@radix-ui/react-compose-refs": 1.1.2(@types/react@19.1.0)(react@19.1.0) + "@radix-ui/react-context": 1.1.2(@types/react@19.1.0)(react@19.1.0) + "@radix-ui/react-direction": 1.1.1(@types/react@19.1.0)(react@19.1.0) + "@radix-ui/react-presence": 1.1.3(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + "@radix-ui/react-primitive": 2.0.3(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + "@radix-ui/react-use-callback-ref": 1.1.1(@types/react@19.1.0)(react@19.1.0) + "@radix-ui/react-use-layout-effect": 1.1.1(@types/react@19.1.0)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + "@types/react": 19.1.0 + "@types/react-dom": 19.1.1(@types/react@19.1.0) + + "@radix-ui/react-select@2.1.7(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)": + dependencies: + "@radix-ui/number": 1.1.1 + "@radix-ui/primitive": 1.1.2 + "@radix-ui/react-collection": 1.1.3(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + "@radix-ui/react-compose-refs": 1.1.2(@types/react@19.1.0)(react@19.1.0) + "@radix-ui/react-context": 1.1.2(@types/react@19.1.0)(react@19.1.0) + "@radix-ui/react-direction": 1.1.1(@types/react@19.1.0)(react@19.1.0) + "@radix-ui/react-dismissable-layer": 1.1.6(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + "@radix-ui/react-focus-guards": 1.1.2(@types/react@19.1.0)(react@19.1.0) + "@radix-ui/react-focus-scope": 1.1.3(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + "@radix-ui/react-id": 1.1.1(@types/react@19.1.0)(react@19.1.0) + "@radix-ui/react-popper": 1.2.3(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + "@radix-ui/react-portal": 1.1.5(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + "@radix-ui/react-primitive": 2.0.3(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + "@radix-ui/react-slot": 1.2.0(@types/react@19.1.0)(react@19.1.0) + "@radix-ui/react-use-callback-ref": 1.1.1(@types/react@19.1.0)(react@19.1.0) + "@radix-ui/react-use-controllable-state": 1.1.1(@types/react@19.1.0)(react@19.1.0) + "@radix-ui/react-use-layout-effect": 1.1.1(@types/react@19.1.0)(react@19.1.0) + "@radix-ui/react-use-previous": 1.1.1(@types/react@19.1.0)(react@19.1.0) + "@radix-ui/react-visually-hidden": 1.1.3(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + aria-hidden: 1.2.4 + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + react-remove-scroll: 2.6.3(@types/react@19.1.0)(react@19.1.0) + optionalDependencies: + "@types/react": 19.1.0 + "@types/react-dom": 19.1.1(@types/react@19.1.0) + + "@radix-ui/react-separator@1.1.3(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)": + dependencies: + "@radix-ui/react-primitive": 2.0.3(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + "@types/react": 19.1.0 + "@types/react-dom": 19.1.1(@types/react@19.1.0) + + "@radix-ui/react-slot@1.2.0(@types/react@19.1.0)(react@19.1.0)": + dependencies: + "@radix-ui/react-compose-refs": 1.1.2(@types/react@19.1.0)(react@19.1.0) + react: 19.1.0 + optionalDependencies: + "@types/react": 19.1.0 + + "@radix-ui/react-switch@1.1.4(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)": + dependencies: + "@radix-ui/primitive": 1.1.2 + "@radix-ui/react-compose-refs": 1.1.2(@types/react@19.1.0)(react@19.1.0) + "@radix-ui/react-context": 1.1.2(@types/react@19.1.0)(react@19.1.0) + "@radix-ui/react-primitive": 2.0.3(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + "@radix-ui/react-use-controllable-state": 1.1.1(@types/react@19.1.0)(react@19.1.0) + "@radix-ui/react-use-previous": 1.1.1(@types/react@19.1.0)(react@19.1.0) + "@radix-ui/react-use-size": 1.1.1(@types/react@19.1.0)(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + "@types/react": 19.1.0 + "@types/react-dom": 19.1.1(@types/react@19.1.0) + + "@radix-ui/react-use-callback-ref@1.1.1(@types/react@19.1.0)(react@19.1.0)": + dependencies: + react: 19.1.0 + optionalDependencies: + "@types/react": 19.1.0 + + "@radix-ui/react-use-controllable-state@1.1.1(@types/react@19.1.0)(react@19.1.0)": + dependencies: + "@radix-ui/react-use-callback-ref": 1.1.1(@types/react@19.1.0)(react@19.1.0) + react: 19.1.0 + optionalDependencies: + "@types/react": 19.1.0 + + "@radix-ui/react-use-escape-keydown@1.1.1(@types/react@19.1.0)(react@19.1.0)": + dependencies: + "@radix-ui/react-use-callback-ref": 1.1.1(@types/react@19.1.0)(react@19.1.0) + react: 19.1.0 + optionalDependencies: + "@types/react": 19.1.0 + + "@radix-ui/react-use-layout-effect@1.1.1(@types/react@19.1.0)(react@19.1.0)": + dependencies: + react: 19.1.0 + optionalDependencies: + "@types/react": 19.1.0 + + "@radix-ui/react-use-previous@1.1.1(@types/react@19.1.0)(react@19.1.0)": + dependencies: + react: 19.1.0 + optionalDependencies: + "@types/react": 19.1.0 + + "@radix-ui/react-use-rect@1.1.1(@types/react@19.1.0)(react@19.1.0)": + dependencies: + "@radix-ui/rect": 1.1.1 + react: 19.1.0 + optionalDependencies: + "@types/react": 19.1.0 + + "@radix-ui/react-use-size@1.1.1(@types/react@19.1.0)(react@19.1.0)": + dependencies: + "@radix-ui/react-use-layout-effect": 1.1.1(@types/react@19.1.0)(react@19.1.0) + react: 19.1.0 + optionalDependencies: + "@types/react": 19.1.0 + + "@radix-ui/react-visually-hidden@1.1.3(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)": + dependencies: + "@radix-ui/react-primitive": 2.0.3(@types/react-dom@19.1.1(@types/react@19.1.0))(@types/react@19.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + optionalDependencies: + "@types/react": 19.1.0 + "@types/react-dom": 19.1.1(@types/react@19.1.0) + + "@radix-ui/rect@1.1.1": {} + + "@rtsao/scc@1.1.0": {} + + "@rushstack/eslint-patch@1.11.0": {} + + "@schummar/icu-type-parser@1.21.5": {} + + "@standard-schema/utils@0.3.0": {} + + "@swc/counter@0.1.3": {} + + "@swc/helpers@0.5.15": + dependencies: + tslib: 2.8.1 + + "@tabler/icons-react@3.31.0(react@19.1.0)": + dependencies: + "@tabler/icons": 3.31.0 + react: 19.1.0 + + "@tabler/icons@3.31.0": {} + + "@tailwindcss/node@4.1.2": + dependencies: + enhanced-resolve: 5.18.1 + jiti: 2.4.2 + lightningcss: 1.29.2 + tailwindcss: 4.1.2 + + "@tailwindcss/oxide-android-arm64@4.1.2": + optional: true + + "@tailwindcss/oxide-darwin-arm64@4.1.2": + optional: true + + "@tailwindcss/oxide-darwin-x64@4.1.2": + optional: true + + "@tailwindcss/oxide-freebsd-x64@4.1.2": + optional: true + + "@tailwindcss/oxide-linux-arm-gnueabihf@4.1.2": + optional: true + + "@tailwindcss/oxide-linux-arm64-gnu@4.1.2": + optional: true + + "@tailwindcss/oxide-linux-arm64-musl@4.1.2": + optional: true + + "@tailwindcss/oxide-linux-x64-gnu@4.1.2": + optional: true + + "@tailwindcss/oxide-linux-x64-musl@4.1.2": + optional: true + + "@tailwindcss/oxide-win32-arm64-msvc@4.1.2": + optional: true + + "@tailwindcss/oxide-win32-x64-msvc@4.1.2": + optional: true + + "@tailwindcss/oxide@4.1.2": + optionalDependencies: + "@tailwindcss/oxide-android-arm64": 4.1.2 + "@tailwindcss/oxide-darwin-arm64": 4.1.2 + "@tailwindcss/oxide-darwin-x64": 4.1.2 + "@tailwindcss/oxide-freebsd-x64": 4.1.2 + "@tailwindcss/oxide-linux-arm-gnueabihf": 4.1.2 + "@tailwindcss/oxide-linux-arm64-gnu": 4.1.2 + "@tailwindcss/oxide-linux-arm64-musl": 4.1.2 + "@tailwindcss/oxide-linux-x64-gnu": 4.1.2 + "@tailwindcss/oxide-linux-x64-musl": 4.1.2 + "@tailwindcss/oxide-win32-arm64-msvc": 4.1.2 + "@tailwindcss/oxide-win32-x64-msvc": 4.1.2 + + "@tailwindcss/postcss@4.1.2": + dependencies: + "@alloc/quick-lru": 5.2.0 + "@tailwindcss/node": 4.1.2 + "@tailwindcss/oxide": 4.1.2 + postcss: 8.5.3 + tailwindcss: 4.1.2 + + "@tybys/wasm-util@0.9.0": + dependencies: + tslib: 2.8.1 + optional: true + + "@types/estree@1.0.7": {} + + "@types/json-schema@7.0.15": {} + + "@types/json5@0.0.29": {} + + "@types/node@22.14.0": + dependencies: + undici-types: 6.21.0 + + "@types/react-dom@19.1.1(@types/react@19.1.0)": + dependencies: + "@types/react": 19.1.0 + + "@types/react@19.1.0": + dependencies: + csstype: 3.1.3 + + "@typescript-eslint/eslint-plugin@8.29.0(@typescript-eslint/parser@8.29.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2)": + dependencies: + "@eslint-community/regexpp": 4.12.1 + "@typescript-eslint/parser": 8.29.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2) + "@typescript-eslint/scope-manager": 8.29.0 + "@typescript-eslint/type-utils": 8.29.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2) + "@typescript-eslint/utils": 8.29.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2) + "@typescript-eslint/visitor-keys": 8.29.0 + eslint: 9.23.0(jiti@2.4.2) + graphemer: 1.4.0 + ignore: 5.3.2 + natural-compare: 1.4.0 + ts-api-utils: 2.1.0(typescript@5.8.2) + typescript: 5.8.2 + transitivePeerDependencies: + - supports-color + + "@typescript-eslint/parser@8.29.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2)": + dependencies: + "@typescript-eslint/scope-manager": 8.29.0 + "@typescript-eslint/types": 8.29.0 + "@typescript-eslint/typescript-estree": 8.29.0(typescript@5.8.2) + "@typescript-eslint/visitor-keys": 8.29.0 + debug: 4.4.0 + eslint: 9.23.0(jiti@2.4.2) + typescript: 5.8.2 + transitivePeerDependencies: + - supports-color + + "@typescript-eslint/scope-manager@8.29.0": + dependencies: + "@typescript-eslint/types": 8.29.0 + "@typescript-eslint/visitor-keys": 8.29.0 + + "@typescript-eslint/type-utils@8.29.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2)": + dependencies: + "@typescript-eslint/typescript-estree": 8.29.0(typescript@5.8.2) + "@typescript-eslint/utils": 8.29.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2) + debug: 4.4.0 + eslint: 9.23.0(jiti@2.4.2) + ts-api-utils: 2.1.0(typescript@5.8.2) + typescript: 5.8.2 + transitivePeerDependencies: + - supports-color + + "@typescript-eslint/types@8.29.0": {} + + "@typescript-eslint/typescript-estree@8.29.0(typescript@5.8.2)": + dependencies: + "@typescript-eslint/types": 8.29.0 + "@typescript-eslint/visitor-keys": 8.29.0 + debug: 4.4.0 + fast-glob: 3.3.3 + is-glob: 4.0.3 + minimatch: 9.0.5 + semver: 7.7.1 + ts-api-utils: 2.1.0(typescript@5.8.2) + typescript: 5.8.2 + transitivePeerDependencies: + - supports-color + + "@typescript-eslint/utils@8.29.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2)": + dependencies: + "@eslint-community/eslint-utils": 4.6.1(eslint@9.23.0(jiti@2.4.2)) + "@typescript-eslint/scope-manager": 8.29.0 + "@typescript-eslint/types": 8.29.0 + "@typescript-eslint/typescript-estree": 8.29.0(typescript@5.8.2) + eslint: 9.23.0(jiti@2.4.2) + typescript: 5.8.2 + transitivePeerDependencies: + - supports-color + + "@typescript-eslint/visitor-keys@8.29.0": + dependencies: + "@typescript-eslint/types": 8.29.0 + eslint-visitor-keys: 4.2.0 + + "@unrs/resolver-binding-darwin-arm64@1.5.0": + optional: true + + "@unrs/resolver-binding-darwin-x64@1.5.0": + optional: true + + "@unrs/resolver-binding-freebsd-x64@1.5.0": + optional: true + + "@unrs/resolver-binding-linux-arm-gnueabihf@1.5.0": + optional: true + + "@unrs/resolver-binding-linux-arm-musleabihf@1.5.0": + optional: true + + "@unrs/resolver-binding-linux-arm64-gnu@1.5.0": + optional: true + + "@unrs/resolver-binding-linux-arm64-musl@1.5.0": + optional: true + + "@unrs/resolver-binding-linux-ppc64-gnu@1.5.0": + optional: true + + "@unrs/resolver-binding-linux-riscv64-gnu@1.5.0": + optional: true + + "@unrs/resolver-binding-linux-s390x-gnu@1.5.0": + optional: true + + "@unrs/resolver-binding-linux-x64-gnu@1.5.0": + optional: true + + "@unrs/resolver-binding-linux-x64-musl@1.5.0": + optional: true + + "@unrs/resolver-binding-wasm32-wasi@1.5.0": + dependencies: + "@napi-rs/wasm-runtime": 0.2.9 + optional: true + + "@unrs/resolver-binding-win32-arm64-msvc@1.5.0": + optional: true + + "@unrs/resolver-binding-win32-ia32-msvc@1.5.0": + optional: true + + "@unrs/resolver-binding-win32-x64-msvc@1.5.0": + optional: true + + acorn-jsx@5.3.2(acorn@8.14.1): + dependencies: + acorn: 8.14.1 + + acorn@8.14.1: {} + + ajv@6.12.6: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + argparse@2.0.1: {} + + aria-hidden@1.2.4: + dependencies: + tslib: 2.8.1 + + aria-query@5.3.2: {} + + array-buffer-byte-length@1.0.2: + dependencies: + call-bound: 1.0.4 + is-array-buffer: 3.0.5 + + array-includes@3.1.8: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + is-string: 1.1.1 + + array.prototype.findlast@1.2.5: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + es-shim-unscopables: 1.1.0 + + array.prototype.findlastindex@1.2.6: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + es-shim-unscopables: 1.1.0 + + array.prototype.flat@1.3.3: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-shim-unscopables: 1.1.0 + + array.prototype.flatmap@1.3.3: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-shim-unscopables: 1.1.0 + + array.prototype.tosorted@1.1.4: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-errors: 1.3.0 + es-shim-unscopables: 1.1.0 + + arraybuffer.prototype.slice@1.0.4: + dependencies: + array-buffer-byte-length: 1.0.2 + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + is-array-buffer: 3.0.5 + + ast-types-flow@0.0.8: {} + + async-function@1.0.0: {} + + asynckit@0.4.0: {} + + available-typed-arrays@1.0.7: + dependencies: + possible-typed-array-names: 1.1.0 + + axe-core@4.10.3: {} + + axios@1.8.4: + dependencies: + follow-redirects: 1.15.9 + form-data: 4.0.2 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + + axobject-query@4.1.0: {} + + balanced-match@1.0.2: {} + + brace-expansion@1.1.11: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@2.0.1: + dependencies: + balanced-match: 1.0.2 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + busboy@1.6.0: + dependencies: + streamsearch: 1.1.0 + + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + call-bind@1.0.8: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + get-intrinsic: 1.3.0 + set-function-length: 1.2.2 + + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + + callsites@3.1.0: {} + + caniuse-lite@1.0.30001714: {} + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + class-variance-authority@0.7.1: + dependencies: + clsx: 2.1.1 + + client-only@0.0.1: {} + + clsx@2.1.1: {} + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + color-string@1.9.1: + dependencies: + color-name: 1.1.4 + simple-swizzle: 0.2.2 + optional: true + + color@4.2.3: + dependencies: + color-convert: 2.0.1 + color-string: 1.9.1 + optional: true + + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + + concat-map@0.0.1: {} + + cookie@0.4.2: {} + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + csstype@3.1.3: {} + + damerau-levenshtein@1.0.8: {} + + data-view-buffer@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + data-view-byte-length@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + data-view-byte-offset@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + date-fns@4.1.0: {} + + debug@3.2.7: + dependencies: + ms: 2.1.3 + + debug@4.4.0: + dependencies: + ms: 2.1.3 + + decimal.js@10.5.0: {} + + deep-is@0.1.4: {} + + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.1 + es-errors: 1.3.0 + gopd: 1.2.0 + + define-properties@1.2.1: + dependencies: + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 + object-keys: 1.1.1 + + delayed-stream@1.0.0: {} + + detect-libc@2.0.3: {} + + detect-node-es@1.1.0: {} + + doctrine@2.1.0: + dependencies: + esutils: 2.0.3 + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + emoji-regex@9.2.2: {} + + enhanced-resolve@5.18.1: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.2.1 + + es-abstract@1.23.9: + dependencies: + array-buffer-byte-length: 1.0.2 + arraybuffer.prototype.slice: 1.0.4 + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + call-bound: 1.0.4 + data-view-buffer: 1.0.2 + data-view-byte-length: 1.0.2 + data-view-byte-offset: 1.0.1 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + es-set-tostringtag: 2.1.0 + es-to-primitive: 1.3.0 + function.prototype.name: 1.1.8 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + get-symbol-description: 1.1.0 + globalthis: 1.0.4 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + has-proto: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + internal-slot: 1.1.0 + is-array-buffer: 3.0.5 + is-callable: 1.2.7 + is-data-view: 1.0.2 + is-regex: 1.2.1 + is-shared-array-buffer: 1.0.4 + is-string: 1.1.1 + is-typed-array: 1.1.15 + is-weakref: 1.1.1 + math-intrinsics: 1.1.0 + object-inspect: 1.13.4 + object-keys: 1.1.1 + object.assign: 4.1.7 + own-keys: 1.0.1 + regexp.prototype.flags: 1.5.4 + safe-array-concat: 1.1.3 + safe-push-apply: 1.0.0 + safe-regex-test: 1.1.0 + set-proto: 1.0.0 + string.prototype.trim: 1.2.10 + string.prototype.trimend: 1.0.9 + string.prototype.trimstart: 1.0.8 + typed-array-buffer: 1.0.3 + typed-array-byte-length: 1.0.3 + typed-array-byte-offset: 1.0.4 + typed-array-length: 1.0.7 + unbox-primitive: 1.1.0 + which-typed-array: 1.1.19 + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-iterator-helpers@1.2.1: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-errors: 1.3.0 + es-set-tostringtag: 2.1.0 + function-bind: 1.1.2 + get-intrinsic: 1.3.0 + globalthis: 1.0.4 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + has-proto: 1.2.0 + has-symbols: 1.1.0 + internal-slot: 1.1.0 + iterator.prototype: 1.1.5 + safe-array-concat: 1.1.3 + + es-object-atoms@1.1.1: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.1.0: + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + es-shim-unscopables@1.1.0: + dependencies: + hasown: 2.0.2 + + es-to-primitive@1.3.0: + dependencies: + is-callable: 1.2.7 + is-date-object: 1.1.0 + is-symbol: 1.1.1 + + escape-string-regexp@4.0.0: {} + + eslint-config-next@15.2.4(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2): + dependencies: + "@next/eslint-plugin-next": 15.2.4 + "@rushstack/eslint-patch": 1.11.0 + "@typescript-eslint/eslint-plugin": 8.29.0(@typescript-eslint/parser@8.29.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2) + "@typescript-eslint/parser": 8.29.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2) + eslint: 9.23.0(jiti@2.4.2) + eslint-import-resolver-node: 0.3.9 + eslint-import-resolver-typescript: 3.10.0(eslint-plugin-import@2.31.0)(eslint@9.23.0(jiti@2.4.2)) + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.29.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(eslint-import-resolver-typescript@3.10.0)(eslint@9.23.0(jiti@2.4.2)) + eslint-plugin-jsx-a11y: 6.10.2(eslint@9.23.0(jiti@2.4.2)) + eslint-plugin-react: 7.37.5(eslint@9.23.0(jiti@2.4.2)) + eslint-plugin-react-hooks: 5.2.0(eslint@9.23.0(jiti@2.4.2)) + optionalDependencies: + typescript: 5.8.2 + transitivePeerDependencies: + - eslint-import-resolver-webpack + - eslint-plugin-import-x + - supports-color + + eslint-config-prettier@9.1.0(eslint@9.23.0(jiti@2.4.2)): + dependencies: + eslint: 9.23.0(jiti@2.4.2) + + eslint-import-resolver-node@0.3.9: + dependencies: + debug: 3.2.7 + is-core-module: 2.16.1 + resolve: 1.22.10 + transitivePeerDependencies: + - supports-color + + eslint-import-resolver-typescript@3.10.0(eslint-plugin-import@2.31.0)(eslint@9.23.0(jiti@2.4.2)): + dependencies: + "@nolyfill/is-core-module": 1.0.39 + debug: 4.4.0 + eslint: 9.23.0(jiti@2.4.2) + get-tsconfig: 4.10.0 + is-bun-module: 2.0.0 + stable-hash: 0.0.5 + tinyglobby: 0.2.12 + unrs-resolver: 1.5.0 + optionalDependencies: + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.29.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(eslint-import-resolver-typescript@3.10.0)(eslint@9.23.0(jiti@2.4.2)) + transitivePeerDependencies: + - supports-color + + eslint-module-utils@2.12.0(@typescript-eslint/parser@8.29.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.0)(eslint@9.23.0(jiti@2.4.2)): + dependencies: + debug: 3.2.7 + optionalDependencies: + "@typescript-eslint/parser": 8.29.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2) + eslint: 9.23.0(jiti@2.4.2) + eslint-import-resolver-node: 0.3.9 + eslint-import-resolver-typescript: 3.10.0(eslint-plugin-import@2.31.0)(eslint@9.23.0(jiti@2.4.2)) + transitivePeerDependencies: + - supports-color + + eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.29.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(eslint-import-resolver-typescript@3.10.0)(eslint@9.23.0(jiti@2.4.2)): + dependencies: + "@rtsao/scc": 1.1.0 + array-includes: 3.1.8 + array.prototype.findlastindex: 1.2.6 + array.prototype.flat: 1.3.3 + array.prototype.flatmap: 1.3.3 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 9.23.0(jiti@2.4.2) + eslint-import-resolver-node: 0.3.9 + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.29.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.0)(eslint@9.23.0(jiti@2.4.2)) + hasown: 2.0.2 + is-core-module: 2.16.1 + is-glob: 4.0.3 + minimatch: 3.1.2 + object.fromentries: 2.0.8 + object.groupby: 1.0.3 + object.values: 1.2.1 + semver: 6.3.1 + string.prototype.trimend: 1.0.9 + tsconfig-paths: 3.15.0 + optionalDependencies: + "@typescript-eslint/parser": 8.29.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2) + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + + eslint-plugin-jsx-a11y@6.10.2(eslint@9.23.0(jiti@2.4.2)): + dependencies: + aria-query: 5.3.2 + array-includes: 3.1.8 + array.prototype.flatmap: 1.3.3 + ast-types-flow: 0.0.8 + axe-core: 4.10.3 + axobject-query: 4.1.0 + damerau-levenshtein: 1.0.8 + emoji-regex: 9.2.2 + eslint: 9.23.0(jiti@2.4.2) + hasown: 2.0.2 + jsx-ast-utils: 3.3.5 + language-tags: 1.0.9 + minimatch: 3.1.2 + object.fromentries: 2.0.8 + safe-regex-test: 1.1.0 + string.prototype.includes: 2.0.1 + + eslint-plugin-prettier@5.2.6(eslint-config-prettier@9.1.0(eslint@9.23.0(jiti@2.4.2)))(eslint@9.23.0(jiti@2.4.2))(prettier@3.5.3): + dependencies: + eslint: 9.23.0(jiti@2.4.2) + prettier: 3.5.3 + prettier-linter-helpers: 1.0.0 + synckit: 0.11.4 + optionalDependencies: + eslint-config-prettier: 9.1.0(eslint@9.23.0(jiti@2.4.2)) + + eslint-plugin-react-hooks@5.2.0(eslint@9.23.0(jiti@2.4.2)): + dependencies: + eslint: 9.23.0(jiti@2.4.2) + + eslint-plugin-react@7.37.5(eslint@9.23.0(jiti@2.4.2)): + dependencies: + array-includes: 3.1.8 + array.prototype.findlast: 1.2.5 + array.prototype.flatmap: 1.3.3 + array.prototype.tosorted: 1.1.4 + doctrine: 2.1.0 + es-iterator-helpers: 1.2.1 + eslint: 9.23.0(jiti@2.4.2) + estraverse: 5.3.0 + hasown: 2.0.2 + jsx-ast-utils: 3.3.5 + minimatch: 3.1.2 + object.entries: 1.1.9 + object.fromentries: 2.0.8 + object.values: 1.2.1 + prop-types: 15.8.1 + resolve: 2.0.0-next.5 + semver: 6.3.1 + string.prototype.matchall: 4.0.12 + string.prototype.repeat: 1.0.0 + + eslint-scope@8.3.0: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-visitor-keys@3.4.3: {} + + eslint-visitor-keys@4.2.0: {} + + eslint@9.23.0(jiti@2.4.2): + dependencies: + "@eslint-community/eslint-utils": 4.6.1(eslint@9.23.0(jiti@2.4.2)) + "@eslint-community/regexpp": 4.12.1 + "@eslint/config-array": 0.19.2 + "@eslint/config-helpers": 0.2.1 + "@eslint/core": 0.12.0 + "@eslint/eslintrc": 3.3.1 + "@eslint/js": 9.23.0 + "@eslint/plugin-kit": 0.2.8 + "@humanfs/node": 0.16.6 + "@humanwhocodes/module-importer": 1.0.1 + "@humanwhocodes/retry": 0.4.2 + "@types/estree": 1.0.7 + "@types/json-schema": 7.0.15 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.4.0 + escape-string-regexp: 4.0.0 + eslint-scope: 8.3.0 + eslint-visitor-keys: 4.2.0 + espree: 10.3.0 + esquery: 1.6.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.4 + optionalDependencies: + jiti: 2.4.2 + transitivePeerDependencies: + - supports-color + + espree@10.3.0: + dependencies: + acorn: 8.14.1 + acorn-jsx: 5.3.2(acorn@8.14.1) + eslint-visitor-keys: 4.2.0 + + esquery@1.6.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@5.3.0: {} + + esutils@2.0.3: {} + + fast-deep-equal@3.1.3: {} + + fast-diff@1.3.0: {} + + fast-glob@3.3.1: + dependencies: + "@nodelib/fs.stat": 2.0.5 + "@nodelib/fs.walk": 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-glob@3.3.3: + dependencies: + "@nodelib/fs.stat": 2.0.5 + "@nodelib/fs.walk": 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + + fastq@1.19.1: + dependencies: + reusify: 1.1.0 + + fdir@6.4.3(picomatch@4.0.2): + optionalDependencies: + picomatch: 4.0.2 + + file-entry-cache@8.0.0: + dependencies: + flat-cache: 4.0.1 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + flat-cache@4.0.1: + dependencies: + flatted: 3.3.3 + keyv: 4.5.4 + + flatted@3.3.3: {} + + follow-redirects@1.15.9: {} + + for-each@0.3.5: + dependencies: + is-callable: 1.2.7 + + form-data@4.0.2: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + es-set-tostringtag: 2.1.0 + mime-types: 2.1.35 + + framer-motion@12.7.3(react-dom@19.1.0(react@19.1.0))(react@19.1.0): + dependencies: + motion-dom: 12.7.3 + motion-utils: 12.7.2 + tslib: 2.8.1 + optionalDependencies: + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + + function-bind@1.1.2: {} + + function.prototype.name@1.1.8: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + functions-have-names: 1.2.3 + hasown: 2.0.2 + is-callable: 1.2.7 + + functions-have-names@1.2.3: {} + + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + math-intrinsics: 1.1.0 + + get-nonce@1.0.1: {} + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + + get-symbol-description@1.1.0: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + + get-tsconfig@4.10.0: + dependencies: + resolve-pkg-maps: 1.0.0 + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + globals@11.12.0: {} + + globals@14.0.0: {} + + globalthis@1.0.4: + dependencies: + define-properties: 1.2.1 + gopd: 1.2.0 + + gopd@1.2.0: {} + + graceful-fs@4.2.11: {} + + graphemer@1.4.0: {} + + has-bigints@1.1.0: {} + + has-flag@4.0.0: {} + + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.1 + + has-proto@1.2.0: + dependencies: + dunder-proto: 1.0.1 + + has-symbols@1.1.0: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + ignore@5.3.2: {} + + import-fresh@3.3.1: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + imurmurhash@0.1.4: {} + + internal-slot@1.1.0: + dependencies: + es-errors: 1.3.0 + hasown: 2.0.2 + side-channel: 1.1.0 + + intl-messageformat@10.7.16: + dependencies: + "@formatjs/ecma402-abstract": 2.3.4 + "@formatjs/fast-memoize": 2.2.7 + "@formatjs/icu-messageformat-parser": 2.11.2 + tslib: 2.8.1 + + is-array-buffer@3.0.5: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + + is-arrayish@0.3.2: + optional: true + + is-async-function@2.1.1: + dependencies: + async-function: 1.0.0 + call-bound: 1.0.4 + get-proto: 1.0.1 + has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 + + is-bigint@1.1.0: + dependencies: + has-bigints: 1.1.0 + + is-boolean-object@1.2.2: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-bun-module@2.0.0: + dependencies: + semver: 7.7.1 + + is-callable@1.2.7: {} + + is-core-module@2.16.1: + dependencies: + hasown: 2.0.2 + + is-data-view@1.0.2: + dependencies: + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + is-typed-array: 1.1.15 + + is-date-object@1.1.0: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-extglob@2.1.1: {} + + is-finalizationregistry@1.1.1: + dependencies: + call-bound: 1.0.4 + + is-generator-function@1.1.0: + dependencies: + call-bound: 1.0.4 + get-proto: 1.0.1 + has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-map@2.0.3: {} + + is-number-object@1.1.1: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-number@7.0.0: {} + + is-regex@1.2.1: + dependencies: + call-bound: 1.0.4 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + is-set@2.0.3: {} + + is-shared-array-buffer@1.0.4: + dependencies: + call-bound: 1.0.4 + + is-string@1.1.1: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-symbol@1.1.1: + dependencies: + call-bound: 1.0.4 + has-symbols: 1.1.0 + safe-regex-test: 1.1.0 + + is-typed-array@1.1.15: + dependencies: + which-typed-array: 1.1.19 + + is-weakmap@2.0.2: {} + + is-weakref@1.1.1: + dependencies: + call-bound: 1.0.4 + + is-weakset@2.0.4: + dependencies: + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + + isarray@2.0.5: {} + + isexe@2.0.0: {} + + iterator.prototype@1.1.5: + dependencies: + define-data-property: 1.1.4 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + has-symbols: 1.1.0 + set-function-name: 2.0.2 + + jiti@2.4.2: {} + + js-tokens@4.0.0: {} + + js-yaml@4.1.0: + dependencies: + argparse: 2.0.1 + + jsesc@3.1.0: {} + + json-buffer@3.0.1: {} + + json-schema-traverse@0.4.1: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + json5@1.0.2: + dependencies: + minimist: 1.2.8 + + jsx-ast-utils@3.3.5: + dependencies: + array-includes: 3.1.8 + array.prototype.flat: 1.3.3 + object.assign: 4.1.7 + object.values: 1.2.1 + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + language-subtag-registry@0.3.23: {} + + language-tags@1.0.9: + dependencies: + language-subtag-registry: 0.3.23 + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + lightningcss-darwin-arm64@1.29.2: + optional: true + + lightningcss-darwin-x64@1.29.2: + optional: true + + lightningcss-freebsd-x64@1.29.2: + optional: true + + lightningcss-linux-arm-gnueabihf@1.29.2: + optional: true + + lightningcss-linux-arm64-gnu@1.29.2: + optional: true + + lightningcss-linux-arm64-musl@1.29.2: + optional: true + + lightningcss-linux-x64-gnu@1.29.2: + optional: true + + lightningcss-linux-x64-musl@1.29.2: + optional: true + + lightningcss-win32-arm64-msvc@1.29.2: + optional: true + + lightningcss-win32-x64-msvc@1.29.2: + optional: true + + lightningcss@1.29.2: + dependencies: + detect-libc: 2.0.3 + optionalDependencies: + lightningcss-darwin-arm64: 1.29.2 + lightningcss-darwin-x64: 1.29.2 + lightningcss-freebsd-x64: 1.29.2 + lightningcss-linux-arm-gnueabihf: 1.29.2 + lightningcss-linux-arm64-gnu: 1.29.2 + lightningcss-linux-arm64-musl: 1.29.2 + lightningcss-linux-x64-gnu: 1.29.2 + lightningcss-linux-x64-musl: 1.29.2 + lightningcss-win32-arm64-msvc: 1.29.2 + lightningcss-win32-x64-msvc: 1.29.2 + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lodash.merge@4.6.2: {} + + loose-envify@1.4.0: + dependencies: + js-tokens: 4.0.0 + + lucide-react@0.487.0(react@19.1.0): + dependencies: + react: 19.1.0 + + math-intrinsics@1.1.0: {} + + merge2@1.4.1: {} + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.11 + + minimatch@9.0.5: + dependencies: + brace-expansion: 2.0.1 + + minimist@1.2.8: {} + + motion-dom@12.7.3: + dependencies: + motion-utils: 12.7.2 + + motion-utils@12.7.2: {} + + ms@2.1.3: {} + + nanoid@3.3.11: {} + + nanoid@5.1.5: {} + + natural-compare@1.4.0: {} + + negotiator@1.0.0: {} + + next-intl@4.0.2(next@15.2.4(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react@19.1.0)(typescript@5.8.2): + dependencies: + "@formatjs/intl-localematcher": 0.5.10 + negotiator: 1.0.0 + next: 15.2.4(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + react: 19.1.0 + use-intl: 4.0.2(react@19.1.0) + optionalDependencies: + typescript: 5.8.2 + + next-themes@0.4.6(react-dom@19.1.0(react@19.1.0))(react@19.1.0): + dependencies: + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + + next@15.2.4(react-dom@19.1.0(react@19.1.0))(react@19.1.0): + dependencies: + "@next/env": 15.2.4 + "@swc/counter": 0.1.3 + "@swc/helpers": 0.5.15 + busboy: 1.6.0 + caniuse-lite: 1.0.30001714 + postcss: 8.4.31 + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + styled-jsx: 5.1.6(react@19.1.0) + optionalDependencies: + "@next/swc-darwin-arm64": 15.2.4 + "@next/swc-darwin-x64": 15.2.4 + "@next/swc-linux-arm64-gnu": 15.2.4 + "@next/swc-linux-arm64-musl": 15.2.4 + "@next/swc-linux-x64-gnu": 15.2.4 + "@next/swc-linux-x64-musl": 15.2.4 + "@next/swc-win32-arm64-msvc": 15.2.4 + "@next/swc-win32-x64-msvc": 15.2.4 + sharp: 0.33.5 + transitivePeerDependencies: + - "@babel/core" + - babel-plugin-macros + + nookies@2.5.2: + dependencies: + cookie: 0.4.2 + set-cookie-parser: 2.7.1 + + object-assign@4.1.1: {} + + object-inspect@1.13.4: {} + + object-keys@1.1.1: {} + + object.assign@4.1.7: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + has-symbols: 1.1.0 + object-keys: 1.1.1 + + object.entries@1.1.9: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + + object.fromentries@2.0.8: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-object-atoms: 1.1.1 + + object.groupby@1.0.3: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + + object.values@1.2.1: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + + own-keys@1.0.1: + dependencies: + get-intrinsic: 1.3.0 + object-keys: 1.1.1 + safe-push-apply: 1.0.0 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + path-exists@4.0.0: {} + + path-key@3.1.1: {} + + path-parse@1.0.7: {} + + picocolors@1.1.1: {} + + picomatch@2.3.1: {} + + picomatch@4.0.2: {} + + possible-typed-array-names@1.1.0: {} + + postcss@8.4.31: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + postcss@8.5.3: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + prelude-ls@1.2.1: {} + + prettier-linter-helpers@1.0.0: + dependencies: + fast-diff: 1.3.0 + + prettier-plugin-sort-json@4.1.1(prettier@3.5.3): + dependencies: + prettier: 3.5.3 + + prettier@3.5.3: {} + + prop-types@15.8.1: + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + react-is: 16.13.1 + + proxy-from-env@1.1.0: {} + + punycode@2.3.1: {} + + queue-microtask@1.2.3: {} + + react-country-flag@3.1.0(react@19.1.0): + dependencies: + react: 19.1.0 + + react-dom@19.1.0(react@19.1.0): + dependencies: + react: 19.1.0 + scheduler: 0.26.0 + + react-hook-form@7.55.0(react@19.1.0): + dependencies: + react: 19.1.0 + + react-is@16.13.1: {} + + react-remove-scroll-bar@2.3.8(@types/react@19.1.0)(react@19.1.0): + dependencies: + react: 19.1.0 + react-style-singleton: 2.2.3(@types/react@19.1.0)(react@19.1.0) + tslib: 2.8.1 + optionalDependencies: + "@types/react": 19.1.0 + + react-remove-scroll@2.6.3(@types/react@19.1.0)(react@19.1.0): + dependencies: + react: 19.1.0 + react-remove-scroll-bar: 2.3.8(@types/react@19.1.0)(react@19.1.0) + react-style-singleton: 2.2.3(@types/react@19.1.0)(react@19.1.0) + tslib: 2.8.1 + use-callback-ref: 1.3.3(@types/react@19.1.0)(react@19.1.0) + use-sidecar: 1.1.3(@types/react@19.1.0)(react@19.1.0) + optionalDependencies: + "@types/react": 19.1.0 + + react-style-singleton@2.2.3(@types/react@19.1.0)(react@19.1.0): + dependencies: + get-nonce: 1.0.1 + react: 19.1.0 + tslib: 2.8.1 + optionalDependencies: + "@types/react": 19.1.0 + + react@19.1.0: {} + + reflect.getprototypeof@1.0.10: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + which-builtin-type: 1.2.1 + + regexp.prototype.flags@1.5.4: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-errors: 1.3.0 + get-proto: 1.0.1 + gopd: 1.2.0 + set-function-name: 2.0.2 + + resolve-from@4.0.0: {} + + resolve-pkg-maps@1.0.0: {} + + resolve@1.22.10: + dependencies: + is-core-module: 2.16.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + resolve@2.0.0-next.5: + dependencies: + is-core-module: 2.16.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + reusify@1.1.0: {} + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + safe-array-concat@1.1.3: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + has-symbols: 1.1.0 + isarray: 2.0.5 + + safe-push-apply@1.0.0: + dependencies: + es-errors: 1.3.0 + isarray: 2.0.5 + + safe-regex-test@1.1.0: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-regex: 1.2.1 + + scheduler@0.26.0: {} + + semver@6.3.1: {} + + semver@7.7.1: {} + + set-cookie-parser@2.7.1: {} + + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.3.0 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + + set-function-name@2.0.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.2 + + set-proto@1.0.0: + dependencies: + dunder-proto: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + + sharp@0.33.5: + dependencies: + color: 4.2.3 + detect-libc: 2.0.3 + semver: 7.7.1 + optionalDependencies: + "@img/sharp-darwin-arm64": 0.33.5 + "@img/sharp-darwin-x64": 0.33.5 + "@img/sharp-libvips-darwin-arm64": 1.0.4 + "@img/sharp-libvips-darwin-x64": 1.0.4 + "@img/sharp-libvips-linux-arm": 1.0.5 + "@img/sharp-libvips-linux-arm64": 1.0.4 + "@img/sharp-libvips-linux-s390x": 1.0.4 + "@img/sharp-libvips-linux-x64": 1.0.4 + "@img/sharp-libvips-linuxmusl-arm64": 1.0.4 + "@img/sharp-libvips-linuxmusl-x64": 1.0.4 + "@img/sharp-linux-arm": 0.33.5 + "@img/sharp-linux-arm64": 0.33.5 + "@img/sharp-linux-s390x": 0.33.5 + "@img/sharp-linux-x64": 0.33.5 + "@img/sharp-linuxmusl-arm64": 0.33.5 + "@img/sharp-linuxmusl-x64": 0.33.5 + "@img/sharp-wasm32": 0.33.5 + "@img/sharp-win32-ia32": 0.33.5 + "@img/sharp-win32-x64": 0.33.5 + optional: true + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + side-channel-list@1.0.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + + side-channel-map@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + + side-channel-weakmap@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + + side-channel@1.1.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.0 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + + simple-swizzle@0.2.2: + dependencies: + is-arrayish: 0.3.2 + optional: true + + sonner@2.0.3(react-dom@19.1.0(react@19.1.0))(react@19.1.0): + dependencies: + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + + source-map-js@1.2.1: {} + + stable-hash@0.0.5: {} + + streamsearch@1.1.0: {} + + string.prototype.includes@2.0.1: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-abstract: 1.23.9 + + string.prototype.matchall@4.0.12: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + gopd: 1.2.0 + has-symbols: 1.1.0 + internal-slot: 1.1.0 + regexp.prototype.flags: 1.5.4 + set-function-name: 2.0.2 + side-channel: 1.1.0 + + string.prototype.repeat@1.0.0: + dependencies: + define-properties: 1.2.1 + es-abstract: 1.23.9 + + string.prototype.trim@1.2.10: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-data-property: 1.1.4 + define-properties: 1.2.1 + es-abstract: 1.23.9 + es-object-atoms: 1.1.1 + has-property-descriptors: 1.0.2 + + string.prototype.trimend@1.0.9: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + + string.prototype.trimstart@1.0.8: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + + strip-bom@3.0.0: {} + + strip-json-comments@3.1.1: {} + + styled-jsx@5.1.6(react@19.1.0): + dependencies: + client-only: 0.0.1 + react: 19.1.0 + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-preserve-symlinks-flag@1.0.0: {} + + synckit@0.11.4: + dependencies: + "@pkgr/core": 0.2.4 + tslib: 2.8.1 + + tailwind-merge@3.2.0: {} + + tailwindcss@4.1.2: {} + + tapable@2.2.1: {} + + tinyglobby@0.2.12: + dependencies: + fdir: 6.4.3(picomatch@4.0.2) + picomatch: 4.0.2 + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + ts-api-utils@2.1.0(typescript@5.8.2): + dependencies: + typescript: 5.8.2 + + tsconfig-paths@3.15.0: + dependencies: + "@types/json5": 0.0.29 + json5: 1.0.2 + minimist: 1.2.8 + strip-bom: 3.0.0 + + tslib@2.8.1: {} + + tw-animate-css@1.2.5: {} + + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + + typed-array-buffer@1.0.3: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-typed-array: 1.1.15 + + typed-array-byte-length@1.0.3: + dependencies: + call-bind: 1.0.8 + for-each: 0.3.5 + gopd: 1.2.0 + has-proto: 1.2.0 + is-typed-array: 1.1.15 + + typed-array-byte-offset@1.0.4: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + for-each: 0.3.5 + gopd: 1.2.0 + has-proto: 1.2.0 + is-typed-array: 1.1.15 + reflect.getprototypeof: 1.0.10 + + typed-array-length@1.0.7: + dependencies: + call-bind: 1.0.8 + for-each: 0.3.5 + gopd: 1.2.0 + is-typed-array: 1.1.15 + possible-typed-array-names: 1.1.0 + reflect.getprototypeof: 1.0.10 + + typescript@5.8.2: {} + + unbox-primitive@1.1.0: + dependencies: + call-bound: 1.0.4 + has-bigints: 1.1.0 + has-symbols: 1.1.0 + which-boxed-primitive: 1.1.1 + + undici-types@6.21.0: {} + + unrs-resolver@1.5.0: + optionalDependencies: + "@unrs/resolver-binding-darwin-arm64": 1.5.0 + "@unrs/resolver-binding-darwin-x64": 1.5.0 + "@unrs/resolver-binding-freebsd-x64": 1.5.0 + "@unrs/resolver-binding-linux-arm-gnueabihf": 1.5.0 + "@unrs/resolver-binding-linux-arm-musleabihf": 1.5.0 + "@unrs/resolver-binding-linux-arm64-gnu": 1.5.0 + "@unrs/resolver-binding-linux-arm64-musl": 1.5.0 + "@unrs/resolver-binding-linux-ppc64-gnu": 1.5.0 + "@unrs/resolver-binding-linux-riscv64-gnu": 1.5.0 + "@unrs/resolver-binding-linux-s390x-gnu": 1.5.0 + "@unrs/resolver-binding-linux-x64-gnu": 1.5.0 + "@unrs/resolver-binding-linux-x64-musl": 1.5.0 + "@unrs/resolver-binding-wasm32-wasi": 1.5.0 + "@unrs/resolver-binding-win32-arm64-msvc": 1.5.0 + "@unrs/resolver-binding-win32-ia32-msvc": 1.5.0 + "@unrs/resolver-binding-win32-x64-msvc": 1.5.0 + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + use-callback-ref@1.3.3(@types/react@19.1.0)(react@19.1.0): + dependencies: + react: 19.1.0 + tslib: 2.8.1 + optionalDependencies: + "@types/react": 19.1.0 + + use-intl@4.0.2(react@19.1.0): + dependencies: + "@formatjs/fast-memoize": 2.2.7 + "@schummar/icu-type-parser": 1.21.5 + intl-messageformat: 10.7.16 + react: 19.1.0 + + use-sidecar@1.1.3(@types/react@19.1.0)(react@19.1.0): + dependencies: + detect-node-es: 1.1.0 + react: 19.1.0 + tslib: 2.8.1 + optionalDependencies: + "@types/react": 19.1.0 + + which-boxed-primitive@1.1.1: + dependencies: + is-bigint: 1.1.0 + is-boolean-object: 1.2.2 + is-number-object: 1.1.1 + is-string: 1.1.1 + is-symbol: 1.1.1 + + which-builtin-type@1.2.1: + dependencies: + call-bound: 1.0.4 + function.prototype.name: 1.1.8 + has-tostringtag: 1.0.2 + is-async-function: 2.1.1 + is-date-object: 1.1.0 + is-finalizationregistry: 1.1.1 + is-generator-function: 1.1.0 + is-regex: 1.2.1 + is-weakref: 1.1.1 + isarray: 2.0.5 + which-boxed-primitive: 1.1.1 + which-collection: 1.0.2 + which-typed-array: 1.1.19 + + which-collection@1.0.2: + dependencies: + is-map: 2.0.3 + is-set: 2.0.3 + is-weakmap: 2.0.2 + is-weakset: 2.0.4 + + which-typed-array@1.1.19: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + call-bound: 1.0.4 + for-each: 0.3.5 + get-proto: 1.0.1 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + word-wrap@1.2.5: {} + + yocto-queue@0.1.0: {} + + zod@3.24.2: {} + + zustand@5.0.3(@types/react@19.1.0)(react@19.1.0): + optionalDependencies: + "@types/react": 19.1.0 + react: 19.1.0 diff --git a/apps/web/postcss.config.js b/apps/web/postcss.config.js deleted file mode 100644 index 2aa7205..0000000 --- a/apps/web/postcss.config.js +++ /dev/null @@ -1,6 +0,0 @@ -export default { - plugins: { - tailwindcss: {}, - autoprefixer: {}, - }, -}; diff --git a/apps/web/postcss.config.mjs b/apps/web/postcss.config.mjs new file mode 100644 index 0000000..c7bcb4b --- /dev/null +++ b/apps/web/postcss.config.mjs @@ -0,0 +1,5 @@ +const config = { + plugins: ["@tailwindcss/postcss"], +}; + +export default config; diff --git a/apps/web/routes.json b/apps/web/routes.json deleted file mode 100644 index ca9ef55..0000000 --- a/apps/web/routes.json +++ /dev/null @@ -1 +0,0 @@ -{"openapi":"3.0.3","info":{"title":"🌴 Palmr. API","description":"API documentation for Palmr file sharing system","version":"1.0.0"},"components":{"schemas":{"def-0":{"type":"string","format":"date-time","title":"dateFormat"}}},"paths":{"/auth/login":{"post":{"operationId":"login","summary":"Login","tags":["Authentication"],"description":"Performs login and returns user data","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string","format":"email","description":"User email"},"password":{"type":"string","minLength":8,"description":"User password"}},"required":["email","password"],"additionalProperties":false}}},"required":true},"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"user":{"type":"object","properties":{"id":{"type":"string","description":"User ID"},"firstName":{"type":"string","description":"User first name"},"lastName":{"type":"string","description":"User last name"},"username":{"type":"string","description":"User username"},"email":{"type":"string","format":"email","description":"User email"},"isAdmin":{"type":"boolean","description":"User is admin"},"isActive":{"type":"boolean","description":"User is active"},"createdAt":{"type":"string","format":"date-time","description":"User creation date"},"updatedAt":{"type":"string","format":"date-time","description":"User last update date"}},"required":["id","firstName","lastName","username","email","isAdmin","isActive","createdAt","updatedAt"],"additionalProperties":false}},"required":["user"],"additionalProperties":false}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}}}}},"/auth/logout":{"post":{"operationId":"logout","summary":"Logout","tags":["Authentication"],"description":"Performs logout by clearing the token cookie","responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Logout message"}},"required":["message"],"additionalProperties":false}}}}}}},"/auth/forgot-password":{"post":{"operationId":"requestPasswordReset","summary":"Request Password Reset","tags":["Authentication"],"description":"Request password reset email","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string","format":"email","description":"User email"}},"required":["email"],"additionalProperties":false}}},"required":true},"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Reset password email sent"}},"required":["message"],"additionalProperties":false}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}}}}},"/auth/reset-password":{"post":{"operationId":"resetPassword","summary":"Reset Password","tags":["Authentication"],"description":"Reset password using token","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"token":{"type":"string","minLength":1,"description":"Reset password token"},"password":{"type":"string","minLength":8,"description":"User password"}},"required":["token","password"],"additionalProperties":false}}},"required":true},"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Reset password message"}},"required":["message"],"additionalProperties":false}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}}}}},"/auth/me":{"get":{"operationId":"getCurrentUser","summary":"Get Current User","tags":["Authentication"],"description":"Returns the current authenticated user's information","responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"user":{"type":"object","properties":{"id":{"type":"string","description":"User ID"},"firstName":{"type":"string","description":"User first name"},"lastName":{"type":"string","description":"User last name"},"username":{"type":"string","description":"User username"},"email":{"type":"string","format":"email","description":"User email"},"image":{"type":"string","nullable":true,"description":"User profile image URL"},"isAdmin":{"type":"boolean","description":"User is admin"},"isActive":{"type":"boolean","description":"User is active"},"createdAt":{"type":"string","format":"date-time","description":"User creation date"},"updatedAt":{"type":"string","format":"date-time","description":"User last update date"}},"required":["id","firstName","lastName","username","email","image","isAdmin","isActive","createdAt","updatedAt"],"additionalProperties":false}},"required":["user"],"additionalProperties":false}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}}}}},"/auth/register":{"post":{"operationId":"registerUser","summary":"Register New User","tags":["User"],"description":"Register a new user (admin only)","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"firstName":{"type":"string","minLength":1,"description":"User first name"},"lastName":{"type":"string","minLength":1,"description":"User last name"},"username":{"type":"string","minLength":3,"description":"User username"},"email":{"type":"string","format":"email","description":"User email"},"image":{"type":"string","description":"User profile image URL"},"password":{"type":"string","minLength":8,"description":"User password"}},"required":["firstName","lastName","username","email","password"],"additionalProperties":false}}},"required":true},"responses":{"201":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"user":{"type":"object","properties":{"id":{"type":"string","description":"User ID"},"firstName":{"type":"string","description":"User first name"},"lastName":{"type":"string","description":"User last name"},"username":{"type":"string","description":"User username"},"email":{"type":"string","format":"email","description":"User email"},"image":{"type":"string","nullable":true,"description":"User profile image URL"},"isAdmin":{"type":"boolean","description":"User is admin"},"isActive":{"type":"boolean","description":"User is active"},"createdAt":{"type":"string","format":"date-time","description":"User creation date"},"updatedAt":{"type":"string","format":"date-time","description":"User last update date"}},"required":["id","firstName","lastName","username","email","image","isAdmin","isActive","createdAt","updatedAt"],"additionalProperties":false},"message":{"type":"string","description":"User registration message"}},"required":["user","message"],"additionalProperties":false}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}}}}},"/users":{"get":{"operationId":"listUsers","summary":"List All Users","tags":["User"],"description":"List all users (admin only)","responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"User ID"},"firstName":{"type":"string","description":"User first name"},"lastName":{"type":"string","description":"User last name"},"username":{"type":"string","description":"User username"},"email":{"type":"string","format":"email","description":"User email"},"image":{"type":"string","nullable":true,"description":"User profile image URL"},"isAdmin":{"type":"boolean","description":"User is admin"},"isActive":{"type":"boolean","description":"User is active"},"createdAt":{"type":"string","format":"date-time","description":"User creation date"},"updatedAt":{"type":"string","format":"date-time","description":"User last update date"}},"required":["id","firstName","lastName","username","email","image","isAdmin","isActive","createdAt","updatedAt"],"additionalProperties":false}}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}}}},"put":{"operationId":"updateUser","summary":"Update User Data","tags":["User"],"description":"Update user data (admin only)","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"firstName":{"type":"string","minLength":1},"lastName":{"type":"string","minLength":1},"username":{"type":"string","minLength":3},"email":{"type":"string","format":"email"},"image":{"type":"string"},"password":{"type":"string","minLength":8,"description":"User password"},"isAdmin":{"type":"boolean"}},"required":["id"],"additionalProperties":false}}},"required":true},"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"User ID"},"firstName":{"type":"string","description":"User first name"},"lastName":{"type":"string","description":"User last name"},"username":{"type":"string","description":"User username"},"email":{"type":"string","format":"email","description":"User email"},"image":{"type":"string","nullable":true,"description":"User profile image URL"},"isAdmin":{"type":"boolean","description":"User is admin"},"isActive":{"type":"boolean","description":"User is active"},"createdAt":{"type":"string","format":"date-time","description":"User creation date"},"updatedAt":{"type":"string","format":"date-time","description":"User last update date"}},"required":["id","firstName","lastName","username","email","image","isAdmin","isActive","createdAt","updatedAt"],"additionalProperties":false}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}}}}},"/users/{id}":{"get":{"operationId":"getUserById","summary":"Get User by ID","tags":["User"],"description":"Get a user by ID (admin only)","parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"User ID"}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"User ID"},"firstName":{"type":"string","description":"User first name"},"lastName":{"type":"string","description":"User last name"},"username":{"type":"string","description":"User username"},"email":{"type":"string","format":"email","description":"User email"},"image":{"type":"string","nullable":true,"description":"User profile image URL"},"isAdmin":{"type":"boolean","description":"User is admin"},"isActive":{"type":"boolean","description":"User is active"},"createdAt":{"type":"string","format":"date-time","description":"User creation date"},"updatedAt":{"type":"string","format":"date-time","description":"User last update date"}},"required":["id","firstName","lastName","username","email","image","isAdmin","isActive","createdAt","updatedAt"],"additionalProperties":false}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}}}},"delete":{"operationId":"deleteUser","summary":"Delete User","tags":["User"],"description":"Delete a user (admin only)","parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"User ID"}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"User ID"},"firstName":{"type":"string","description":"User first name"},"lastName":{"type":"string","description":"User last name"},"username":{"type":"string","description":"User username"},"email":{"type":"string","format":"email","description":"User email"},"image":{"type":"string","nullable":true,"description":"User profile image URL"},"isAdmin":{"type":"boolean","description":"User is admin"},"isActive":{"type":"boolean","description":"User is active"},"createdAt":{"type":"string","format":"date-time","description":"User creation date"},"updatedAt":{"type":"string","format":"date-time","description":"User last update date"}},"required":["id","firstName","lastName","username","email","image","isAdmin","isActive","createdAt","updatedAt"],"additionalProperties":false}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}}}}},"/users/{id}/activate":{"patch":{"operationId":"activateUser","summary":"Activate User","tags":["User"],"description":"Activate a user (admin only)","parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"User ID"}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"User ID"},"firstName":{"type":"string","description":"User first name"},"lastName":{"type":"string","description":"User last name"},"username":{"type":"string","description":"User username"},"email":{"type":"string","format":"email","description":"User email"},"image":{"type":"string","nullable":true,"description":"User profile image URL"},"isAdmin":{"type":"boolean","description":"User is admin"},"isActive":{"type":"boolean","description":"User is active"},"createdAt":{"type":"string","format":"date-time","description":"User creation date"},"updatedAt":{"type":"string","format":"date-time","description":"User last update date"}},"required":["id","firstName","lastName","username","email","image","isAdmin","isActive","createdAt","updatedAt"],"additionalProperties":false}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}}}}},"/users/{id}/deactivate":{"patch":{"operationId":"deactivateUser","summary":"Deactivate User","tags":["User"],"description":"Deactivate a user (admin only)","parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"User ID"}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"User ID"},"firstName":{"type":"string","description":"User first name"},"lastName":{"type":"string","description":"User last name"},"username":{"type":"string","description":"User username"},"email":{"type":"string","format":"email","description":"User email"},"image":{"type":"string","nullable":true,"description":"User profile image URL"},"isAdmin":{"type":"boolean","description":"User is admin"},"isActive":{"type":"boolean","description":"User is active"},"createdAt":{"type":"string","format":"date-time","description":"User creation date"},"updatedAt":{"type":"string","format":"date-time","description":"User last update date"}},"required":["id","firstName","lastName","username","email","image","isAdmin","isActive","createdAt","updatedAt"],"additionalProperties":false}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}}}}},"/users/{id}/image":{"patch":{"operationId":"updateUserImage","summary":"Update User Image","tags":["User"],"description":"Update user profile image (admin only)","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"image":{"type":"string","format":"uri","description":"User profile image URL"}},"required":["image"],"additionalProperties":false}}},"required":true},"parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"User ID"}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"User ID"},"firstName":{"type":"string","description":"User first name"},"lastName":{"type":"string","description":"User last name"},"username":{"type":"string","description":"User username"},"email":{"type":"string","format":"email","description":"User email"},"image":{"type":"string","nullable":true,"description":"User profile image URL"},"isAdmin":{"type":"boolean","description":"User is admin"},"isActive":{"type":"boolean","description":"User is active"},"createdAt":{"type":"string","format":"date-time","description":"User creation date"},"updatedAt":{"type":"string","format":"date-time","description":"User last update date"}},"required":["id","firstName","lastName","username","email","image","isAdmin","isActive","createdAt","updatedAt"],"additionalProperties":false}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}}}}},"/users/avatar":{"post":{"operationId":"uploadAvatar","summary":"Upload user avatar","tags":["User"],"description":"Upload and update user profile image","requestBody":{"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"description":"Image file (JPG, PNG, GIF)"}},"additionalProperties":false}}}},"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"firstName":{"type":"string"},"lastName":{"type":"string"},"username":{"type":"string"},"email":{"type":"string"},"image":{"type":"string","nullable":true},"isAdmin":{"type":"boolean"},"isActive":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","firstName","lastName","username","email","image","isAdmin","isActive","createdAt","updatedAt"],"additionalProperties":false}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"],"additionalProperties":false}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"],"additionalProperties":false}}}}}},"delete":{"operationId":"removeAvatar","summary":"Remove user avatar","tags":["User"],"description":"Remove user profile image","responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"firstName":{"type":"string"},"lastName":{"type":"string"},"username":{"type":"string"},"email":{"type":"string"},"image":{"type":"string","nullable":true},"isAdmin":{"type":"boolean"},"isActive":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["id","firstName","lastName","username","email","image","isAdmin","isActive","createdAt","updatedAt"],"additionalProperties":false}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"],"additionalProperties":false}}}}}}},"/files/presigned-url":{"get":{"operationId":"getPresignedUrl","summary":"Get Presigned URL","tags":["File"],"description":"Generates a pre-signed URL for direct upload to MinIO","parameters":[{"schema":{"type":"string","minLength":1},"in":"query","name":"filename","required":true,"description":"The filename of the file"},{"schema":{"type":"string","minLength":1},"in":"query","name":"extension","required":true,"description":"The extension of the file"}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","description":"The pre-signed URL"},"objectName":{"type":"string","description":"The object name of the file"}},"required":["url","objectName"],"additionalProperties":false}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}},"500":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}}}}},"/files":{"post":{"operationId":"registerFile","summary":"Register File Metadata","tags":["File"],"description":"Registers file metadata in the database","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1},"description":{"type":"string"},"extension":{"type":"string","minLength":1},"size":{"type":"number"},"objectName":{"type":"string","minLength":1}},"required":["name","extension","size","objectName"],"additionalProperties":false}}},"required":true},"responses":{"201":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"file":{"type":"object","properties":{"id":{"type":"string","description":"The file ID"},"name":{"type":"string","description":"The file name"},"description":{"type":"string","nullable":true,"description":"The file description"},"extension":{"type":"string","description":"The file extension"},"size":{"type":"string","description":"The file size"},"objectName":{"type":"string","description":"The object name of the file"},"userId":{"type":"string","description":"The user ID"},"createdAt":{"type":"string","format":"date-time","description":"The file creation date"},"updatedAt":{"type":"string","format":"date-time","description":"The file last update date"}},"required":["id","name","description","extension","size","objectName","userId","createdAt","updatedAt"],"additionalProperties":false},"message":{"type":"string","description":"The file registration message"}},"required":["file","message"],"additionalProperties":false}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}}}},"get":{"operationId":"listFiles","summary":"List Files","tags":["File"],"description":"Lists user files","responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"files":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The file ID"},"name":{"type":"string","description":"The file name"},"description":{"type":"string","nullable":true,"description":"The file description"},"extension":{"type":"string","description":"The file extension"},"size":{"type":"string","description":"The file size"},"objectName":{"type":"string","description":"The object name of the file"},"userId":{"type":"string","description":"The user ID"},"createdAt":{"type":"string","format":"date-time","description":"The file creation date"},"updatedAt":{"type":"string","format":"date-time","description":"The file last update date"}},"required":["id","name","description","extension","size","objectName","userId","createdAt","updatedAt"],"additionalProperties":false}}},"required":["files"],"additionalProperties":false}}}},"500":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}}}}},"/files/{objectName}/download":{"get":{"operationId":"getDownloadUrl","summary":"Get Download URL","tags":["File"],"description":"Generates a pre-signed URL for downloading a private file","parameters":[{"schema":{"type":"string","minLength":1},"in":"path","name":"objectName","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","description":"The download URL"},"expiresIn":{"type":"number","description":"The expiration time in seconds"}},"required":["url","expiresIn"],"additionalProperties":false}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}},"500":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}}}}},"/files/{id}":{"delete":{"operationId":"deleteFile","summary":"Delete File","tags":["File"],"description":"Deletes a user file","parameters":[{"schema":{"type":"string","minLength":1},"in":"path","name":"id","required":true,"description":"The file ID"}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"The file deletion message"}},"required":["message"],"additionalProperties":false}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}},"500":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}}}},"patch":{"operationId":"updateFile","summary":"Update File Metadata","tags":["File"],"description":"Updates file metadata in the database","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"The file name"},"description":{"type":"string","nullable":true,"description":"The file description"}},"additionalProperties":false}}}},"parameters":[{"schema":{"type":"string","minLength":1},"in":"path","name":"id","required":true,"description":"The file ID"}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"file":{"type":"object","properties":{"id":{"type":"string","description":"The file ID"},"name":{"type":"string","description":"The file name"},"description":{"type":"string","nullable":true,"description":"The file description"},"extension":{"type":"string","description":"The file extension"},"size":{"type":"string","description":"The file size"},"objectName":{"type":"string","description":"The object name of the file"},"userId":{"type":"string","description":"The user ID"},"createdAt":{"type":"string","format":"date-time","description":"The file creation date"},"updatedAt":{"type":"string","format":"date-time","description":"The file last update date"}},"required":["id","name","description","extension","size","objectName","userId","createdAt","updatedAt"],"additionalProperties":false},"message":{"type":"string","description":"Success message"}},"required":["file","message"],"additionalProperties":false}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}}}}},"/shares":{"post":{"operationId":"createShare","summary":"Create a new share","tags":["Share"],"description":"Create a new share","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"The share name"},"description":{"type":"string","description":"The share description"},"expiration":{"type":"string","format":"date-time"},"files":{"type":"array","items":{"type":"string"},"description":"The file IDs"},"password":{"type":"string","description":"The share password"},"maxViews":{"type":"number","nullable":true,"description":"The maximum number of views"},"recipients":{"type":"array","items":{"type":"string","format":"email"},"description":"The recipient emails"}},"required":["files"],"additionalProperties":false}}},"required":true},"responses":{"201":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"share":{"type":"object","properties":{"id":{"type":"string","description":"The share ID"},"name":{"type":"string","nullable":true,"description":"The share name"},"description":{"type":"string","nullable":true,"description":"The share description"},"expiration":{"type":"string","nullable":true,"description":"The share expiration date"},"views":{"type":"number","description":"The number of views"},"createdAt":{"type":"string","description":"The share creation date"},"updatedAt":{"type":"string","description":"The share update date"},"creatorId":{"type":"string","description":"The creator ID"},"security":{"type":"object","properties":{"maxViews":{"type":"number","nullable":true,"description":"The maximum number of views"},"hasPassword":{"type":"boolean","description":"Whether the share has a password"}},"required":["maxViews","hasPassword"],"additionalProperties":false},"files":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The file ID"},"name":{"type":"string","description":"The file name"},"description":{"type":"string","nullable":true,"description":"The file description"},"extension":{"type":"string","description":"The file extension"},"size":{"type":"string","description":"The file size"},"objectName":{"type":"string","description":"The file object name"},"userId":{"type":"string","description":"The user ID"},"createdAt":{"type":"string","description":"The file creation date"},"updatedAt":{"type":"string","description":"The file update date"}},"required":["id","name","description","extension","size","objectName","userId","createdAt","updatedAt"],"additionalProperties":false}},"recipients":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The recipient ID"},"email":{"type":"string","format":"email","description":"The recipient email"},"createdAt":{"type":"string","description":"The recipient creation date"},"updatedAt":{"type":"string","description":"The recipient update date"}},"required":["id","email","createdAt","updatedAt"],"additionalProperties":false}},"alias":{"type":"object","properties":{"id":{"type":"string"},"alias":{"type":"string"},"shareId":{"type":"string"},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["id","alias","shareId","createdAt","updatedAt"],"additionalProperties":false,"nullable":true}},"required":["id","name","description","expiration","views","createdAt","updatedAt","creatorId","security","files","recipients","alias"],"additionalProperties":false}},"required":["share"],"additionalProperties":false}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}}}},"put":{"operationId":"updateShare","summary":"Update a share","tags":["Share"],"description":"Update a share","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"expiration":{"type":"string","format":"date-time"},"password":{"type":"string"},"maxViews":{"type":"number","nullable":true},"recipients":{"type":"array","items":{"type":"string","format":"email"}}},"required":["id"],"additionalProperties":false}}},"required":true},"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"share":{"type":"object","properties":{"id":{"type":"string","description":"The share ID"},"name":{"type":"string","nullable":true,"description":"The share name"},"description":{"type":"string","nullable":true,"description":"The share description"},"expiration":{"type":"string","nullable":true,"description":"The share expiration date"},"views":{"type":"number","description":"The number of views"},"createdAt":{"type":"string","description":"The share creation date"},"updatedAt":{"type":"string","description":"The share update date"},"creatorId":{"type":"string","description":"The creator ID"},"security":{"type":"object","properties":{"maxViews":{"type":"number","nullable":true,"description":"The maximum number of views"},"hasPassword":{"type":"boolean","description":"Whether the share has a password"}},"required":["maxViews","hasPassword"],"additionalProperties":false},"files":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The file ID"},"name":{"type":"string","description":"The file name"},"description":{"type":"string","nullable":true,"description":"The file description"},"extension":{"type":"string","description":"The file extension"},"size":{"type":"string","description":"The file size"},"objectName":{"type":"string","description":"The file object name"},"userId":{"type":"string","description":"The user ID"},"createdAt":{"type":"string","description":"The file creation date"},"updatedAt":{"type":"string","description":"The file update date"}},"required":["id","name","description","extension","size","objectName","userId","createdAt","updatedAt"],"additionalProperties":false}},"recipients":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The recipient ID"},"email":{"type":"string","format":"email","description":"The recipient email"},"createdAt":{"type":"string","description":"The recipient creation date"},"updatedAt":{"type":"string","description":"The recipient update date"}},"required":["id","email","createdAt","updatedAt"],"additionalProperties":false}},"alias":{"type":"object","properties":{"id":{"type":"string"},"alias":{"type":"string"},"shareId":{"type":"string"},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["id","alias","shareId","createdAt","updatedAt"],"additionalProperties":false,"nullable":true}},"required":["id","name","description","expiration","views","createdAt","updatedAt","creatorId","security","files","recipients","alias"],"additionalProperties":false}},"required":["share"],"additionalProperties":false}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}}}}},"/shares/me":{"get":{"operationId":"listUserShares","summary":"List all shares created by the authenticated user","tags":["Share"],"description":"List all shares created by the authenticated user","responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"shares":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The share ID"},"name":{"type":"string","nullable":true,"description":"The share name"},"description":{"type":"string","nullable":true,"description":"The share description"},"expiration":{"type":"string","nullable":true,"description":"The share expiration date"},"views":{"type":"number","description":"The number of views"},"createdAt":{"type":"string","description":"The share creation date"},"updatedAt":{"type":"string","description":"The share update date"},"creatorId":{"type":"string","description":"The creator ID"},"security":{"type":"object","properties":{"maxViews":{"type":"number","nullable":true,"description":"The maximum number of views"},"hasPassword":{"type":"boolean","description":"Whether the share has a password"}},"required":["maxViews","hasPassword"],"additionalProperties":false},"files":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The file ID"},"name":{"type":"string","description":"The file name"},"description":{"type":"string","nullable":true,"description":"The file description"},"extension":{"type":"string","description":"The file extension"},"size":{"type":"string","description":"The file size"},"objectName":{"type":"string","description":"The file object name"},"userId":{"type":"string","description":"The user ID"},"createdAt":{"type":"string","description":"The file creation date"},"updatedAt":{"type":"string","description":"The file update date"}},"required":["id","name","description","extension","size","objectName","userId","createdAt","updatedAt"],"additionalProperties":false}},"recipients":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The recipient ID"},"email":{"type":"string","format":"email","description":"The recipient email"},"createdAt":{"type":"string","description":"The recipient creation date"},"updatedAt":{"type":"string","description":"The recipient update date"}},"required":["id","email","createdAt","updatedAt"],"additionalProperties":false}},"alias":{"type":"object","properties":{"id":{"type":"string"},"alias":{"type":"string"},"shareId":{"type":"string"},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["id","alias","shareId","createdAt","updatedAt"],"additionalProperties":false,"nullable":true}},"required":["id","name","description","expiration","views","createdAt","updatedAt","creatorId","security","files","recipients","alias"],"additionalProperties":false}}},"required":["shares"],"additionalProperties":false}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}}}}},"/shares/{shareId}":{"get":{"operationId":"getShare","summary":"Get a share by ID","tags":["Share"],"description":"Get a share by ID","parameters":[{"schema":{"type":"string"},"in":"query","name":"password","required":false,"description":"The share password"},{"schema":{"type":"string"},"in":"path","name":"shareId","required":true,"description":"The share ID"}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"share":{"type":"object","properties":{"id":{"type":"string","description":"The share ID"},"name":{"type":"string","nullable":true,"description":"The share name"},"description":{"type":"string","nullable":true,"description":"The share description"},"expiration":{"type":"string","nullable":true,"description":"The share expiration date"},"views":{"type":"number","description":"The number of views"},"createdAt":{"type":"string","description":"The share creation date"},"updatedAt":{"type":"string","description":"The share update date"},"creatorId":{"type":"string","description":"The creator ID"},"security":{"type":"object","properties":{"maxViews":{"type":"number","nullable":true,"description":"The maximum number of views"},"hasPassword":{"type":"boolean","description":"Whether the share has a password"}},"required":["maxViews","hasPassword"],"additionalProperties":false},"files":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The file ID"},"name":{"type":"string","description":"The file name"},"description":{"type":"string","nullable":true,"description":"The file description"},"extension":{"type":"string","description":"The file extension"},"size":{"type":"string","description":"The file size"},"objectName":{"type":"string","description":"The file object name"},"userId":{"type":"string","description":"The user ID"},"createdAt":{"type":"string","description":"The file creation date"},"updatedAt":{"type":"string","description":"The file update date"}},"required":["id","name","description","extension","size","objectName","userId","createdAt","updatedAt"],"additionalProperties":false}},"recipients":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The recipient ID"},"email":{"type":"string","format":"email","description":"The recipient email"},"createdAt":{"type":"string","description":"The recipient creation date"},"updatedAt":{"type":"string","description":"The recipient update date"}},"required":["id","email","createdAt","updatedAt"],"additionalProperties":false}},"alias":{"type":"object","properties":{"id":{"type":"string"},"alias":{"type":"string"},"shareId":{"type":"string"},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["id","alias","shareId","createdAt","updatedAt"],"additionalProperties":false,"nullable":true}},"required":["id","name","description","expiration","views","createdAt","updatedAt","creatorId","security","files","recipients","alias"],"additionalProperties":false}},"required":["share"],"additionalProperties":false}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}}}}},"/shares/{id}":{"delete":{"operationId":"deleteShare","summary":"Delete a share","tags":["Share"],"description":"Delete a share","parameters":[{"schema":{"type":"string"},"in":"path","name":"id","required":true,"description":"The share ID"}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"share":{"type":"object","properties":{"id":{"type":"string","description":"The share ID"},"name":{"type":"string","nullable":true,"description":"The share name"},"description":{"type":"string","nullable":true,"description":"The share description"},"expiration":{"type":"string","nullable":true,"description":"The share expiration date"},"views":{"type":"number","description":"The number of views"},"createdAt":{"type":"string","description":"The share creation date"},"updatedAt":{"type":"string","description":"The share update date"},"creatorId":{"type":"string","description":"The creator ID"},"security":{"type":"object","properties":{"maxViews":{"type":"number","nullable":true,"description":"The maximum number of views"},"hasPassword":{"type":"boolean","description":"Whether the share has a password"}},"required":["maxViews","hasPassword"],"additionalProperties":false},"files":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The file ID"},"name":{"type":"string","description":"The file name"},"description":{"type":"string","nullable":true,"description":"The file description"},"extension":{"type":"string","description":"The file extension"},"size":{"type":"string","description":"The file size"},"objectName":{"type":"string","description":"The file object name"},"userId":{"type":"string","description":"The user ID"},"createdAt":{"type":"string","description":"The file creation date"},"updatedAt":{"type":"string","description":"The file update date"}},"required":["id","name","description","extension","size","objectName","userId","createdAt","updatedAt"],"additionalProperties":false}},"recipients":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The recipient ID"},"email":{"type":"string","format":"email","description":"The recipient email"},"createdAt":{"type":"string","description":"The recipient creation date"},"updatedAt":{"type":"string","description":"The recipient update date"}},"required":["id","email","createdAt","updatedAt"],"additionalProperties":false}},"alias":{"type":"object","properties":{"id":{"type":"string"},"alias":{"type":"string"},"shareId":{"type":"string"},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["id","alias","shareId","createdAt","updatedAt"],"additionalProperties":false,"nullable":true}},"required":["id","name","description","expiration","views","createdAt","updatedAt","creatorId","security","files","recipients","alias"],"additionalProperties":false}},"required":["share"],"additionalProperties":false}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}}}}},"/shares/{shareId}/password":{"patch":{"operationId":"updateSharePassword","summary":"Update share password","tags":["Share"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"password":{"type":"string","nullable":true,"description":"The new password. Send null to remove password"}},"required":["password"],"additionalProperties":false}}},"required":true},"parameters":[{"schema":{"type":"string"},"in":"path","name":"shareId","required":true}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"share":{"type":"object","properties":{"id":{"type":"string","description":"The share ID"},"name":{"type":"string","nullable":true,"description":"The share name"},"description":{"type":"string","nullable":true,"description":"The share description"},"expiration":{"type":"string","nullable":true,"description":"The share expiration date"},"views":{"type":"number","description":"The number of views"},"createdAt":{"type":"string","description":"The share creation date"},"updatedAt":{"type":"string","description":"The share update date"},"creatorId":{"type":"string","description":"The creator ID"},"security":{"type":"object","properties":{"maxViews":{"type":"number","nullable":true,"description":"The maximum number of views"},"hasPassword":{"type":"boolean","description":"Whether the share has a password"}},"required":["maxViews","hasPassword"],"additionalProperties":false},"files":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The file ID"},"name":{"type":"string","description":"The file name"},"description":{"type":"string","nullable":true,"description":"The file description"},"extension":{"type":"string","description":"The file extension"},"size":{"type":"string","description":"The file size"},"objectName":{"type":"string","description":"The file object name"},"userId":{"type":"string","description":"The user ID"},"createdAt":{"type":"string","description":"The file creation date"},"updatedAt":{"type":"string","description":"The file update date"}},"required":["id","name","description","extension","size","objectName","userId","createdAt","updatedAt"],"additionalProperties":false}},"recipients":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The recipient ID"},"email":{"type":"string","format":"email","description":"The recipient email"},"createdAt":{"type":"string","description":"The recipient creation date"},"updatedAt":{"type":"string","description":"The recipient update date"}},"required":["id","email","createdAt","updatedAt"],"additionalProperties":false}},"alias":{"type":"object","properties":{"id":{"type":"string"},"alias":{"type":"string"},"shareId":{"type":"string"},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["id","alias","shareId","createdAt","updatedAt"],"additionalProperties":false,"nullable":true}},"required":["id","name","description","expiration","views","createdAt","updatedAt","creatorId","security","files","recipients","alias"],"additionalProperties":false}},"required":["share"],"additionalProperties":false}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}}}}},"/shares/{shareId}/files":{"post":{"operationId":"addFiles","summary":"Add files to share","tags":["Share"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"files":{"type":"array","items":{"type":"string","minLength":1,"description":"The file IDs"}}},"required":["files"],"additionalProperties":false}}},"required":true},"parameters":[{"schema":{"type":"string"},"in":"path","name":"shareId","required":true,"description":"The share ID"}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"share":{"type":"object","properties":{"id":{"type":"string","description":"The share ID"},"name":{"type":"string","nullable":true,"description":"The share name"},"description":{"type":"string","nullable":true,"description":"The share description"},"expiration":{"type":"string","nullable":true,"description":"The share expiration date"},"views":{"type":"number","description":"The number of views"},"createdAt":{"type":"string","description":"The share creation date"},"updatedAt":{"type":"string","description":"The share update date"},"creatorId":{"type":"string","description":"The creator ID"},"security":{"type":"object","properties":{"maxViews":{"type":"number","nullable":true,"description":"The maximum number of views"},"hasPassword":{"type":"boolean","description":"Whether the share has a password"}},"required":["maxViews","hasPassword"],"additionalProperties":false},"files":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The file ID"},"name":{"type":"string","description":"The file name"},"description":{"type":"string","nullable":true,"description":"The file description"},"extension":{"type":"string","description":"The file extension"},"size":{"type":"string","description":"The file size"},"objectName":{"type":"string","description":"The file object name"},"userId":{"type":"string","description":"The user ID"},"createdAt":{"type":"string","description":"The file creation date"},"updatedAt":{"type":"string","description":"The file update date"}},"required":["id","name","description","extension","size","objectName","userId","createdAt","updatedAt"],"additionalProperties":false}},"recipients":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The recipient ID"},"email":{"type":"string","format":"email","description":"The recipient email"},"createdAt":{"type":"string","description":"The recipient creation date"},"updatedAt":{"type":"string","description":"The recipient update date"}},"required":["id","email","createdAt","updatedAt"],"additionalProperties":false}},"alias":{"type":"object","properties":{"id":{"type":"string"},"alias":{"type":"string"},"shareId":{"type":"string"},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["id","alias","shareId","createdAt","updatedAt"],"additionalProperties":false,"nullable":true}},"required":["id","name","description","expiration","views","createdAt","updatedAt","creatorId","security","files","recipients","alias"],"additionalProperties":false}},"required":["share"],"additionalProperties":false}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}}}},"delete":{"operationId":"removeFiles","summary":"Remove files from share","tags":["Share"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"files":{"type":"array","items":{"type":"string","minLength":1,"description":"The file IDs"}}},"required":["files"],"additionalProperties":false}}},"required":true},"parameters":[{"schema":{"type":"string"},"in":"path","name":"shareId","required":true,"description":"The share ID"}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"share":{"type":"object","properties":{"id":{"type":"string","description":"The share ID"},"name":{"type":"string","nullable":true,"description":"The share name"},"description":{"type":"string","nullable":true,"description":"The share description"},"expiration":{"type":"string","nullable":true,"description":"The share expiration date"},"views":{"type":"number","description":"The number of views"},"createdAt":{"type":"string","description":"The share creation date"},"updatedAt":{"type":"string","description":"The share update date"},"creatorId":{"type":"string","description":"The creator ID"},"security":{"type":"object","properties":{"maxViews":{"type":"number","nullable":true,"description":"The maximum number of views"},"hasPassword":{"type":"boolean","description":"Whether the share has a password"}},"required":["maxViews","hasPassword"],"additionalProperties":false},"files":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The file ID"},"name":{"type":"string","description":"The file name"},"description":{"type":"string","nullable":true,"description":"The file description"},"extension":{"type":"string","description":"The file extension"},"size":{"type":"string","description":"The file size"},"objectName":{"type":"string","description":"The file object name"},"userId":{"type":"string","description":"The user ID"},"createdAt":{"type":"string","description":"The file creation date"},"updatedAt":{"type":"string","description":"The file update date"}},"required":["id","name","description","extension","size","objectName","userId","createdAt","updatedAt"],"additionalProperties":false}},"recipients":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The recipient ID"},"email":{"type":"string","format":"email","description":"The recipient email"},"createdAt":{"type":"string","description":"The recipient creation date"},"updatedAt":{"type":"string","description":"The recipient update date"}},"required":["id","email","createdAt","updatedAt"],"additionalProperties":false}},"alias":{"type":"object","properties":{"id":{"type":"string"},"alias":{"type":"string"},"shareId":{"type":"string"},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["id","alias","shareId","createdAt","updatedAt"],"additionalProperties":false,"nullable":true}},"required":["id","name","description","expiration","views","createdAt","updatedAt","creatorId","security","files","recipients","alias"],"additionalProperties":false}},"required":["share"],"additionalProperties":false}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}}}}},"/shares/{shareId}/recipients":{"post":{"operationId":"addRecipients","summary":"Add recipients to a share","tags":["Share"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"emails":{"type":"array","items":{"type":"string","format":"email","description":"The recipient emails"}}},"required":["emails"],"additionalProperties":false}}},"required":true},"parameters":[{"schema":{"type":"string"},"in":"path","name":"shareId","required":true,"description":"The share ID"}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"share":{"type":"object","properties":{"id":{"type":"string","description":"The share ID"},"name":{"type":"string","nullable":true,"description":"The share name"},"description":{"type":"string","nullable":true,"description":"The share description"},"expiration":{"type":"string","nullable":true,"description":"The share expiration date"},"views":{"type":"number","description":"The number of views"},"createdAt":{"type":"string","description":"The share creation date"},"updatedAt":{"type":"string","description":"The share update date"},"creatorId":{"type":"string","description":"The creator ID"},"security":{"type":"object","properties":{"maxViews":{"type":"number","nullable":true,"description":"The maximum number of views"},"hasPassword":{"type":"boolean","description":"Whether the share has a password"}},"required":["maxViews","hasPassword"],"additionalProperties":false},"files":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The file ID"},"name":{"type":"string","description":"The file name"},"description":{"type":"string","nullable":true,"description":"The file description"},"extension":{"type":"string","description":"The file extension"},"size":{"type":"string","description":"The file size"},"objectName":{"type":"string","description":"The file object name"},"userId":{"type":"string","description":"The user ID"},"createdAt":{"type":"string","description":"The file creation date"},"updatedAt":{"type":"string","description":"The file update date"}},"required":["id","name","description","extension","size","objectName","userId","createdAt","updatedAt"],"additionalProperties":false}},"recipients":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The recipient ID"},"email":{"type":"string","format":"email","description":"The recipient email"},"createdAt":{"type":"string","description":"The recipient creation date"},"updatedAt":{"type":"string","description":"The recipient update date"}},"required":["id","email","createdAt","updatedAt"],"additionalProperties":false}},"alias":{"type":"object","properties":{"id":{"type":"string"},"alias":{"type":"string"},"shareId":{"type":"string"},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["id","alias","shareId","createdAt","updatedAt"],"additionalProperties":false,"nullable":true}},"required":["id","name","description","expiration","views","createdAt","updatedAt","creatorId","security","files","recipients","alias"],"additionalProperties":false}},"required":["share"],"additionalProperties":false}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}}}},"delete":{"operationId":"removeRecipients","summary":"Remove recipients from a share","tags":["Share"],"description":"Remove recipients from a share","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"emails":{"type":"array","items":{"type":"string","format":"email","description":"The recipient emails"}}},"required":["emails"],"additionalProperties":false}}},"required":true},"parameters":[{"schema":{"type":"string"},"in":"path","name":"shareId","required":true,"description":"The share ID"}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"share":{"type":"object","properties":{"id":{"type":"string","description":"The share ID"},"name":{"type":"string","nullable":true,"description":"The share name"},"description":{"type":"string","nullable":true,"description":"The share description"},"expiration":{"type":"string","nullable":true,"description":"The share expiration date"},"views":{"type":"number","description":"The number of views"},"createdAt":{"type":"string","description":"The share creation date"},"updatedAt":{"type":"string","description":"The share update date"},"creatorId":{"type":"string","description":"The creator ID"},"security":{"type":"object","properties":{"maxViews":{"type":"number","nullable":true,"description":"The maximum number of views"},"hasPassword":{"type":"boolean","description":"Whether the share has a password"}},"required":["maxViews","hasPassword"],"additionalProperties":false},"files":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The file ID"},"name":{"type":"string","description":"The file name"},"description":{"type":"string","nullable":true,"description":"The file description"},"extension":{"type":"string","description":"The file extension"},"size":{"type":"string","description":"The file size"},"objectName":{"type":"string","description":"The file object name"},"userId":{"type":"string","description":"The user ID"},"createdAt":{"type":"string","description":"The file creation date"},"updatedAt":{"type":"string","description":"The file update date"}},"required":["id","name","description","extension","size","objectName","userId","createdAt","updatedAt"],"additionalProperties":false}},"recipients":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The recipient ID"},"email":{"type":"string","format":"email","description":"The recipient email"},"createdAt":{"type":"string","description":"The recipient creation date"},"updatedAt":{"type":"string","description":"The recipient update date"}},"required":["id","email","createdAt","updatedAt"],"additionalProperties":false}},"alias":{"type":"object","properties":{"id":{"type":"string"},"alias":{"type":"string"},"shareId":{"type":"string"},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["id","alias","shareId","createdAt","updatedAt"],"additionalProperties":false,"nullable":true}},"required":["id","name","description","expiration","views","createdAt","updatedAt","creatorId","security","files","recipients","alias"],"additionalProperties":false}},"required":["share"],"additionalProperties":false}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}}}}},"/shares/{shareId}/alias":{"post":{"operationId":"createShareAlias","summary":"Create or update share alias","tags":["Share"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"alias":{"type":"string","pattern":"^[a-zA-Z0-9]+$","minLength":3,"maxLength":30}},"required":["alias"],"additionalProperties":false}}},"required":true},"parameters":[{"schema":{"type":"string"},"in":"path","name":"shareId","required":true,"description":"The share ID"}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"alias":{"type":"object","properties":{"id":{"type":"string"},"alias":{"type":"string"},"shareId":{"type":"string"},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["id","alias","shareId","createdAt","updatedAt"],"additionalProperties":false}},"required":["alias"],"additionalProperties":false}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"],"additionalProperties":false}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"],"additionalProperties":false}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"],"additionalProperties":false}}}}}}},"/shares/alias/{alias}":{"get":{"operationId":"getShareByAlias","summary":"Get share by alias","tags":["Share"],"parameters":[{"schema":{"type":"string"},"in":"query","name":"password","required":false,"description":"The share password"},{"schema":{"type":"string"},"in":"path","name":"alias","required":true,"description":"The share alias"}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"share":{"type":"object","properties":{"id":{"type":"string","description":"The share ID"},"name":{"type":"string","nullable":true,"description":"The share name"},"description":{"type":"string","nullable":true,"description":"The share description"},"expiration":{"type":"string","nullable":true,"description":"The share expiration date"},"views":{"type":"number","description":"The number of views"},"createdAt":{"type":"string","description":"The share creation date"},"updatedAt":{"type":"string","description":"The share update date"},"creatorId":{"type":"string","description":"The creator ID"},"security":{"type":"object","properties":{"maxViews":{"type":"number","nullable":true,"description":"The maximum number of views"},"hasPassword":{"type":"boolean","description":"Whether the share has a password"}},"required":["maxViews","hasPassword"],"additionalProperties":false},"files":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The file ID"},"name":{"type":"string","description":"The file name"},"description":{"type":"string","nullable":true,"description":"The file description"},"extension":{"type":"string","description":"The file extension"},"size":{"type":"string","description":"The file size"},"objectName":{"type":"string","description":"The file object name"},"userId":{"type":"string","description":"The user ID"},"createdAt":{"type":"string","description":"The file creation date"},"updatedAt":{"type":"string","description":"The file update date"}},"required":["id","name","description","extension","size","objectName","userId","createdAt","updatedAt"],"additionalProperties":false}},"recipients":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The recipient ID"},"email":{"type":"string","format":"email","description":"The recipient email"},"createdAt":{"type":"string","description":"The recipient creation date"},"updatedAt":{"type":"string","description":"The recipient update date"}},"required":["id","email","createdAt","updatedAt"],"additionalProperties":false}},"alias":{"type":"object","properties":{"id":{"type":"string"},"alias":{"type":"string"},"shareId":{"type":"string"},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}},"required":["id","alias","shareId","createdAt","updatedAt"],"additionalProperties":false,"nullable":true}},"required":["id","name","description","expiration","views","createdAt","updatedAt","creatorId","security","files","recipients","alias"],"additionalProperties":false}},"required":["share"],"additionalProperties":false}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"],"additionalProperties":false}}}}}}},"/shares/{shareId}/notify":{"post":{"operationId":"notifyRecipients","summary":"Send email notification to share recipients","tags":["Share"],"description":"Send email notification with share link to all recipients","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"shareLink":{"type":"string","format":"uri","description":"The frontend share URL"}},"required":["shareLink"],"additionalProperties":false}}},"required":true},"parameters":[{"schema":{"type":"string"},"in":"path","name":"shareId","required":true,"description":"The share ID"}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Success message"},"notifiedRecipients":{"type":"array","items":{"type":"string"},"description":"List of notified email addresses"}},"required":["message","notifiedRecipients"],"additionalProperties":false}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"],"additionalProperties":false}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"],"additionalProperties":false}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"],"additionalProperties":false}}}}}}},"/storage/disk-space":{"get":{"operationId":"getDiskSpace","summary":"Get server disk space information","tags":["Storage"],"description":"Get server disk space information","responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"diskSizeGB":{"type":"number","description":"The server disk size in GB"},"diskUsedGB":{"type":"number","description":"The server disk used in GB"},"diskAvailableGB":{"type":"number","description":"The server disk available in GB"},"uploadAllowed":{"type":"boolean","description":"Whether file upload is allowed"}},"required":["diskSizeGB","diskUsedGB","diskAvailableGB","uploadAllowed"],"additionalProperties":false}}}},"500":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}}}}},"/storage/check-upload":{"get":{"operationId":"checkUploadAllowed","summary":"Check if file upload is allowed","tags":["Storage"],"description":"Check if file upload is allowed based on available space (fileSize in bytes)","parameters":[{"schema":{"type":"string"},"in":"query","name":"fileSize","required":true,"description":"The file size in bytes"}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"diskSizeGB":{"type":"number","description":"The server disk size in GB"},"diskUsedGB":{"type":"number","description":"The server disk used in GB"},"diskAvailableGB":{"type":"number","description":"The server disk available in GB"},"uploadAllowed":{"type":"boolean","description":"Whether file upload is allowed"},"fileSizeInfo":{"type":"object","properties":{"bytes":{"type":"number"},"kb":{"type":"number"},"mb":{"type":"number"},"gb":{"type":"number"}},"required":["bytes","kb","mb","gb"],"additionalProperties":false}},"required":["diskSizeGB","diskUsedGB","diskAvailableGB","uploadAllowed","fileSizeInfo"],"additionalProperties":false}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}},"500":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}}}}},"/app/info":{"get":{"operationId":"getAppInfo","summary":"Get application base information","tags":["App"],"description":"Get application base information","responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"appName":{"type":"string","description":"The application name"},"appDescription":{"type":"string","description":"The application description"},"appLogo":{"type":"string","description":"The application logo"}},"required":["appName","appDescription","appLogo"],"additionalProperties":false}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}}}}},"/app/configs/{key}":{"patch":{"operationId":"updateConfig","summary":"Update a configuration value","tags":["App"],"description":"Update a configuration value (admin only)","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"value":{"type":"string","description":"The config value"}},"required":["value"],"additionalProperties":false}}},"required":true},"parameters":[{"schema":{"type":"string"},"in":"path","name":"key","required":true,"description":"The config key"}],"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"config":{"type":"object","properties":{"key":{"type":"string","description":"The config key"},"value":{"type":"string","description":"The config value"},"type":{"type":"string","description":"The config type"},"group":{"type":"string","description":"The config group"},"updatedAt":{"type":"string","format":"date-time","description":"The config update date"}},"required":["key","value","type","group","updatedAt"],"additionalProperties":false}},"required":["config"],"additionalProperties":false}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}},"404":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}}}}},"/app/configs":{"get":{"operationId":"getAllConfigs","summary":"List all configurations","tags":["App"],"description":"List all configurations (admin only)","responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"configs":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string","description":"The config key"},"value":{"type":"string","description":"The config value"},"type":{"type":"string","description":"The config type"},"group":{"type":"string","description":"The config group"},"updatedAt":{"type":"string","format":"date-time","description":"The config update date"}},"required":["key","value","type","group","updatedAt"],"additionalProperties":false}}},"required":["configs"],"additionalProperties":false}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}}}},"patch":{"operationId":"bulkUpdateConfigs","summary":"Bulk update configuration values","tags":["App"],"description":"Bulk update configuration values (admin only)","requestBody":{"content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string","description":"The config key"},"value":{"type":"string","description":"The config value"}},"required":["key","value"],"additionalProperties":false}}}}},"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"configs":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string","description":"The config key"},"value":{"type":"string","description":"The config value"},"type":{"type":"string","description":"The config type"},"group":{"type":"string","description":"The config group"},"updatedAt":{"type":"string","format":"date-time","description":"The config update date"}},"required":["key","value","type","group","updatedAt"],"additionalProperties":false}}},"required":["configs"],"additionalProperties":false}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}}}}},"/app/logo":{"post":{"operationId":"uploadLogo","summary":"Upload app logo","tags":["App"],"description":"Upload a new app logo (admin only)","requestBody":{"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"description":"Image file (JPG, PNG, GIF)"}},"additionalProperties":false}}}},"responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"logo":{"type":"string","description":"The logo URL"}},"required":["logo"],"additionalProperties":false}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}}}},"delete":{"operationId":"removeLogo","summary":"Remove app logo","tags":["App"],"description":"Remove the current app logo (admin only)","responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Success message"}},"required":["message"],"additionalProperties":false}}}},"400":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}},"401":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}},"403":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Error message"}},"required":["error"],"additionalProperties":false}}}}}}},"/health":{"get":{"operationId":"checkHealth","summary":"Check API Health","tags":["Health"],"description":"Returns the health status of the API","responses":{"200":{"description":"Default Response","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","description":"The health status"},"timestamp":{"type":"string","description":"The timestamp of the health check"}},"required":["status","timestamp"],"additionalProperties":false}}}}}}}},"tags":[{"name":"Health","description":"Health check endpoints"},{"name":"Authentication","description":"Authentication related endpoints"},{"name":"User","description":"User management endpoints"},{"name":"File","description":"File management endpoints"},{"name":"Share","description":"File sharing endpoints"},{"name":"Storage","description":"Storage management endpoints"},{"name":"App","description":"Application configuration endpoints"}]} \ No newline at end of file diff --git a/apps/web/src/App.tsx b/apps/web/src/App.tsx deleted file mode 100644 index f4f6754..0000000 --- a/apps/web/src/App.tsx +++ /dev/null @@ -1,85 +0,0 @@ -import { FilesPage } from "./pages/files/page"; -import { ForgotPasswordPage } from "./pages/forgot-password/page"; -import { ResetPasswordPage } from "./pages/reset-password/page"; -import { SettingsPage } from "./pages/settings/page"; -import { PublicSharePage } from "./pages/share/[alias]/page"; -import { SharesPage } from "./pages/shares/page"; -import { AdminProtectedRoute } from "@/components/route-protector/admin-protected-route"; -import { ProtectedRoute } from "@/components/route-protector/protected-route"; -import { DashboardPage } from "@/pages/dashboard/page"; -import { HomePage } from "@/pages/home/page"; -import { LoginPage } from "@/pages/login/page"; -import { ProfilePage } from "@/pages/profile/page"; -import { AdminAreaPage } from "@/pages/users-management/page"; -import { useEffect } from "react"; -import { useTranslation } from "react-i18next"; -import { Route, Routes } from "react-router-dom"; - -function App() { - const { i18n } = useTranslation(); - - useEffect(() => { - document.documentElement.dir = i18n.language === "ar-SA" ? "rtl" : "ltr"; - document.documentElement.lang = i18n.language; - }, [i18n.language]); - - return ( - - } path="/" /> - } path="/login" /> - - - - } - path="/dashboard" - /> - - - - } - path="/profile" - /> - - - - } - path="/settings" - /> - - - - } - path="/admin" - /> - - - - } - path="/files" - /> - - - - } - path="/shares" - /> - } path="/s/:alias" /> - } path="/forgot-password" /> - } path="/reset-password" /> - - ); -} - -export default App; diff --git a/apps/web/src/app/(home)/components/home-content.tsx b/apps/web/src/app/(home)/components/home-content.tsx new file mode 100644 index 0000000..97c1d2f --- /dev/null +++ b/apps/web/src/app/(home)/components/home-content.tsx @@ -0,0 +1,73 @@ +import Link from "next/link"; +import { IconBrandGithubFilled } from "@tabler/icons-react"; +import { motion } from "framer-motion"; +import { useTranslations } from "next-intl"; + +import { Button } from "@/components/ui/button"; +import { siteConfig } from "@/config/site"; +import { BackgroundLights } from "../../../components/ui/background-lights"; +import { HomeContentProps } from "../types"; +import { HomeHeader } from "./home-header"; + +const fadeInAnimation = { + animate: { opacity: 1 }, + initial: { opacity: 0 }, + transition: { duration: 0.5 }, +}; + +const fadeInUpAnimation = { + animate: { opacity: 1, y: 0 }, + initial: { opacity: 0, y: 20 }, + transition: { duration: 0.5 }, +}; + +function ActionButtons({ t }: { t: (key: string) => string }) { + return ( +
    + + +
    + ); +} + +export function HomeContent({ isLoading }: HomeContentProps) { + const t = useTranslations(); + + if (isLoading) { + return null; + } + + return ( +
    + +
    + + + {t("home.description")} + + + + +

    {t("home.privacyMessage")}

    +
    +
    +
    + ); +} diff --git a/apps/web/src/app/(home)/components/home-header.tsx b/apps/web/src/app/(home)/components/home-header.tsx new file mode 100644 index 0000000..77a733a --- /dev/null +++ b/apps/web/src/app/(home)/components/home-header.tsx @@ -0,0 +1,50 @@ +import { motion } from "framer-motion"; +import { useTranslations } from "next-intl"; + +import { HomeHeaderProps } from "../types"; + +const fadeInUpAnimation = { + animate: { opacity: 1, y: 0 }, + initial: { opacity: 0, y: 20 }, + transition: { duration: 0.5 }, +}; + +const titleAnimation = { + animate: { scale: 1 }, + initial: { scale: 0.9 }, + transition: { duration: 0.3 }, +}; + +const slideInAnimation = (delay: number, direction: -1 | 1) => ({ + animate: { opacity: 1, x: 0 }, + initial: { opacity: 0, x: 20 * direction }, + transition: { delay, duration: 0.5 }, +}); + +export function HomeHeader({ title }: HomeHeaderProps) { + const t = useTranslations(); + + return ( + +
    + + {title} + +
    + + {t("home.header.fileSharing")} + + + {t("home.header.tagline")} + +
    +
    +
    + ); +} diff --git a/apps/web/src/app/(home)/components/navbar.tsx b/apps/web/src/app/(home)/components/navbar.tsx new file mode 100644 index 0000000..fe3969a --- /dev/null +++ b/apps/web/src/app/(home)/components/navbar.tsx @@ -0,0 +1,91 @@ +"use client"; + +import { useEffect, useState } from "react"; // Add this import +import Link from "next/link"; +import { IconHeart, IconMenu2 } from "@tabler/icons-react"; + +import { LanguageSwitcher } from "@/components/general/language-switcher"; +import { ModeToggle } from "@/components/general/mode-toggle"; +import { Button } from "@/components/ui/button"; +import { Sheet, SheetContent, SheetTrigger } from "@/components/ui/sheet"; +import { siteConfig } from "@/config/site"; +import { useAppInfo } from "@/contexts/app-info-context"; +import { cn } from "@/lib/utils"; + +export function Navbar() { + const { appName, appLogo, refreshAppInfo } = useAppInfo(); + const [isMenuOpen, setIsMenuOpen] = useState(false); + + useEffect(() => { + refreshAppInfo(); + }, [refreshAppInfo]); + + return ( +
    +
    +
    +
    + + {appLogo && App Logo} +

    {appName}

    + + +
    +
    + + + + +
    + +
    + + + + + + + +
    +
    + {siteConfig.navMenuItems.map((item, index) => ( + setIsMenuOpen(false)} + > + {item.label} + + ))} +
    +
    +
    +
    +
    +
    +
    +
    + ); +} diff --git a/apps/web/src/app/(home)/hooks/use-home.ts b/apps/web/src/app/(home)/hooks/use-home.ts new file mode 100644 index 0000000..e0c0d5a --- /dev/null +++ b/apps/web/src/app/(home)/hooks/use-home.ts @@ -0,0 +1,52 @@ +"use client"; + +import { useEffect } from "react"; +import { useRouter } from "next/navigation"; +import { create } from "zustand"; + +import { getAllConfigs } from "@/http/endpoints"; + +interface Config { + key: string; + value: string; +} + +interface HomeStore { + isLoading: boolean; + checkHomePageAccess: () => Promise; +} + +const useHomeStore = create((set) => ({ + isLoading: true, + checkHomePageAccess: async () => { + try { + const response = await getAllConfigs(); + const showHomePage = + response.data.configs.find((config: Config) => config.key === "showHomePage")?.value === "true"; + + set({ isLoading: false }); + return showHomePage; + } catch (error) { + console.error("Failed to check homepage access:", error); + set({ isLoading: false }); + return false; + } + }, +})); + +export function useHome() { + const router = useRouter(); + const { isLoading, checkHomePageAccess } = useHomeStore(); + + useEffect(() => { + checkHomePageAccess().then((hasAccess) => { + if (!hasAccess) { + router.push("/login"); + } + }); + }, [router, checkHomePageAccess]); + + return { + isLoading, + }; +} diff --git a/apps/web/src/app/(home)/layout.tsx b/apps/web/src/app/(home)/layout.tsx new file mode 100644 index 0000000..9aaabe2 --- /dev/null +++ b/apps/web/src/app/(home)/layout.tsx @@ -0,0 +1,14 @@ +import { Metadata } from "next"; +import { getTranslations } from "next-intl/server"; + +export async function generateMetadata(): Promise { + const t = await getTranslations(); + + return { + title: `${t("home.pageTitle")} `, + }; +} + +export default function HomeLayout({ children }: { children: React.ReactNode }) { + return <>{children}; +} diff --git a/apps/web/src/pages/home/page.tsx b/apps/web/src/app/(home)/page.tsx similarity index 72% rename from apps/web/src/pages/home/page.tsx rename to apps/web/src/app/(home)/page.tsx index 441a4f0..32f0a1c 100644 --- a/apps/web/src/pages/home/page.tsx +++ b/apps/web/src/app/(home)/page.tsx @@ -1,16 +1,12 @@ +"use client"; + +import { LoadingScreen } from "@/components/layout/loading-screen"; +import { DefaultFooter } from "@/components/ui/default-footer"; import { HomeContent } from "./components/home-content"; import { Navbar } from "./components/navbar"; import { useHome } from "./hooks/use-home"; -import { LoadingScreen } from "@/components/layout/loading-screen"; -import { DefaultFooter } from "@/components/ui/default-footer"; -import { usePageTitle } from "@/hooks/use-page-title"; -import { useTranslation } from "react-i18next"; - -export function HomePage() { - const { t } = useTranslation(); - - usePageTitle(t("home.pageTitle")); +export default function HomePage() { const { isLoading } = useHome(); if (isLoading) { diff --git a/apps/web/src/pages/home/types/index.ts b/apps/web/src/app/(home)/types/index.ts similarity index 65% rename from apps/web/src/pages/home/types/index.ts rename to apps/web/src/app/(home)/types/index.ts index 9c7f811..e5a790e 100644 --- a/apps/web/src/pages/home/types/index.ts +++ b/apps/web/src/app/(home)/types/index.ts @@ -5,3 +5,8 @@ export interface HomeContentProps { export interface HomeHeaderProps { title: string; } + +export interface Config { + key: string; + value: string; +} diff --git a/apps/web/src/app/(shares)/s/[alias]/components/files-table.tsx b/apps/web/src/app/(shares)/s/[alias]/components/files-table.tsx new file mode 100644 index 0000000..11b5582 --- /dev/null +++ b/apps/web/src/app/(shares)/s/[alias]/components/files-table.tsx @@ -0,0 +1,78 @@ +import { IconDownload } from "@tabler/icons-react"; +import { useTranslations } from "next-intl"; + +import { Button } from "@/components/ui/button"; +import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"; +import { getFileIcon } from "@/utils/file-icons"; +import { formatFileSize } from "@/utils/format-file-size"; +import { ShareFilesTableProps } from "../types"; + +export function ShareFilesTable({ files, onDownload }: ShareFilesTableProps) { + const t = useTranslations(); + + const formatDateTime = (dateString: string) => { + const date = new Date(dateString); + return new Intl.DateTimeFormat("en-US", { + year: "numeric", + month: "2-digit", + day: "2-digit", + hour: "2-digit", + minute: "2-digit", + hour12: false, + }).format(date); + }; + + return ( +
    +
    + + + + + {t("filesTable.columns.name")} + + + {t("filesTable.columns.size")} + + + {t("filesTable.columns.createdAt")} + + + {t("filesTable.columns.actions")} + + + + + {files.map((file) => { + const { icon: FileIcon, color } = getFileIcon(file.name); + + return ( + + +
    + + {file.name} +
    +
    + {formatFileSize(Number(file.size))} + {formatDateTime(file.createdAt)} + + + +
    + ); + })} +
    +
    +
    +
    + ); +} diff --git a/apps/web/src/app/(shares)/s/[alias]/components/password-modal.tsx b/apps/web/src/app/(shares)/s/[alias]/components/password-modal.tsx new file mode 100644 index 0000000..12344f8 --- /dev/null +++ b/apps/web/src/app/(shares)/s/[alias]/components/password-modal.tsx @@ -0,0 +1,42 @@ +import { IconLock } from "@tabler/icons-react"; +import { useTranslations } from "next-intl"; + +import { Button } from "@/components/ui/button"; +import { Dialog, DialogContent, DialogFooter, DialogHeader } from "@/components/ui/dialog"; +import { Input } from "@/components/ui/input"; +import { PasswordModalProps } from "../types"; + +export function PasswordModal({ isOpen, password, isError, onPasswordChange, onSubmit }: PasswordModalProps) { + const t = useTranslations(); + + return ( + {}} modal> + + +

    {t("share.password.title")}

    +
    + +

    {t("share.password.protected")}

    +
    + {isError && ( +
    +

    {t("share.password.incorrect")}

    +
    + )} +
    +
    + onPasswordChange(e.target.value)} + onKeyDown={(e) => e.key === "Enter" && onSubmit()} + /> +
    + + + +
    +
    + ); +} diff --git a/apps/web/src/pages/share/[alias]/components/share-details.tsx b/apps/web/src/app/(shares)/s/[alias]/components/share-details.tsx similarity index 70% rename from apps/web/src/pages/share/[alias]/components/share-details.tsx rename to apps/web/src/app/(shares)/s/[alias]/components/share-details.tsx index fa24250..09987c2 100644 --- a/apps/web/src/pages/share/[alias]/components/share-details.tsx +++ b/apps/web/src/app/(shares)/s/[alias]/components/share-details.tsx @@ -1,24 +1,25 @@ +import { IconShare } from "@tabler/icons-react"; +import { format } from "date-fns"; +import { useTranslations } from "next-intl"; + +import { Card, CardContent } from "@/components/ui/card"; import { ShareDetailsProps } from "../types"; import { ShareFilesTable } from "./files-table"; -import { Card, CardBody } from "@heroui/card"; -import { format } from "date-fns"; -import { useTranslation } from "react-i18next"; -import { FaShare } from "react-icons/fa"; export function ShareDetails({ share, onDownload }: ShareDetailsProps) { - const { t } = useTranslation(); + const t = useTranslations(); return ( - +
    - +

    {share.name || t("share.details.untitled")}

    - {share.description &&

    {share.description}

    } -
    + {share.description &&

    {share.description}

    } +
    {t("share.details.created", { date: format(new Date(share.createdAt), "MM/dd/yyyy HH:mm"), @@ -36,7 +37,7 @@ export function ShareDetails({ share, onDownload }: ShareDetailsProps) {
    - + ); } diff --git a/apps/web/src/pages/share/[alias]/components/share-header.tsx b/apps/web/src/app/(shares)/s/[alias]/components/share-header.tsx similarity index 80% rename from apps/web/src/pages/share/[alias]/components/share-header.tsx rename to apps/web/src/app/(shares)/s/[alias]/components/share-header.tsx index ccb3e48..73204e3 100644 --- a/apps/web/src/pages/share/[alias]/components/share-header.tsx +++ b/apps/web/src/app/(shares)/s/[alias]/components/share-header.tsx @@ -1,7 +1,9 @@ +import Image from "next/image"; +import Link from "next/link"; + import { LanguageSwitcher } from "@/components/general/language-switcher"; -import { ThemeSwitch } from "@/components/general/theme-switch"; +import { ModeToggle } from "@/components/general/mode-toggle"; import { useAppInfo } from "@/contexts/app-info-context"; -import { Link } from "@heroui/link"; export function ShareHeader() { const { appName, appLogo } = useAppInfo(); @@ -10,12 +12,12 @@ export function ShareHeader() {
    - {appLogo && App Logo} + {appLogo && App Logo}

    {appName}

    - +
    diff --git a/apps/web/src/app/(shares)/s/[alias]/components/share-not-found.tsx b/apps/web/src/app/(shares)/s/[alias]/components/share-not-found.tsx new file mode 100644 index 0000000..4bed381 --- /dev/null +++ b/apps/web/src/app/(shares)/s/[alias]/components/share-not-found.tsx @@ -0,0 +1,24 @@ +import { IconLock } from "@tabler/icons-react"; +import { useTranslations } from "next-intl"; + +import { Card, CardContent } from "@/components/ui/card"; + +export function ShareNotFound() { + const t = useTranslations(); + + return ( + + +
    +
    + +
    +

    {t("share.notFound.title")}

    +
    +
    +

    {t("share.notFound.description")}

    +
    +
    +
    + ); +} diff --git a/apps/web/src/pages/share/[alias]/hooks/use-public-share.ts b/apps/web/src/app/(shares)/s/[alias]/hooks/use-public-share.ts similarity index 91% rename from apps/web/src/pages/share/[alias]/hooks/use-public-share.ts rename to apps/web/src/app/(shares)/s/[alias]/hooks/use-public-share.ts index a3c0ed8..3fb07ea 100644 --- a/apps/web/src/pages/share/[alias]/hooks/use-public-share.ts +++ b/apps/web/src/app/(shares)/s/[alias]/hooks/use-public-share.ts @@ -1,13 +1,17 @@ -import { getDownloadUrl, getShareByAlias } from "@/http/endpoints"; -import type { GetShareByAlias200Share } from "@/http/models/getShareByAlias200Share"; -import { useState, useEffect } from "react"; -import { useTranslation } from "react-i18next"; -import { useParams } from "react-router-dom"; +"use client"; + +import { useEffect, useState } from "react"; +import { useParams } from "next/navigation"; +import { useTranslations } from "next-intl"; import { toast } from "sonner"; +import { getDownloadUrl, getShareByAlias } from "@/http/endpoints"; +import type { GetShareByAlias200Share } from "@/http/models/getShareByAlias200Share"; + export function usePublicShare() { - const { t } = useTranslation(); - const { alias } = useParams<{ alias: string }>(); + const t = useTranslations(); + const params = useParams(); + const alias = params?.alias as string; const [share, setShare] = useState(null); const [isLoading, setIsLoading] = useState(true); const [password, setPassword] = useState(""); diff --git a/apps/web/src/app/(shares)/s/[alias]/layout.tsx b/apps/web/src/app/(shares)/s/[alias]/layout.tsx new file mode 100644 index 0000000..b10b883 --- /dev/null +++ b/apps/web/src/app/(shares)/s/[alias]/layout.tsx @@ -0,0 +1,18 @@ +import { Metadata } from "next"; +import { getTranslations } from "next-intl/server"; + +interface LayoutProps { + children: React.ReactNode; +} + +export async function generateMetadata(): Promise { + const t = await getTranslations(); + + return { + title: `${t("share.pageTitle")}`, + }; +} + +export default function DashboardLayout({ children }: LayoutProps) { + return <>{children}; +} diff --git a/apps/web/src/pages/share/[alias]/page.tsx b/apps/web/src/app/(shares)/s/[alias]/page.tsx similarity index 85% rename from apps/web/src/pages/share/[alias]/page.tsx rename to apps/web/src/app/(shares)/s/[alias]/page.tsx index daf27dc..d2b188a 100644 --- a/apps/web/src/pages/share/[alias]/page.tsx +++ b/apps/web/src/app/(shares)/s/[alias]/page.tsx @@ -1,15 +1,14 @@ +"use client"; + +import { LoadingScreen } from "@/components/layout/loading-screen"; +import { DefaultFooter } from "@/components/ui/default-footer"; import { PasswordModal } from "./components/password-modal"; import { ShareDetails } from "./components/share-details"; import { ShareHeader } from "./components/share-header"; import { ShareNotFound } from "./components/share-not-found"; import { usePublicShare } from "./hooks/use-public-share"; -import { LoadingScreen } from "@/components/layout/loading-screen"; -import { DefaultFooter } from "@/components/ui/default-footer"; -import { usePageTitle } from "@/hooks/use-page-title"; -import { useTranslation } from "react-i18next"; -export function PublicSharePage() { - const { t } = useTranslation(); +export default function PublicSharePage() { const { isLoading, share, @@ -21,8 +20,6 @@ export function PublicSharePage() { handleDownload, } = usePublicShare(); - usePageTitle(share?.name ?? t("share.pageTitle")); - if (isLoading) { return ; } diff --git a/apps/web/src/pages/share/[alias]/types/index.tsx b/apps/web/src/app/(shares)/s/[alias]/types/index.tsx similarity index 100% rename from apps/web/src/pages/share/[alias]/types/index.tsx rename to apps/web/src/app/(shares)/s/[alias]/types/index.tsx diff --git a/apps/web/src/pages/shares/components/empty-shares-state.tsx b/apps/web/src/app/(shares)/shares/components/empty-shares-state.tsx similarity index 50% rename from apps/web/src/pages/shares/components/empty-shares-state.tsx rename to apps/web/src/app/(shares)/shares/components/empty-shares-state.tsx index 3dd0f9b..e38d07a 100644 --- a/apps/web/src/pages/shares/components/empty-shares-state.tsx +++ b/apps/web/src/app/(shares)/shares/components/empty-shares-state.tsx @@ -1,19 +1,21 @@ -import { Button } from "@heroui/button"; -import { useTranslation } from "react-i18next"; -import { FaShare, FaPlus } from "react-icons/fa"; +import { IconPlus, IconShare } from "@tabler/icons-react"; +import { useTranslations } from "next-intl"; + +import { Button } from "@/components/ui/button"; interface EmptySharesStateProps { onCreateShare: () => void; } export function EmptySharesState({ onCreateShare }: EmptySharesStateProps) { - const { t } = useTranslation(); + const t = useTranslations(); return (
    - +

    {t("shares.empty.message")}

    -
    diff --git a/apps/web/src/app/(shares)/shares/components/shares-header.tsx b/apps/web/src/app/(shares)/shares/components/shares-header.tsx new file mode 100644 index 0000000..f8b8a68 --- /dev/null +++ b/apps/web/src/app/(shares)/shares/components/shares-header.tsx @@ -0,0 +1,44 @@ +import Link from "next/link"; +import { IconLayoutDashboard, IconShare } from "@tabler/icons-react"; +import { useTranslations } from "next-intl"; + +import { + Breadcrumb, + BreadcrumbItem, + BreadcrumbLink, + BreadcrumbList, + BreadcrumbSeparator, +} from "@/components/ui/breadcrumb"; +import { Separator } from "@/components/ui/separator"; + +export function SharesHeader() { + const t = useTranslations(); + + return ( +
    +
    + +

    {t("shares.header.title")}

    +
    + + + + + + + + {t("common.dashboard")} + + + + + + + {t("shares.header.myShares")} + + + + +
    + ); +} diff --git a/apps/web/src/pages/shares/components/shares-modals.tsx b/apps/web/src/app/(shares)/shares/components/shares-modals.tsx similarity index 100% rename from apps/web/src/pages/shares/components/shares-modals.tsx rename to apps/web/src/app/(shares)/shares/components/shares-modals.tsx index 8628f61..e3801a3 100644 --- a/apps/web/src/pages/shares/components/shares-modals.tsx +++ b/apps/web/src/app/(shares)/shares/components/shares-modals.tsx @@ -1,8 +1,8 @@ -import { SharesModalsProps } from "../types"; import { CreateShareModal } from "@/components/modals/create-share-modal"; import { GenerateShareLinkModal } from "@/components/modals/generate-share-link-modal"; import { ShareActionsModals } from "@/components/modals/share-actions-modals"; import { ShareDetailsModal } from "@/components/modals/share-details-modal"; +import { SharesModalsProps } from "../types"; export function SharesModals({ isCreateModalOpen, diff --git a/apps/web/src/app/(shares)/shares/components/shares-search.tsx b/apps/web/src/app/(shares)/shares/components/shares-search.tsx new file mode 100644 index 0000000..8845c68 --- /dev/null +++ b/apps/web/src/app/(shares)/shares/components/shares-search.tsx @@ -0,0 +1,48 @@ +import { IconPlus, IconSearch } from "@tabler/icons-react"; +import { useTranslations } from "next-intl"; + +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import { SharesSearchProps } from "../types"; + +export function SharesSearch({ + searchQuery, + onSearchChange, + onCreateShare, + totalShares, + filteredCount, +}: SharesSearchProps) { + const t = useTranslations(); + + return ( +
    +
    +

    {t("shares.search.title")}

    + +
    + +
    +
    + + onSearchChange(e.target.value)} + /> +
    + {searchQuery && ( + + {t("shares.search.results", { + filtered: filteredCount, + total: totalShares, + })} + + )} +
    +
    + ); +} diff --git a/apps/web/src/pages/shares/components/shares-table-container.tsx b/apps/web/src/app/(shares)/shares/components/shares-table-container.tsx similarity index 100% rename from apps/web/src/pages/shares/components/shares-table-container.tsx rename to apps/web/src/app/(shares)/shares/components/shares-table-container.tsx index 04c17c0..4f35e76 100644 --- a/apps/web/src/pages/shares/components/shares-table-container.tsx +++ b/apps/web/src/app/(shares)/shares/components/shares-table-container.tsx @@ -1,6 +1,6 @@ +import { SharesTable } from "@/components/tables/shares-table"; import { SharesTableContainerProps } from "../types"; import { EmptySharesState } from "./empty-shares-state"; -import { SharesTable } from "@/components/tables/shares-table"; export function SharesTableContainer({ shares, onCopyLink, onCreateShare, shareManager }: SharesTableContainerProps) { return shares.length > 0 ? ( diff --git a/apps/web/src/pages/shares/hooks/use-shares.ts b/apps/web/src/app/(shares)/shares/hooks/use-shares.ts similarity index 87% rename from apps/web/src/pages/shares/hooks/use-shares.ts rename to apps/web/src/app/(shares)/shares/hooks/use-shares.ts index 66db2f5..a9d95ff 100644 --- a/apps/web/src/pages/shares/hooks/use-shares.ts +++ b/apps/web/src/app/(shares)/shares/hooks/use-shares.ts @@ -1,17 +1,19 @@ -import { getAllConfigs, listUserShares, notifyRecipients } from "@/http/endpoints"; -import { ListUserShares200SharesItem } from "@/http/models/listUserShares200SharesItem"; -import { ShareType } from "@/types/share"; +"use client"; + import { useEffect, useState } from "react"; -import { useTranslation } from "react-i18next"; +import { useTranslations } from "next-intl"; import { toast } from "sonner"; +import { getAllConfigs, listUserShares, notifyRecipients } from "@/http/endpoints"; +import { ListUserShares200SharesItem } from "@/http/models/listUserShares200SharesItem"; + export function useShares() { - const { t } = useTranslation(); - const [shares, setShares] = useState([]); + const t = useTranslations(); + const [shares, setShares] = useState([]); const [isLoading, setIsLoading] = useState(true); const [searchQuery, setSearchQuery] = useState(""); - const [shareToViewDetails, setShareToViewDetails] = useState(null); - const [shareToGenerateLink, setShareToGenerateLink] = useState(null); + const [shareToViewDetails, setShareToViewDetails] = useState(null); + const [shareToGenerateLink, setShareToGenerateLink] = useState(null); const [smtpEnabled, setSmtpEnabled] = useState("false"); const loadShares = async () => { @@ -47,7 +49,6 @@ export function useShares() { loadConfigs(); }, []); - // Filter shares based on search query const filteredShares = shares.filter( (share) => share.name?.toLowerCase().includes(searchQuery.toLowerCase()) ?? false ); @@ -76,7 +77,6 @@ export function useShares() { }; return { - // State shares, isLoading, searchQuery, @@ -84,8 +84,6 @@ export function useShares() { shareToGenerateLink, filteredShares, smtpEnabled, - - // Actions setSearchQuery, setShareToViewDetails, setShareToGenerateLink, diff --git a/apps/web/src/app/(shares)/shares/layout.tsx b/apps/web/src/app/(shares)/shares/layout.tsx new file mode 100644 index 0000000..fce242e --- /dev/null +++ b/apps/web/src/app/(shares)/shares/layout.tsx @@ -0,0 +1,18 @@ +import { Metadata } from "next"; +import { getTranslations } from "next-intl/server"; + +interface LayoutProps { + children: React.ReactNode; +} + +export async function generateMetadata(): Promise { + const t = await getTranslations(); + + return { + title: `${t("shares.pageTitle")}`, + }; +} + +export default function UsersManagementLayout({ children }: LayoutProps) { + return <>{children}; +} diff --git a/apps/web/src/app/(shares)/shares/page.tsx b/apps/web/src/app/(shares)/shares/page.tsx new file mode 100644 index 0000000..69c04ca --- /dev/null +++ b/apps/web/src/app/(shares)/shares/page.tsx @@ -0,0 +1,84 @@ +"use client"; + +import { ProtectedRoute } from "@/components/auth/protected-route"; +import { LoadingScreen } from "@/components/layout/loading-screen"; +import { Navbar } from "@/components/layout/navbar"; +import { Card, CardContent } from "@/components/ui/card"; +import { DefaultFooter } from "@/components/ui/default-footer"; +import { useDisclosure } from "@/hooks/use-disclosure"; +import { useShareManager } from "@/hooks/use-share-manager"; +import { SharesHeader } from "./components/shares-header"; +import { SharesModals } from "./components/shares-modals"; +import { SharesSearch } from "./components/shares-search"; +import { SharesTableContainer } from "./components/shares-table-container"; +import { useShares } from "./hooks/use-shares"; + +export default function SharesPage() { + const { + shares, + isLoading, + searchQuery, + setSearchQuery, + filteredShares, + shareToViewDetails, + shareToGenerateLink, + handleCopyLink, + loadShares, + setShareToViewDetails, + setShareToGenerateLink, + smtpEnabled, + } = useShares(); + + const { isOpen: isCreateModalOpen, onOpen: onOpenCreateModal, onClose: onCloseCreateModal } = useDisclosure(); + const shareManager = useShareManager(loadShares); + + if (isLoading) { + return ; + } + + return ( + +
    + +
    +
    + + + +
    + + + +
    +
    +
    + + setShareToGenerateLink(null)} + onCloseViewDetails={() => setShareToViewDetails(null)} + onSuccess={loadShares} + /> +
    +
    + +
    +
    + ); +} diff --git a/apps/web/src/pages/shares/types/index.ts b/apps/web/src/app/(shares)/shares/types/index.ts similarity index 54% rename from apps/web/src/pages/shares/types/index.ts rename to apps/web/src/app/(shares)/shares/types/index.ts index 7679805..a2165cc 100644 --- a/apps/web/src/pages/shares/types/index.ts +++ b/apps/web/src/app/(shares)/shares/types/index.ts @@ -1,4 +1,4 @@ -import { ShareType } from "@/types/share"; +import { ListUserShares200SharesItem } from "@/http/models"; export interface SharesSearchProps { searchQuery: string; @@ -16,25 +16,23 @@ export interface SharesTableContainerProps { } export interface ShareManager { - // State properties - shareToDelete: ShareType | null; - shareToEdit: ShareType | null; - shareToManageFiles: ShareType | null; - shareToManageRecipients: ShareType | null; + shareToDelete: ListUserShares200SharesItem | null; + shareToEdit: ListUserShares200SharesItem | null; + shareToManageFiles: ListUserShares200SharesItem | null; + shareToManageRecipients: ListUserShares200SharesItem | null; - // Actions (existing properties) - setShareToDelete: (share: ShareType | null) => void; - setShareToEdit: (share: ShareType | null) => void; - setShareToManageFiles: (share: ShareType | null) => void; - setShareToManageRecipients: (share: ShareType | null) => void; - setShareToViewDetails: (share: ShareType | null) => void; - setShareToGenerateLink: (share: ShareType | null) => void; + setShareToDelete: (share: ListUserShares200SharesItem | null) => void; + setShareToEdit: (share: ListUserShares200SharesItem | null) => void; + setShareToManageFiles: (share: ListUserShares200SharesItem | null) => void; + setShareToManageRecipients: (share: ListUserShares200SharesItem | null) => void; + setShareToViewDetails: (share: ListUserShares200SharesItem | null) => void; + setShareToGenerateLink: (share: ListUserShares200SharesItem | null) => void; handleDelete: (shareId: string) => Promise; handleEdit: (shareId: string, data: any) => Promise; handleManageFiles: (shareId: string, files: any[]) => Promise; handleManageRecipients: (shareId: string, recipients: any[]) => Promise; handleGenerateLink: (shareId: string, alias: string) => Promise; - handleNotifyRecipients: (share: ShareType) => Promise; + handleNotifyRecipients: (share: ListUserShares200SharesItem) => Promise; } export interface SharesModalsProps { diff --git a/apps/web/src/app/api/(proxy)/app/check-upload/route.ts b/apps/web/src/app/api/(proxy)/app/check-upload/route.ts new file mode 100644 index 0000000..05645b2 --- /dev/null +++ b/apps/web/src/app/api/(proxy)/app/check-upload/route.ts @@ -0,0 +1,28 @@ +import { NextRequest, NextResponse } from "next/server"; + +export async function GET(req: NextRequest) { + const cookieHeader = req.headers.get("cookie"); + + const apiRes = await fetch(`${process.env.API_BASE_URL}/storage/check-upload`, { + method: "GET", + headers: { + cookie: cookieHeader || "", + }, + redirect: "manual", + }); + + const resBody = await apiRes.text(); + const res = new NextResponse(resBody, { + status: apiRes.status, + headers: { + "Content-Type": "application/json", + }, + }); + + const setCookie = apiRes.headers.getSetCookie?.() || []; + if (setCookie.length > 0) { + res.headers.set("Set-Cookie", setCookie.join(",")); + } + + return res; +} diff --git a/apps/web/src/app/api/(proxy)/app/configs/route.ts b/apps/web/src/app/api/(proxy)/app/configs/route.ts new file mode 100644 index 0000000..70d5090 --- /dev/null +++ b/apps/web/src/app/api/(proxy)/app/configs/route.ts @@ -0,0 +1,30 @@ +import { NextRequest, NextResponse } from "next/server"; + +export async function GET(req: NextRequest) { + const cookieHeader = req.headers.get("cookie"); + + const apiRes = await fetch(`${process.env.API_BASE_URL}/app/configs`, { + method: "GET", + headers: { + cookie: cookieHeader || "", + }, + redirect: "manual", + }); + + const resBody = await apiRes.text(); + const res = new NextResponse(resBody, { + status: apiRes.status, + headers: { + "Content-Type": "application/json", + }, + }); + + const setCookie = apiRes.headers.getSetCookie?.() || []; + if (setCookie.length > 0) { + res.headers.set("Set-Cookie", setCookie.join(",")); + } + + console.log(res); + + return res; +} diff --git a/apps/web/src/app/api/(proxy)/app/disk-space/route.ts b/apps/web/src/app/api/(proxy)/app/disk-space/route.ts new file mode 100644 index 0000000..d753ce9 --- /dev/null +++ b/apps/web/src/app/api/(proxy)/app/disk-space/route.ts @@ -0,0 +1,28 @@ +import { NextRequest, NextResponse } from "next/server"; + +export async function GET(req: NextRequest) { + const cookieHeader = req.headers.get("cookie"); + + const apiRes = await fetch(`${process.env.API_BASE_URL}/storage/disk-space`, { + method: "GET", + headers: { + cookie: cookieHeader || "", + }, + redirect: "manual", + }); + + const resBody = await apiRes.text(); + const res = new NextResponse(resBody, { + status: apiRes.status, + headers: { + "Content-Type": "application/json", + }, + }); + + const setCookie = apiRes.headers.getSetCookie?.() || []; + if (setCookie.length > 0) { + res.headers.set("Set-Cookie", setCookie.join(",")); + } + + return res; +} diff --git a/apps/web/src/app/api/(proxy)/app/health/route.ts b/apps/web/src/app/api/(proxy)/app/health/route.ts new file mode 100644 index 0000000..4366da6 --- /dev/null +++ b/apps/web/src/app/api/(proxy)/app/health/route.ts @@ -0,0 +1,28 @@ +import { NextRequest, NextResponse } from "next/server"; + +export async function GET(req: NextRequest) { + const cookieHeader = req.headers.get("cookie"); + + const apiRes = await fetch(`${process.env.API_BASE_URL}/health`, { + method: "GET", + headers: { + cookie: cookieHeader || "", + }, + redirect: "manual", + }); + + const resBody = await apiRes.text(); + const res = new NextResponse(resBody, { + status: apiRes.status, + headers: { + "Content-Type": "application/json", + }, + }); + + const setCookie = apiRes.headers.getSetCookie?.() || []; + if (setCookie.length > 0) { + res.headers.set("Set-Cookie", setCookie.join(",")); + } + + return res; +} diff --git a/apps/web/src/app/api/(proxy)/app/info/route.ts b/apps/web/src/app/api/(proxy)/app/info/route.ts new file mode 100644 index 0000000..c443cd5 --- /dev/null +++ b/apps/web/src/app/api/(proxy)/app/info/route.ts @@ -0,0 +1,28 @@ +import { NextRequest, NextResponse } from "next/server"; + +export async function GET(req: NextRequest) { + const cookieHeader = req.headers.get("cookie"); + + const apiRes = await fetch(`${process.env.API_BASE_URL}/app/info`, { + method: "GET", + headers: { + cookie: cookieHeader || "", + }, + redirect: "manual", + }); + + const resBody = await apiRes.text(); + const res = new NextResponse(resBody, { + status: apiRes.status, + headers: { + "Content-Type": "application/json", + }, + }); + + const setCookie = apiRes.headers.getSetCookie?.() || []; + if (setCookie.length > 0) { + res.headers.set("Set-Cookie", setCookie.join(",")); + } + + return res; +} diff --git a/apps/web/src/app/api/(proxy)/app/remove-logo/route.ts b/apps/web/src/app/api/(proxy)/app/remove-logo/route.ts new file mode 100644 index 0000000..e1a7172 --- /dev/null +++ b/apps/web/src/app/api/(proxy)/app/remove-logo/route.ts @@ -0,0 +1,28 @@ +import { NextRequest, NextResponse } from "next/server"; + +export async function DELETE(req: NextRequest) { + const cookieHeader = req.headers.get("cookie"); + + const apiRes = await fetch(`${process.env.API_BASE_URL}/app/logo`, { + method: "DELETE", + headers: { + cookie: cookieHeader || "", + }, + redirect: "manual", + }); + + const resBody = await apiRes.text(); + const res = new NextResponse(resBody, { + status: apiRes.status, + headers: { + "Content-Type": "application/json", + }, + }); + + const setCookie = apiRes.headers.getSetCookie?.() || []; + if (setCookie.length > 0) { + res.headers.set("Set-Cookie", setCookie.join(",")); + } + + return res; +} diff --git a/apps/web/src/app/api/(proxy)/app/upload-logo/route.ts b/apps/web/src/app/api/(proxy)/app/upload-logo/route.ts new file mode 100644 index 0000000..284ba95 --- /dev/null +++ b/apps/web/src/app/api/(proxy)/app/upload-logo/route.ts @@ -0,0 +1,29 @@ +import { NextRequest, NextResponse } from "next/server"; + +export async function POST(req: NextRequest) { + const cookieHeader = req.headers.get("cookie"); + const formData = await req.formData(); + + const apiRes = await fetch(`${process.env.API_BASE_URL}/app/logo`, { + method: "POST", + headers: { + cookie: cookieHeader || "", + }, + body: formData, + }); + + const resBody = await apiRes.text(); + const res = new NextResponse(resBody, { + status: apiRes.status, + headers: { + "Content-Type": "application/json", + }, + }); + + const setCookie = apiRes.headers.getSetCookie?.() || []; + if (setCookie.length > 0) { + res.headers.set("Set-Cookie", setCookie.join(",")); + } + + return res; +} diff --git a/apps/web/src/app/api/(proxy)/auth/forgot-password/route.ts b/apps/web/src/app/api/(proxy)/auth/forgot-password/route.ts new file mode 100644 index 0000000..38eeaef --- /dev/null +++ b/apps/web/src/app/api/(proxy)/auth/forgot-password/route.ts @@ -0,0 +1,28 @@ +import { NextRequest, NextResponse } from "next/server"; + +export async function POST(req: NextRequest) { + const body = await req.text(); + + const apiRes = await fetch(`${process.env.API_BASE_URL}/auth/forgot-password`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body, + }); + + const resBody = await apiRes.text(); + const res = new NextResponse(resBody, { + status: apiRes.status, + headers: { + "Content-Type": "application/json", + }, + }); + + const setCookie = apiRes.headers.getSetCookie?.() || []; + if (setCookie.length > 0) { + res.headers.set("Set-Cookie", setCookie.join(",")); + } + + return res; +} diff --git a/apps/web/src/app/api/(proxy)/auth/login/route.ts b/apps/web/src/app/api/(proxy)/auth/login/route.ts new file mode 100644 index 0000000..99ee519 --- /dev/null +++ b/apps/web/src/app/api/(proxy)/auth/login/route.ts @@ -0,0 +1,29 @@ +import { NextRequest, NextResponse } from "next/server"; + +export async function POST(req: NextRequest) { + const body = await req.text(); + + const apiRes = await fetch(`${process.env.API_BASE_URL}/auth/login`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body, + redirect: "manual", + }); + + const resBody = await apiRes.text(); + const res = new NextResponse(resBody, { + status: apiRes.status, + headers: { + "Content-Type": "application/json", + }, + }); + + const setCookie = apiRes.headers.getSetCookie?.() || []; + if (setCookie.length > 0) { + res.headers.set("Set-Cookie", setCookie.join(",")); + } + + return res; +} diff --git a/apps/web/src/app/api/(proxy)/auth/logout/route.ts b/apps/web/src/app/api/(proxy)/auth/logout/route.ts new file mode 100644 index 0000000..bdffe0a --- /dev/null +++ b/apps/web/src/app/api/(proxy)/auth/logout/route.ts @@ -0,0 +1,28 @@ +import { NextRequest, NextResponse } from "next/server"; + +export async function POST(req: NextRequest) { + const cookieHeader = req.headers.get("cookie"); + + const apiRes = await fetch(`${process.env.API_BASE_URL}/auth/logout`, { + method: "POST", + headers: { + cookie: cookieHeader || "", + }, + redirect: "manual", + }); + + const resBody = await apiRes.text(); + const res = new NextResponse(resBody, { + status: apiRes.status, + headers: { + "Content-Type": "application/json", + }, + }); + + const setCookie = apiRes.headers.getSetCookie?.() || []; + if (setCookie.length > 0) { + res.headers.set("Set-Cookie", setCookie.join(",")); + } + + return res; +} diff --git a/apps/web/src/app/api/(proxy)/auth/me/route.ts b/apps/web/src/app/api/(proxy)/auth/me/route.ts new file mode 100644 index 0000000..424545d --- /dev/null +++ b/apps/web/src/app/api/(proxy)/auth/me/route.ts @@ -0,0 +1,28 @@ +import { NextRequest, NextResponse } from "next/server"; + +export async function GET(req: NextRequest) { + const cookieHeader = req.headers.get("cookie"); + + const apiRes = await fetch(`${process.env.API_BASE_URL}/auth/me`, { + method: "GET", + headers: { + cookie: cookieHeader || "", + }, + redirect: "manual", + }); + + const resBody = await apiRes.text(); + const res = new NextResponse(resBody, { + status: apiRes.status, + headers: { + "Content-Type": "application/json", + }, + }); + + const setCookie = apiRes.headers.getSetCookie?.() || []; + if (setCookie.length > 0) { + res.headers.set("Set-Cookie", setCookie.join(",")); + } + + return res; +} diff --git a/apps/web/src/app/api/(proxy)/auth/reset-password/route.ts b/apps/web/src/app/api/(proxy)/auth/reset-password/route.ts new file mode 100644 index 0000000..3d704ac --- /dev/null +++ b/apps/web/src/app/api/(proxy)/auth/reset-password/route.ts @@ -0,0 +1,28 @@ +import { NextRequest, NextResponse } from "next/server"; + +export async function POST(req: NextRequest) { + const body = await req.text(); + + const apiRes = await fetch(`${process.env.API_BASE_URL}/auth/reset-password`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body, + }); + + const resBody = await apiRes.text(); + const res = new NextResponse(resBody, { + status: apiRes.status, + headers: { + "Content-Type": "application/json", + }, + }); + + const setCookie = apiRes.headers.getSetCookie?.() || []; + if (setCookie.length > 0) { + res.headers.set("Set-Cookie", setCookie.join(",")); + } + + return res; +} diff --git a/apps/web/src/app/api/(proxy)/config/list/route.ts b/apps/web/src/app/api/(proxy)/config/list/route.ts new file mode 100644 index 0000000..7f0cbb2 --- /dev/null +++ b/apps/web/src/app/api/(proxy)/config/list/route.ts @@ -0,0 +1,28 @@ +import { NextRequest, NextResponse } from "next/server"; + +export async function GET(req: NextRequest) { + const cookieHeader = req.headers.get("cookie"); + + const apiRes = await fetch(`${process.env.API_BASE_URL}/app/configs`, { + method: "GET", + headers: { + cookie: cookieHeader || "", + }, + redirect: "manual", + }); + + const resBody = await apiRes.text(); + const res = new NextResponse(resBody, { + status: apiRes.status, + headers: { + "Content-Type": "application/json", + }, + }); + + const setCookie = apiRes.headers.getSetCookie?.() || []; + if (setCookie.length > 0) { + res.headers.set("Set-Cookie", setCookie.join(",")); + } + + return res; +} diff --git a/apps/web/src/app/api/(proxy)/config/update/[key]/route.ts b/apps/web/src/app/api/(proxy)/config/update/[key]/route.ts new file mode 100644 index 0000000..bfa10d5 --- /dev/null +++ b/apps/web/src/app/api/(proxy)/config/update/[key]/route.ts @@ -0,0 +1,33 @@ +import { NextRequest, NextResponse } from "next/server"; + +export async function PATCH(req: NextRequest, { params }: { params: { key: string } }) { + const { key } = params; + const body = await req.text(); + const cookieHeader = req.headers.get("cookie"); + + const apiRes = await fetch(`${process.env.API_BASE_URL}/app/configs/${key}`, { + method: "PATCH", + headers: { + "Content-Type": "application/json", + cookie: cookieHeader || "", + }, + body, + redirect: "manual", + }); + + const resBody = await apiRes.text(); + + const res = new NextResponse(resBody, { + status: apiRes.status, + headers: { + "Content-Type": "application/json", + }, + }); + + const setCookie = apiRes.headers.getSetCookie?.() || []; + if (setCookie.length > 0) { + res.headers.set("Set-Cookie", setCookie.join(",")); + } + + return res; +} diff --git a/apps/web/src/app/api/(proxy)/config/update/bulk/route.ts b/apps/web/src/app/api/(proxy)/config/update/bulk/route.ts new file mode 100644 index 0000000..294f8c7 --- /dev/null +++ b/apps/web/src/app/api/(proxy)/config/update/bulk/route.ts @@ -0,0 +1,32 @@ +import { NextRequest, NextResponse } from "next/server"; + +export async function PATCH(req: NextRequest) { + const body = await req.text(); + const cookieHeader = req.headers.get("cookie"); + + const apiRes = await fetch(`${process.env.API_BASE_URL}/app/configs`, { + method: "PATCH", + headers: { + "Content-Type": "application/json", + cookie: cookieHeader || "", + }, + body, + redirect: "manual", + }); + + const resBody = await apiRes.text(); + + const res = new NextResponse(resBody, { + status: apiRes.status, + headers: { + "Content-Type": "application/json", + }, + }); + + const setCookie = apiRes.headers.getSetCookie?.() || []; + if (setCookie.length > 0) { + res.headers.set("Set-Cookie", setCookie.join(",")); + } + + return res; +} diff --git a/apps/web/src/app/api/(proxy)/files/(download)/[objectName]/download/route.ts b/apps/web/src/app/api/(proxy)/files/(download)/[objectName]/download/route.ts new file mode 100644 index 0000000..c3f4f62 --- /dev/null +++ b/apps/web/src/app/api/(proxy)/files/(download)/[objectName]/download/route.ts @@ -0,0 +1,33 @@ +import { NextRequest, NextResponse } from "next/server"; + +export async function GET(req: NextRequest, { params }: { params: { objectName: string } }) { + // Await params before destructuring + const { objectName } = await params; + const cookieHeader = req.headers.get("cookie"); + + const url = `${process.env.API_BASE_URL}/files/${encodeURIComponent(objectName)}/download`; + + const apiRes = await fetch(url, { + method: "GET", + headers: { + cookie: cookieHeader || "", + }, + redirect: "manual", + }); + + const resBody = await apiRes.text(); + + const res = new NextResponse(resBody, { + status: apiRes.status, + headers: { + "Content-Type": "application/json", + }, + }); + + const setCookie = apiRes.headers.getSetCookie?.() || []; + if (setCookie.length > 0) { + res.headers.set("Set-Cookie", setCookie.join(",")); + } + + return res; +} diff --git a/apps/web/src/app/api/(proxy)/files/delete/[id]/route.ts b/apps/web/src/app/api/(proxy)/files/delete/[id]/route.ts new file mode 100644 index 0000000..240c12c --- /dev/null +++ b/apps/web/src/app/api/(proxy)/files/delete/[id]/route.ts @@ -0,0 +1,30 @@ +import { NextRequest, NextResponse } from "next/server"; + +export async function DELETE(req: NextRequest, { params }: { params: { id: string } }) { + const { id } = params; + const cookieHeader = req.headers.get("cookie"); + + const apiRes = await fetch(`${process.env.API_BASE_URL}/files/${encodeURIComponent(id)}`, { + method: "DELETE", + headers: { + cookie: cookieHeader || "", + }, + redirect: "manual", + }); + + const resBody = await apiRes.text(); + + const res = new NextResponse(resBody, { + status: apiRes.status, + headers: { + "Content-Type": "application/json", + }, + }); + + const setCookie = apiRes.headers.getSetCookie?.() || []; + if (setCookie.length > 0) { + res.headers.set("Set-Cookie", setCookie.join(",")); + } + + return res; +} diff --git a/apps/web/src/app/api/(proxy)/files/generate-presigned-url/route.ts b/apps/web/src/app/api/(proxy)/files/generate-presigned-url/route.ts new file mode 100644 index 0000000..8aeadfc --- /dev/null +++ b/apps/web/src/app/api/(proxy)/files/generate-presigned-url/route.ts @@ -0,0 +1,31 @@ +import { NextRequest, NextResponse } from "next/server"; + +export async function GET(req: NextRequest) { + const cookieHeader = req.headers.get("cookie"); + const searchParams = req.nextUrl.searchParams.toString(); + const url = `${process.env.API_BASE_URL}/files/presigned-url${searchParams ? `?${searchParams}` : ""}`; + + const apiRes = await fetch(url, { + method: "GET", + headers: { + cookie: cookieHeader || "", + }, + redirect: "manual", + }); + + const resBody = await apiRes.text(); + + const res = new NextResponse(resBody, { + status: apiRes.status, + headers: { + "Content-Type": "application/json", + }, + }); + + const setCookie = apiRes.headers.getSetCookie?.() || []; + if (setCookie.length > 0) { + res.headers.set("Set-Cookie", setCookie.join(",")); + } + + return res; +} diff --git a/apps/web/src/app/api/(proxy)/files/list/route.ts b/apps/web/src/app/api/(proxy)/files/list/route.ts new file mode 100644 index 0000000..4c08b7a --- /dev/null +++ b/apps/web/src/app/api/(proxy)/files/list/route.ts @@ -0,0 +1,28 @@ +import { NextRequest, NextResponse } from "next/server"; + +export async function GET(req: NextRequest) { + const cookieHeader = req.headers.get("cookie"); + + const apiRes = await fetch(`${process.env.API_BASE_URL}/files`, { + method: "GET", + headers: { + cookie: cookieHeader || "", + }, + redirect: "manual", + }); + + const resBody = await apiRes.text(); + const res = new NextResponse(resBody, { + status: apiRes.status, + headers: { + "Content-Type": "application/json", + }, + }); + + const setCookie = apiRes.headers.getSetCookie?.() || []; + if (setCookie.length > 0) { + res.headers.set("Set-Cookie", setCookie.join(",")); + } + + return res; +} diff --git a/apps/web/src/app/api/(proxy)/files/register/route.ts b/apps/web/src/app/api/(proxy)/files/register/route.ts new file mode 100644 index 0000000..c71ad2d --- /dev/null +++ b/apps/web/src/app/api/(proxy)/files/register/route.ts @@ -0,0 +1,32 @@ +import { NextRequest, NextResponse } from "next/server"; + +export async function POST(req: NextRequest) { + const body = await req.text(); + const cookieHeader = req.headers.get("cookie"); + + const apiRes = await fetch(`${process.env.API_BASE_URL}/files`, { + method: "POST", + headers: { + "Content-Type": "application/json", + cookie: cookieHeader || "", + }, + body, + redirect: "manual", + }); + + const resBody = await apiRes.text(); + + const res = new NextResponse(resBody, { + status: apiRes.status, + headers: { + "Content-Type": "application/json", + }, + }); + + const setCookie = apiRes.headers.getSetCookie?.() || []; + if (setCookie.length > 0) { + res.headers.set("Set-Cookie", setCookie.join(",")); + } + + return res; +} diff --git a/apps/web/src/app/api/(proxy)/files/update/[id]/route.ts b/apps/web/src/app/api/(proxy)/files/update/[id]/route.ts new file mode 100644 index 0000000..7baeb28 --- /dev/null +++ b/apps/web/src/app/api/(proxy)/files/update/[id]/route.ts @@ -0,0 +1,33 @@ +import { NextRequest, NextResponse } from "next/server"; + +export async function PATCH(req: NextRequest, { params }: { params: { id: string } }) { + const { id } = params; + const body = await req.text(); + const cookieHeader = req.headers.get("cookie"); + + const apiRes = await fetch(`${process.env.API_BASE_URL}/files/${encodeURIComponent(id)}`, { + method: "PATCH", + headers: { + "Content-Type": "application/json", + cookie: cookieHeader || "", + }, + body, + redirect: "manual", + }); + + const resBody = await apiRes.text(); + + const res = new NextResponse(resBody, { + status: apiRes.status, + headers: { + "Content-Type": "application/json", + }, + }); + + const setCookie = apiRes.headers.getSetCookie?.() || []; + if (setCookie.length > 0) { + res.headers.set("Set-Cookie", setCookie.join(",")); + } + + return res; +} diff --git a/apps/web/src/app/api/(proxy)/shares/alias/create/[shareId]/route.ts b/apps/web/src/app/api/(proxy)/shares/alias/create/[shareId]/route.ts new file mode 100644 index 0000000..19ef52b --- /dev/null +++ b/apps/web/src/app/api/(proxy)/shares/alias/create/[shareId]/route.ts @@ -0,0 +1,32 @@ +import { NextRequest, NextResponse } from "next/server"; + +export async function POST(req: NextRequest, { params }: { params: { shareId: string } }) { + const body = await req.text(); + const cookieHeader = req.headers.get("cookie"); + + const apiRes = await fetch(`${process.env.API_BASE_URL}/shares/${params.shareId}/alias`, { + method: "POST", + headers: { + "Content-Type": "application/json", + cookie: cookieHeader || "", + }, + body, + redirect: "manual", + }); + + const resBody = await apiRes.text(); + + const res = new NextResponse(resBody, { + status: apiRes.status, + headers: { + "Content-Type": "application/json", + }, + }); + + const setCookie = apiRes.headers.getSetCookie?.() || []; + if (setCookie.length > 0) { + res.headers.set("Set-Cookie", setCookie.join(",")); + } + + return res; +} diff --git a/apps/web/src/app/api/(proxy)/shares/alias/get/[alias]/route.ts b/apps/web/src/app/api/(proxy)/shares/alias/get/[alias]/route.ts new file mode 100644 index 0000000..4e45063 --- /dev/null +++ b/apps/web/src/app/api/(proxy)/shares/alias/get/[alias]/route.ts @@ -0,0 +1,32 @@ +import { NextRequest, NextResponse } from "next/server"; + +export async function GET(req: NextRequest, { params }: { params: { alias: string } }) { + const cookieHeader = req.headers.get("cookie"); + const queryParams = new URLSearchParams(req.url.split("?")[1]) || undefined; + + const apiRes = await fetch(`${process.env.API_BASE_URL}/shares/alias/${params.alias}`, { + method: "GET", + headers: { + "Content-Type": "application/json", + cookie: cookieHeader || "", + }, + redirect: "manual", + ...(queryParams ? { params: queryParams } : {}), + }); + + const resBody = await apiRes.text(); + + const res = new NextResponse(resBody, { + status: apiRes.status, + headers: { + "Content-Type": "application/json", + }, + }); + + const setCookie = apiRes.headers.getSetCookie?.() || []; + if (setCookie.length > 0) { + res.headers.set("Set-Cookie", setCookie.join(",")); + } + + return res; +} diff --git a/apps/web/src/app/api/(proxy)/shares/create/route.ts b/apps/web/src/app/api/(proxy)/shares/create/route.ts new file mode 100644 index 0000000..1575733 --- /dev/null +++ b/apps/web/src/app/api/(proxy)/shares/create/route.ts @@ -0,0 +1,32 @@ +import { NextRequest, NextResponse } from "next/server"; + +export async function POST(req: NextRequest) { + const cookieHeader = req.headers.get("cookie"); + const body = await req.text(); + + const apiRes = await fetch(`${process.env.API_BASE_URL}/shares`, { + method: "POST", + headers: { + "Content-Type": "application/json", + cookie: cookieHeader || "", + }, + body, + redirect: "manual", + }); + + const resBody = await apiRes.text(); + + const res = new NextResponse(resBody, { + status: apiRes.status, + headers: { + "Content-Type": "application/json", + }, + }); + + const setCookie = apiRes.headers.getSetCookie?.() || []; + if (setCookie.length > 0) { + res.headers.set("Set-Cookie", setCookie.join(",")); + } + + return res; +} diff --git a/apps/web/src/app/api/(proxy)/shares/delete/[id]/route.ts b/apps/web/src/app/api/(proxy)/shares/delete/[id]/route.ts new file mode 100644 index 0000000..50e87c4 --- /dev/null +++ b/apps/web/src/app/api/(proxy)/shares/delete/[id]/route.ts @@ -0,0 +1,29 @@ +import { NextRequest, NextResponse } from "next/server"; + +export async function DELETE(req: NextRequest, { params }: { params: { id: string } }) { + const cookieHeader = req.headers.get("cookie"); + + const apiRes = await fetch(`${process.env.API_BASE_URL}/shares/${params.id}`, { + method: "DELETE", + headers: { + cookie: cookieHeader || "", + }, + redirect: "manual", + }); + + const resBody = await apiRes.text(); + + const res = new NextResponse(resBody, { + status: apiRes.status, + headers: { + "Content-Type": "application/json", + }, + }); + + const setCookie = apiRes.headers.getSetCookie?.() || []; + if (setCookie.length > 0) { + res.headers.set("Set-Cookie", setCookie.join(",")); + } + + return res; +} diff --git a/apps/web/src/app/api/(proxy)/shares/details/[shareId]/route.ts b/apps/web/src/app/api/(proxy)/shares/details/[shareId]/route.ts new file mode 100644 index 0000000..3b4a62b --- /dev/null +++ b/apps/web/src/app/api/(proxy)/shares/details/[shareId]/route.ts @@ -0,0 +1,34 @@ +import { NextRequest, NextResponse } from "next/server"; + +export async function GET(req: NextRequest, { params }: { params: { shareId: string } }) { + const cookieHeader = req.headers.get("cookie"); + const url = new URL(req.url); + const searchParams = url.searchParams.toString(); + + const apiRes = await fetch( + `${process.env.API_BASE_URL}/shares/${params.shareId}${searchParams ? `?${searchParams}` : ""}`, + { + method: "GET", + headers: { + cookie: cookieHeader || "", + }, + redirect: "manual", + } + ); + + const resBody = await apiRes.text(); + + const res = new NextResponse(resBody, { + status: apiRes.status, + headers: { + "Content-Type": "application/json", + }, + }); + + const setCookie = apiRes.headers.getSetCookie?.() || []; + if (setCookie.length > 0) { + res.headers.set("Set-Cookie", setCookie.join(",")); + } + + return res; +} diff --git a/apps/web/src/app/api/(proxy)/shares/files/add/[shareId]/route.ts b/apps/web/src/app/api/(proxy)/shares/files/add/[shareId]/route.ts new file mode 100644 index 0000000..3993705 --- /dev/null +++ b/apps/web/src/app/api/(proxy)/shares/files/add/[shareId]/route.ts @@ -0,0 +1,32 @@ +import { NextRequest, NextResponse } from "next/server"; + +export async function POST(req: NextRequest, { params }: { params: { shareId: string } }) { + const body = await req.text(); + const cookieHeader = req.headers.get("cookie"); + + const apiRes = await fetch(`${process.env.API_BASE_URL}/shares/${params.shareId}/files`, { + method: "POST", + headers: { + "Content-Type": "application/json", + cookie: cookieHeader || "", + }, + body, + redirect: "manual", + }); + + const resBody = await apiRes.text(); + + const res = new NextResponse(resBody, { + status: apiRes.status, + headers: { + "Content-Type": "application/json", + }, + }); + + const setCookie = apiRes.headers.getSetCookie?.() || []; + if (setCookie.length > 0) { + res.headers.set("Set-Cookie", setCookie.join(",")); + } + + return res; +} diff --git a/apps/web/src/app/api/(proxy)/shares/files/remove/[shareId]/route.ts b/apps/web/src/app/api/(proxy)/shares/files/remove/[shareId]/route.ts new file mode 100644 index 0000000..d5516fc --- /dev/null +++ b/apps/web/src/app/api/(proxy)/shares/files/remove/[shareId]/route.ts @@ -0,0 +1,32 @@ +import { NextRequest, NextResponse } from "next/server"; + +export async function DELETE(req: NextRequest, { params }: { params: { shareId: string } }) { + const body = await req.text(); + const cookieHeader = req.headers.get("cookie"); + + const apiRes = await fetch(`${process.env.API_BASE_URL}/shares/${params.shareId}/files`, { + method: "DELETE", + headers: { + "Content-Type": "application/json", + cookie: cookieHeader || "", + }, + body, + redirect: "manual", + }); + + const resBody = await apiRes.text(); + + const res = new NextResponse(resBody, { + status: apiRes.status, + headers: { + "Content-Type": "application/json", + }, + }); + + const setCookie = apiRes.headers.getSetCookie?.() || []; + if (setCookie.length > 0) { + res.headers.set("Set-Cookie", setCookie.join(",")); + } + + return res; +} diff --git a/apps/web/src/app/api/(proxy)/shares/list/route.ts b/apps/web/src/app/api/(proxy)/shares/list/route.ts new file mode 100644 index 0000000..4a67118 --- /dev/null +++ b/apps/web/src/app/api/(proxy)/shares/list/route.ts @@ -0,0 +1,29 @@ +import { NextRequest, NextResponse } from "next/server"; + +export async function GET(req: NextRequest) { + const cookieHeader = req.headers.get("cookie"); + + const apiRes = await fetch(`${process.env.API_BASE_URL}/shares/me`, { + method: "GET", + headers: { + cookie: cookieHeader || "", + }, + redirect: "manual", + }); + + const resBody = await apiRes.text(); + + const res = new NextResponse(resBody, { + status: apiRes.status, + headers: { + "Content-Type": "application/json", + }, + }); + + const setCookie = apiRes.headers.getSetCookie?.() || []; + if (setCookie.length > 0) { + res.headers.set("Set-Cookie", setCookie.join(",")); + } + + return res; +} diff --git a/apps/web/src/app/api/(proxy)/shares/password/update/shareId/route.ts b/apps/web/src/app/api/(proxy)/shares/password/update/shareId/route.ts new file mode 100644 index 0000000..636c5d3 --- /dev/null +++ b/apps/web/src/app/api/(proxy)/shares/password/update/shareId/route.ts @@ -0,0 +1,32 @@ +import { NextRequest, NextResponse } from "next/server"; + +export async function PATCH(req: NextRequest, { params }: { params: { shareId: string } }) { + const body = await req.text(); + const cookieHeader = req.headers.get("cookie"); + + const apiRes = await fetch(`${process.env.API_BASE_URL}/shares/${params.shareId}/password`, { + method: "PATCH", + headers: { + "Content-Type": "application/json", + cookie: cookieHeader || "", + }, + body, + redirect: "manual", + }); + + const resBody = await apiRes.text(); + + const res = new NextResponse(resBody, { + status: apiRes.status, + headers: { + "Content-Type": "application/json", + }, + }); + + const setCookie = apiRes.headers.getSetCookie?.() || []; + if (setCookie.length > 0) { + res.headers.set("Set-Cookie", setCookie.join(",")); + } + + return res; +} diff --git a/apps/web/src/app/api/(proxy)/shares/recipients/add/[shareId]/route.ts b/apps/web/src/app/api/(proxy)/shares/recipients/add/[shareId]/route.ts new file mode 100644 index 0000000..a8a4ea4 --- /dev/null +++ b/apps/web/src/app/api/(proxy)/shares/recipients/add/[shareId]/route.ts @@ -0,0 +1,32 @@ +import { NextRequest, NextResponse } from "next/server"; + +export async function POST(req: NextRequest, { params }: { params: { shareId: string } }) { + const body = await req.text(); + const cookieHeader = req.headers.get("cookie"); + + const apiRes = await fetch(`${process.env.API_BASE_URL}/shares/${params.shareId}/recipients`, { + method: "POST", + headers: { + "Content-Type": "application/json", + cookie: cookieHeader || "", + }, + body, + redirect: "manual", + }); + + const resBody = await apiRes.text(); + + const res = new NextResponse(resBody, { + status: apiRes.status, + headers: { + "Content-Type": "application/json", + }, + }); + + const setCookie = apiRes.headers.getSetCookie?.() || []; + if (setCookie.length > 0) { + res.headers.set("Set-Cookie", setCookie.join(",")); + } + + return res; +} diff --git a/apps/web/src/app/api/(proxy)/shares/recipients/notify/[shareId]/route.ts b/apps/web/src/app/api/(proxy)/shares/recipients/notify/[shareId]/route.ts new file mode 100644 index 0000000..104fd0f --- /dev/null +++ b/apps/web/src/app/api/(proxy)/shares/recipients/notify/[shareId]/route.ts @@ -0,0 +1,32 @@ +import { NextRequest, NextResponse } from "next/server"; + +export async function POST(req: NextRequest, { params }: { params: { shareId: string } }) { + const body = await req.text(); + const cookieHeader = req.headers.get("cookie"); + + const apiRes = await fetch(`${process.env.API_BASE_URL}/shares/${params.shareId}/notify`, { + method: "POST", + headers: { + "Content-Type": "application/json", + cookie: cookieHeader || "", + }, + body, + redirect: "manual", + }); + + const resBody = await apiRes.text(); + + const res = new NextResponse(resBody, { + status: apiRes.status, + headers: { + "Content-Type": "application/json", + }, + }); + + const setCookie = apiRes.headers.getSetCookie?.() || []; + if (setCookie.length > 0) { + res.headers.set("Set-Cookie", setCookie.join(",")); + } + + return res; +} diff --git a/apps/web/src/app/api/(proxy)/shares/recipients/remove/[shareId]/route.ts b/apps/web/src/app/api/(proxy)/shares/recipients/remove/[shareId]/route.ts new file mode 100644 index 0000000..83c2e77 --- /dev/null +++ b/apps/web/src/app/api/(proxy)/shares/recipients/remove/[shareId]/route.ts @@ -0,0 +1,32 @@ +import { NextRequest, NextResponse } from "next/server"; + +export async function DELETE(req: NextRequest, { params }: { params: { shareId: string } }) { + const body = await req.text(); + const cookieHeader = req.headers.get("cookie"); + + const apiRes = await fetch(`${process.env.API_BASE_URL}/shares/${params.shareId}/recipients`, { + method: "DELETE", + headers: { + "Content-Type": "application/json", + cookie: cookieHeader || "", + }, + body, + redirect: "manual", + }); + + const resBody = await apiRes.text(); + + const res = new NextResponse(resBody, { + status: apiRes.status, + headers: { + "Content-Type": "application/json", + }, + }); + + const setCookie = apiRes.headers.getSetCookie?.() || []; + if (setCookie.length > 0) { + res.headers.set("Set-Cookie", setCookie.join(",")); + } + + return res; +} diff --git a/apps/web/src/app/api/(proxy)/shares/update/route.ts b/apps/web/src/app/api/(proxy)/shares/update/route.ts new file mode 100644 index 0000000..691a60c --- /dev/null +++ b/apps/web/src/app/api/(proxy)/shares/update/route.ts @@ -0,0 +1,32 @@ +import { NextRequest, NextResponse } from "next/server"; + +export async function PUT(req: NextRequest) { + const cookieHeader = req.headers.get("cookie"); + const body = await req.text(); + + const apiRes = await fetch(`${process.env.API_BASE_URL}/shares`, { + method: "PUT", + headers: { + "Content-Type": "application/json", + cookie: cookieHeader || "", + }, + body, + redirect: "manual", + }); + + const resBody = await apiRes.text(); + + const res = new NextResponse(resBody, { + status: apiRes.status, + headers: { + "Content-Type": "application/json", + }, + }); + + const setCookie = apiRes.headers.getSetCookie?.() || []; + if (setCookie.length > 0) { + res.headers.set("Set-Cookie", setCookie.join(",")); + } + + return res; +} diff --git a/apps/web/src/app/api/(proxy)/users/activate/[id]/route.ts b/apps/web/src/app/api/(proxy)/users/activate/[id]/route.ts new file mode 100644 index 0000000..8bdce2f --- /dev/null +++ b/apps/web/src/app/api/(proxy)/users/activate/[id]/route.ts @@ -0,0 +1,29 @@ +import { NextRequest, NextResponse } from "next/server"; + +export async function PATCH(req: NextRequest, { params }: { params: { id: string } }) { + const cookieHeader = req.headers.get("cookie"); + + const apiRes = await fetch(`${process.env.API_BASE_URL}/users/${params.id}/activate`, { + method: "PATCH", + headers: { + cookie: cookieHeader || "", + }, + redirect: "manual", + }); + + const resBody = await apiRes.text(); + + const res = new NextResponse(resBody, { + status: apiRes.status, + headers: { + "Content-Type": "application/json", + }, + }); + + const setCookie = apiRes.headers.getSetCookie?.() || []; + if (setCookie.length > 0) { + res.headers.set("Set-Cookie", setCookie.join(",")); + } + + return res; +} diff --git a/apps/web/src/app/api/(proxy)/users/avatar/remove/route.ts b/apps/web/src/app/api/(proxy)/users/avatar/remove/route.ts new file mode 100644 index 0000000..0b240bf --- /dev/null +++ b/apps/web/src/app/api/(proxy)/users/avatar/remove/route.ts @@ -0,0 +1,29 @@ +import { NextRequest, NextResponse } from "next/server"; + +export async function DELETE(req: NextRequest) { + const cookieHeader = req.headers.get("cookie"); + + const apiRes = await fetch(`${process.env.API_BASE_URL}/users/avatar`, { + method: "DELETE", + headers: { + cookie: cookieHeader || "", + }, + redirect: "manual", + }); + + const resBody = await apiRes.text(); + + const res = new NextResponse(resBody, { + status: apiRes.status, + headers: { + "Content-Type": "application/json", + }, + }); + + const setCookie = apiRes.headers.getSetCookie?.() || []; + if (setCookie.length > 0) { + res.headers.set("Set-Cookie", setCookie.join(",")); + } + + return res; +} diff --git a/apps/web/src/app/api/(proxy)/users/avatar/upload/route.ts b/apps/web/src/app/api/(proxy)/users/avatar/upload/route.ts new file mode 100644 index 0000000..fadbbb4 --- /dev/null +++ b/apps/web/src/app/api/(proxy)/users/avatar/upload/route.ts @@ -0,0 +1,29 @@ +import { NextRequest, NextResponse } from "next/server"; + +export async function POST(req: NextRequest) { + const cookieHeader = req.headers.get("cookie"); + const formData = await req.formData(); + + const apiRes = await fetch(`${process.env.API_BASE_URL}/users/avatar`, { + method: "POST", + headers: { + cookie: cookieHeader || "", + }, + body: formData, + }); + + const resBody = await apiRes.text(); + const res = new NextResponse(resBody, { + status: apiRes.status, + headers: { + "Content-Type": "application/json", + }, + }); + + const setCookie = apiRes.headers.getSetCookie?.() || []; + if (setCookie.length > 0) { + res.headers.set("Set-Cookie", setCookie.join(",")); + } + + return res; +} diff --git a/apps/web/src/app/api/(proxy)/users/deactivate/[id]/route.ts b/apps/web/src/app/api/(proxy)/users/deactivate/[id]/route.ts new file mode 100644 index 0000000..b00bcd0 --- /dev/null +++ b/apps/web/src/app/api/(proxy)/users/deactivate/[id]/route.ts @@ -0,0 +1,29 @@ +import { NextRequest, NextResponse } from "next/server"; + +export async function PATCH(req: NextRequest, { params }: { params: { id: string } }) { + const cookieHeader = req.headers.get("cookie"); + + const apiRes = await fetch(`${process.env.API_BASE_URL}/users/${params.id}/deactivate`, { + method: "PATCH", + headers: { + cookie: cookieHeader || "", + }, + redirect: "manual", + }); + + const resBody = await apiRes.text(); + + const res = new NextResponse(resBody, { + status: apiRes.status, + headers: { + "Content-Type": "application/json", + }, + }); + + const setCookie = apiRes.headers.getSetCookie?.() || []; + if (setCookie.length > 0) { + res.headers.set("Set-Cookie", setCookie.join(",")); + } + + return res; +} diff --git a/apps/web/src/app/api/(proxy)/users/delete/[id]/route.ts b/apps/web/src/app/api/(proxy)/users/delete/[id]/route.ts new file mode 100644 index 0000000..ee73c45 --- /dev/null +++ b/apps/web/src/app/api/(proxy)/users/delete/[id]/route.ts @@ -0,0 +1,29 @@ +import { NextRequest, NextResponse } from "next/server"; + +export async function DELETE(req: NextRequest, { params }: { params: { id: string } }) { + const cookieHeader = req.headers.get("cookie"); + + const apiRes = await fetch(`${process.env.API_BASE_URL}/users/${params.id}`, { + method: "DELETE", + headers: { + cookie: cookieHeader || "", + }, + redirect: "manual", + }); + + const resBody = await apiRes.text(); + + const res = new NextResponse(resBody, { + status: apiRes.status, + headers: { + "Content-Type": "application/json", + }, + }); + + const setCookie = apiRes.headers.getSetCookie?.() || []; + if (setCookie.length > 0) { + res.headers.set("Set-Cookie", setCookie.join(",")); + } + + return res; +} diff --git a/apps/web/src/app/api/(proxy)/users/details/[id]/route.ts b/apps/web/src/app/api/(proxy)/users/details/[id]/route.ts new file mode 100644 index 0000000..b591bb2 --- /dev/null +++ b/apps/web/src/app/api/(proxy)/users/details/[id]/route.ts @@ -0,0 +1,32 @@ +import { NextRequest, NextResponse } from "next/server"; + +export async function GET(req: NextRequest, { params }: { params: { id: string } }) { + const cookieHeader = req.headers.get("cookie"); + const searchParams = req.nextUrl.searchParams.toString(); + + const url = `${process.env.API_BASE_URL}/users/${params.id}${searchParams ? `?${searchParams}` : ""}`; + + const apiRes = await fetch(url, { + method: "GET", + headers: { + cookie: cookieHeader || "", + }, + redirect: "manual", + }); + + const resBody = await apiRes.text(); + + const res = new NextResponse(resBody, { + status: apiRes.status, + headers: { + "Content-Type": "application/json", + }, + }); + + const setCookie = apiRes.headers.getSetCookie?.() || []; + if (setCookie.length > 0) { + res.headers.set("Set-Cookie", setCookie.join(",")); + } + + return res; +} diff --git a/apps/web/src/app/api/(proxy)/users/list/route.ts b/apps/web/src/app/api/(proxy)/users/list/route.ts new file mode 100644 index 0000000..b2d2b5f --- /dev/null +++ b/apps/web/src/app/api/(proxy)/users/list/route.ts @@ -0,0 +1,32 @@ +import { NextRequest, NextResponse } from "next/server"; + +export async function GET(req: NextRequest) { + const cookieHeader = req.headers.get("cookie"); + const searchParams = req.nextUrl.searchParams.toString(); + + const url = `${process.env.API_BASE_URL}/users${searchParams ? `?${searchParams}` : ""}`; + + const apiRes = await fetch(url, { + method: "GET", + headers: { + cookie: cookieHeader || "", + }, + redirect: "manual", + }); + + const resBody = await apiRes.text(); + + const res = new NextResponse(resBody, { + status: apiRes.status, + headers: { + "Content-Type": "application/json", + }, + }); + + const setCookie = apiRes.headers.getSetCookie?.() || []; + if (setCookie.length > 0) { + res.headers.set("Set-Cookie", setCookie.join(",")); + } + + return res; +} diff --git a/apps/web/src/app/api/(proxy)/users/register/route.ts b/apps/web/src/app/api/(proxy)/users/register/route.ts new file mode 100644 index 0000000..48d730d --- /dev/null +++ b/apps/web/src/app/api/(proxy)/users/register/route.ts @@ -0,0 +1,32 @@ +import { NextRequest, NextResponse } from "next/server"; + +export async function POST(req: NextRequest) { + const body = await req.text(); + const cookieHeader = req.headers.get("cookie"); + + const apiRes = await fetch(`${process.env.API_BASE_URL}/auth/register`, { + method: "POST", + headers: { + "Content-Type": "application/json", + cookie: cookieHeader || "", + }, + body, + redirect: "manual", + }); + + const resBody = await apiRes.text(); + + const res = new NextResponse(resBody, { + status: apiRes.status, + headers: { + "Content-Type": "application/json", + }, + }); + + const setCookie = apiRes.headers.getSetCookie?.() || []; + if (setCookie.length > 0) { + res.headers.set("Set-Cookie", setCookie.join(",")); + } + + return res; +} diff --git a/apps/web/src/app/api/(proxy)/users/update-image/[id]/route.ts b/apps/web/src/app/api/(proxy)/users/update-image/[id]/route.ts new file mode 100644 index 0000000..dab2015 --- /dev/null +++ b/apps/web/src/app/api/(proxy)/users/update-image/[id]/route.ts @@ -0,0 +1,32 @@ +import { NextRequest, NextResponse } from "next/server"; + +export async function PATCH(req: NextRequest, { params }: { params: { id: string } }) { + const cookieHeader = req.headers.get("cookie"); + const body = await req.text(); + + const apiRes = await fetch(`${process.env.API_BASE_URL}/users/${params.id}/image`, { + method: "PATCH", + headers: { + "Content-Type": "application/json", + cookie: cookieHeader || "", + }, + body, + redirect: "manual", + }); + + const resBody = await apiRes.text(); + + const res = new NextResponse(resBody, { + status: apiRes.status, + headers: { + "Content-Type": "application/json", + }, + }); + + const setCookie = apiRes.headers.getSetCookie?.() || []; + if (setCookie.length > 0) { + res.headers.set("Set-Cookie", setCookie.join(",")); + } + + return res; +} diff --git a/apps/web/src/app/api/(proxy)/users/update/route.ts b/apps/web/src/app/api/(proxy)/users/update/route.ts new file mode 100644 index 0000000..af1e9e3 --- /dev/null +++ b/apps/web/src/app/api/(proxy)/users/update/route.ts @@ -0,0 +1,32 @@ +import { NextRequest, NextResponse } from "next/server"; + +export async function PUT(req: NextRequest) { + const body = await req.text(); + const cookieHeader = req.headers.get("cookie"); + + const apiRes = await fetch(`${process.env.API_BASE_URL}/users`, { + method: "PUT", + headers: { + "Content-Type": "application/json", + cookie: cookieHeader || "", + }, + body, + redirect: "manual", + }); + + const resBody = await apiRes.text(); + + const res = new NextResponse(resBody, { + status: apiRes.status, + headers: { + "Content-Type": "application/json", + }, + }); + + const setCookie = apiRes.headers.getSetCookie?.() || []; + if (setCookie.length > 0) { + res.headers.set("Set-Cookie", setCookie.join(",")); + } + + return res; +} diff --git a/apps/web/src/app/dashboard/components/empty-file-state.tsx b/apps/web/src/app/dashboard/components/empty-file-state.tsx new file mode 100644 index 0000000..4f8d0bb --- /dev/null +++ b/apps/web/src/app/dashboard/components/empty-file-state.tsx @@ -0,0 +1,19 @@ +import { IconCloudUpload, IconFolderOpen } from "@tabler/icons-react"; +import { useTranslations } from "next-intl"; + +import { Button } from "@/components/ui/button"; + +export function EmptyFilesState({ onUpload }: { onUpload: () => void }) { + const t = useTranslations(); + + return ( +
    + +

    {t("recentFiles.noFiles")}

    + +
    + ); +} diff --git a/apps/web/src/app/dashboard/components/empty-shares-state.tsx b/apps/web/src/app/dashboard/components/empty-shares-state.tsx new file mode 100644 index 0000000..7da158e --- /dev/null +++ b/apps/web/src/app/dashboard/components/empty-shares-state.tsx @@ -0,0 +1,21 @@ +import { IconPlus, IconShare } from "@tabler/icons-react"; +import { useTranslations } from "next-intl"; + +import { Button } from "@/components/ui/button"; + +export function EmptySharesState({ onCreate }: { onCreate: () => void }) { + const t = useTranslations(); + + return ( +
    + +
    +

    {t("recentShares.noShares")}

    + +
    +
    + ); +} diff --git a/apps/web/src/pages/dashboard/components/quick-access-cards.tsx b/apps/web/src/app/dashboard/components/quick-access-cards.tsx similarity index 57% rename from apps/web/src/pages/dashboard/components/quick-access-cards.tsx rename to apps/web/src/app/dashboard/components/quick-access-cards.tsx index 6b4b32a..31dabe2 100644 --- a/apps/web/src/pages/dashboard/components/quick-access-cards.tsx +++ b/apps/web/src/app/dashboard/components/quick-access-cards.tsx @@ -1,26 +1,27 @@ -import { Card, CardBody } from "@heroui/card"; -import { useTranslation } from "react-i18next"; -import { FaFolderOpen, FaShareAlt } from "react-icons/fa"; -import { useNavigate } from "react-router-dom"; +import { useRouter } from "next/navigation"; +import { IconFoldersFilled, IconShare2 } from "@tabler/icons-react"; +import { useTranslations } from "next-intl"; + +import { Card, CardContent } from "@/components/ui/card"; export function QuickAccessCards() { - const { t } = useTranslation(); - const navigate = useNavigate(); + const t = useTranslations(); + const router = useRouter(); const QUICK_ACCESS_ITEMS = [ { title: t("quickAccess.files.title"), - icon: , + icon: , description: t("quickAccess.files.description"), path: "/files", - color: "bg-primary-500", + color: "bg-primary", }, { title: t("quickAccess.shares.title"), - icon: , + icon: , description: t("quickAccess.shares.description"), path: "/shares", - color: "bg-warning-500", + color: "bg-orange-400", }, ] as const; @@ -29,13 +30,14 @@ export function QuickAccessCards() { {QUICK_ACCESS_ITEMS.map((card) => ( navigate(card.path)} + className="cursor-pointer transform transition-all hover:scale-102" + onClick={() => router.push(card.path)} > - +
    -
    +
    {card.icon}
    @@ -43,7 +45,7 @@ export function QuickAccessCards() {

    {card.description}

    - + ))}
    diff --git a/apps/web/src/app/dashboard/components/recent-files.tsx b/apps/web/src/app/dashboard/components/recent-files.tsx new file mode 100644 index 0000000..c95c279 --- /dev/null +++ b/apps/web/src/app/dashboard/components/recent-files.tsx @@ -0,0 +1,59 @@ +import { useRouter } from "next/navigation"; +import { IconCloudUpload, IconFolderOpen } from "@tabler/icons-react"; +import { useTranslations } from "next-intl"; + +import { FilesTable } from "@/components/tables/files-table"; +import { Button } from "@/components/ui/button"; +import { Card, CardContent } from "@/components/ui/card"; +import type { RecentFilesProps } from "../types"; +import { EmptyFilesState } from "./empty-file-state"; + +export function RecentFiles({ files, fileManager, onOpenUploadModal }: RecentFilesProps) { + const t = useTranslations(); + const router = useRouter(); + + return ( + + +
    +

    + + {t("recentFiles.title")} +

    + {files.length >= 5 ? ( + + ) : files.length === 0 ? null : ( + + )} +
    + {files.length > 0 ? ( + + ) : ( + + )} +
    +
    + ); +} diff --git a/apps/web/src/pages/dashboard/components/recent-shares.tsx b/apps/web/src/app/dashboard/components/recent-shares.tsx similarity index 51% rename from apps/web/src/pages/dashboard/components/recent-shares.tsx rename to apps/web/src/app/dashboard/components/recent-shares.tsx index fb88cf2..6d27ed2 100644 --- a/apps/web/src/pages/dashboard/components/recent-shares.tsx +++ b/apps/web/src/app/dashboard/components/recent-shares.tsx @@ -1,44 +1,44 @@ -import { RecentSharesProps } from "../types"; +import { useRouter } from "next/navigation"; +import { IconPlus, IconShare } from "@tabler/icons-react"; +import { useTranslations } from "next-intl"; + import { SharesTable } from "@/components/tables/shares-table"; -import { Button } from "@heroui/button"; -import { Card, CardBody } from "@heroui/card"; -import { useTranslation } from "react-i18next"; -import { FaShareAlt, FaPlus } from "react-icons/fa"; -import { useNavigate } from "react-router-dom"; +import { Button } from "@/components/ui/button"; +import { Card, CardContent } from "@/components/ui/card"; +import { RecentSharesProps } from "../types"; +import { EmptySharesState } from "./empty-shares-state"; export function RecentShares({ shares, shareManager, onOpenCreateModal, onCopyLink }: RecentSharesProps) { - const { t } = useTranslation(); - const navigate = useNavigate(); + const t = useTranslations(); + const router = useRouter(); return ( - +

    - + {t("recentShares.title")}

    {shares.length >= 5 ? ( ) : shares.length === 0 ? null : ( )} @@ -60,23 +60,7 @@ export function RecentShares({ shares, shareManager, onOpenCreateModal, onCopyLi )}
    - + ); } - -function EmptySharesState({ onCreate }: { onCreate: () => void }) { - const { t } = useTranslation(); - - return ( -
    - -
    -

    {t("recentShares.noShares")}

    - -
    -
    - ); -} diff --git a/apps/web/src/app/dashboard/components/storage-usage.tsx b/apps/web/src/app/dashboard/components/storage-usage.tsx new file mode 100644 index 0000000..86345c0 --- /dev/null +++ b/apps/web/src/app/dashboard/components/storage-usage.tsx @@ -0,0 +1,42 @@ +import { IconDatabaseCog } from "@tabler/icons-react"; +import { useTranslations } from "next-intl"; + +import { Card, CardContent } from "@/components/ui/card"; +import { Progress } from "@/components/ui/progress"; +import type { StorageUsageProps } from "../types"; +import { formatStorageSize } from "../utils/format-storage-size"; + +export function StorageUsage({ diskSpace }: StorageUsageProps) { + const t = useTranslations(); + console.log("diskSpace:", diskSpace); + + return ( + + +
    +

    + + {t("storageUsage.title")} +

    +
    + +
    + + {" "} + {formatStorageSize(diskSpace?.diskUsedGB || 0)} {t("storageUsage.used")} + + + {" "} + {formatStorageSize(diskSpace?.diskAvailableGB || 0)} {t("storageUsage.available")} + +
    +
    +
    +
    +
    + ); +} diff --git a/apps/web/src/pages/dashboard/hooks/use-dashboard.ts b/apps/web/src/app/dashboard/hooks/use-dashboard.ts similarity index 82% rename from apps/web/src/pages/dashboard/hooks/use-dashboard.ts rename to apps/web/src/app/dashboard/hooks/use-dashboard.ts index 47f7cb1..8ad8549 100644 --- a/apps/web/src/pages/dashboard/hooks/use-dashboard.ts +++ b/apps/web/src/app/dashboard/hooks/use-dashboard.ts @@ -1,14 +1,16 @@ -import { useFileManager } from "@/hooks/use-file-manager"; -import { useShareManager } from "@/hooks/use-share-manager"; -import { getDiskSpace, listFiles, listUserShares, getAllConfigs } from "@/http/endpoints"; -import { ListUserShares200SharesItem } from "@/http/models/listUserShares200SharesItem"; -import { useDisclosure } from "@heroui/modal"; +"use client"; + import { useEffect, useState } from "react"; -import { useTranslation } from "react-i18next"; +import { useTranslations } from "next-intl"; import { toast } from "sonner"; +import { useFileManager } from "@/hooks/use-file-manager"; +import { useShareManager } from "@/hooks/use-share-manager"; +import { getAllConfigs, getDiskSpace, listFiles, listUserShares } from "@/http/endpoints"; +import { ListUserShares200SharesItem } from "@/http/models/listUserShares200SharesItem"; + export function useDashboard() { - const { t } = useTranslation(); + const t = useTranslations(); const [diskSpace, setDiskSpace] = useState<{ diskSizeGB: number; diskUsedGB: number; @@ -20,8 +22,13 @@ export function useDashboard() { const [isLoading, setIsLoading] = useState(true); const [smtpEnabled, setSmtpEnabled] = useState("false"); - const { isOpen: isUploadModalOpen, onOpen: onOpenUploadModal, onClose: onCloseUploadModal } = useDisclosure(); - const { isOpen: isCreateModalOpen, onOpen: onOpenCreateModal, onClose: onCloseCreateModal } = useDisclosure(); + const [isUploadModalOpen, setIsUploadModalOpen] = useState(false); + const [isCreateModalOpen, setIsCreateModalOpen] = useState(false); + + const onOpenUploadModal = () => setIsUploadModalOpen(true); + const onCloseUploadModal = () => setIsUploadModalOpen(false); + const onOpenCreateModal = () => setIsCreateModalOpen(true); + const onCloseCreateModal = () => setIsCreateModalOpen(false); const loadDashboardData = async () => { try { diff --git a/apps/web/src/app/dashboard/layout.tsx b/apps/web/src/app/dashboard/layout.tsx new file mode 100644 index 0000000..dd52f74 --- /dev/null +++ b/apps/web/src/app/dashboard/layout.tsx @@ -0,0 +1,18 @@ +import { Metadata } from "next"; +import { getTranslations } from "next-intl/server"; + +interface LayoutProps { + children: React.ReactNode; +} + +export async function generateMetadata(): Promise { + const t = await getTranslations(); + + return { + title: `${t("home.pageTitle")}`, + }; +} + +export default function DashboardLayout({ children }: LayoutProps) { + return <>{children}; +} diff --git a/apps/web/src/pages/dashboard/modals/dashboard-modals.tsx b/apps/web/src/app/dashboard/modals/dashboard-modals.tsx similarity index 100% rename from apps/web/src/pages/dashboard/modals/dashboard-modals.tsx rename to apps/web/src/app/dashboard/modals/dashboard-modals.tsx index 6a5fc11..674af5b 100644 --- a/apps/web/src/pages/dashboard/modals/dashboard-modals.tsx +++ b/apps/web/src/app/dashboard/modals/dashboard-modals.tsx @@ -1,4 +1,3 @@ -import { DashboardModalsProps } from "../types"; import { CreateShareModal } from "@/components/modals/create-share-modal"; import { FileActionsModals } from "@/components/modals/file-actions-modals"; import { FilePreviewModal } from "@/components/modals/file-preview-modal"; @@ -6,6 +5,7 @@ import { GenerateShareLinkModal } from "@/components/modals/generate-share-link- import { ShareActionsModals } from "@/components/modals/share-actions-modals"; import { ShareDetailsModal } from "@/components/modals/share-details-modal"; import { UploadFileModal } from "@/components/modals/upload-file-modal"; +import { DashboardModalsProps } from "../types"; export function DashboardModals({ modals, fileManager, shareManager, onSuccess }: DashboardModalsProps) { return ( diff --git a/apps/web/src/app/dashboard/page.tsx b/apps/web/src/app/dashboard/page.tsx new file mode 100644 index 0000000..bdc1689 --- /dev/null +++ b/apps/web/src/app/dashboard/page.tsx @@ -0,0 +1,72 @@ +"use client"; + +import { IconLayoutDashboardFilled } from "@tabler/icons-react"; +import { useTranslations } from "next-intl"; + +import { ProtectedRoute } from "@/components/auth/protected-route"; +import { FileManagerLayout } from "@/components/layout/file-manager-layout"; +import { LoadingScreen } from "@/components/layout/loading-screen"; +import { QuickAccessCards } from "./components/quick-access-cards"; +import { RecentFiles } from "./components/recent-files"; +import { RecentShares } from "./components/recent-shares"; +import { StorageUsage } from "./components/storage-usage"; +import { useDashboard } from "./hooks/use-dashboard"; +import { DashboardModals } from "./modals/dashboard-modals"; + +export default function DashboardPage() { + const t = useTranslations(); + + const { + isLoading, + diskSpace, + recentFiles, + recentShares, + modals, + fileManager, + shareManager, + handleCopyLink, + loadDashboardData, + } = useDashboard(); + + if (isLoading) { + return ; + } + + return ( + + } + showBreadcrumb={false} + title={t("dashboard.pageTitle")} + > + + + +
    + + + +
    + + +
    +
    + ); +} diff --git a/apps/web/src/pages/dashboard/types/index.ts b/apps/web/src/app/dashboard/types/index.ts similarity index 100% rename from apps/web/src/pages/dashboard/types/index.ts rename to apps/web/src/app/dashboard/types/index.ts diff --git a/apps/web/src/pages/dashboard/utils/format-storage-size.ts b/apps/web/src/app/dashboard/utils/format-storage-size.ts similarity index 100% rename from apps/web/src/pages/dashboard/utils/format-storage-size.ts rename to apps/web/src/app/dashboard/utils/format-storage-size.ts diff --git a/apps/web/favicon.ico b/apps/web/src/app/favicon.ico similarity index 100% rename from apps/web/favicon.ico rename to apps/web/src/app/favicon.ico diff --git a/apps/web/src/app/files/components/empty-state.tsx b/apps/web/src/app/files/components/empty-state.tsx new file mode 100644 index 0000000..6e7bef9 --- /dev/null +++ b/apps/web/src/app/files/components/empty-state.tsx @@ -0,0 +1,20 @@ +import { IconCloudUpload, IconFolder } from "@tabler/icons-react"; +import { useTranslations } from "next-intl"; + +import { Button } from "@/components/ui/button"; +import type { EmptyStateProps } from "../types"; + +export function EmptyState({ onUpload }: EmptyStateProps) { + const t = useTranslations(); + + return ( +
    + +

    {t("emptyState.noFiles")}

    + +
    + ); +} diff --git a/apps/web/src/pages/files/components/file-list.tsx b/apps/web/src/app/files/components/file-list.tsx similarity index 91% rename from apps/web/src/pages/files/components/file-list.tsx rename to apps/web/src/app/files/components/file-list.tsx index 8321ada..30da5ad 100644 --- a/apps/web/src/pages/files/components/file-list.tsx +++ b/apps/web/src/app/files/components/file-list.tsx @@ -1,14 +1,14 @@ +import { FilesTable } from "@/components/tables/files-table"; +import { Card, CardContent } from "@/components/ui/card"; import { FileListProps } from "../types"; import { EmptyState } from "./empty-state"; import { Header } from "./header"; import { SearchBar } from "./search-bar"; -import { FilesTable } from "@/components/tables/files-table"; -import { Card, CardBody } from "@heroui/card"; export function FileList({ files, filteredFiles, fileManager, searchQuery, onSearch, onUpload }: FileListProps) { return ( - +
    )}
    -
    +
    ); } diff --git a/apps/web/src/pages/files/components/header.tsx b/apps/web/src/app/files/components/header.tsx similarity index 51% rename from apps/web/src/pages/files/components/header.tsx rename to apps/web/src/app/files/components/header.tsx index 07a844b..397ad45 100644 --- a/apps/web/src/pages/files/components/header.tsx +++ b/apps/web/src/app/files/components/header.tsx @@ -1,15 +1,17 @@ +import { IconCloudUpload } from "@tabler/icons-react"; +import { useTranslations } from "next-intl"; + +import { Button } from "@/components/ui/button"; import type { HeaderProps } from "../types"; -import { Button } from "@heroui/button"; -import { useTranslation } from "react-i18next"; -import { FaCloudUploadAlt } from "react-icons/fa"; export function Header({ onUpload }: HeaderProps) { - const { t } = useTranslation(); + const t = useTranslations(); return (

    {t("files.title")}

    -
    diff --git a/apps/web/src/app/files/components/search-bar.tsx b/apps/web/src/app/files/components/search-bar.tsx new file mode 100644 index 0000000..ebb6fe0 --- /dev/null +++ b/apps/web/src/app/files/components/search-bar.tsx @@ -0,0 +1,28 @@ +import { IconSearch } from "@tabler/icons-react"; +import { useTranslations } from "next-intl"; + +import { Input } from "@/components/ui/input"; +import type { SearchBarProps } from "../types"; + +export function SearchBar({ searchQuery, onSearch, totalFiles, filteredCount }: SearchBarProps) { + const t = useTranslations(); + + return ( +
    +
    + + onSearch(e.target.value)} + /> +
    + {searchQuery && ( + + {t("searchBar.results", { filtered: filteredCount, total: totalFiles })} + + )} +
    + ); +} diff --git a/apps/web/src/pages/files/hooks/use-files.ts b/apps/web/src/app/files/hooks/use-files.ts similarity index 80% rename from apps/web/src/pages/files/hooks/use-files.ts rename to apps/web/src/app/files/hooks/use-files.ts index ec9fcb2..17c4f49 100644 --- a/apps/web/src/pages/files/hooks/use-files.ts +++ b/apps/web/src/app/files/hooks/use-files.ts @@ -1,16 +1,18 @@ -import { useFileManager } from "@/hooks/use-file-manager"; -import { listFiles } from "@/http/endpoints"; -import { useDisclosure } from "@heroui/modal"; +"use client"; + import { useEffect, useState } from "react"; -import { useTranslation } from "react-i18next"; +import { useTranslations } from "next-intl"; import { toast } from "sonner"; +import { useFileManager } from "@/hooks/use-file-manager"; +import { listFiles } from "@/http/endpoints"; + export function useFiles() { - const { t } = useTranslation(); + const t = useTranslations(); const [files, setFiles] = useState([]); const [isLoading, setIsLoading] = useState(true); const [searchQuery, setSearchQuery] = useState(""); - const { isOpen: isUploadModalOpen, onOpen: onOpenUploadModal, onClose: onCloseUploadModal } = useDisclosure(); + const [isUploadModalOpen, setIsUploadModalOpen] = useState(false); const loadFiles = async () => { try { @@ -42,8 +44,8 @@ export function useFiles() { searchQuery, modals: { isUploadModalOpen, - onOpenUploadModal, - onCloseUploadModal, + onOpenUploadModal: () => setIsUploadModalOpen(true), + onCloseUploadModal: () => setIsUploadModalOpen(false), }, fileManager, filteredFiles, diff --git a/apps/web/src/app/files/layout.tsx b/apps/web/src/app/files/layout.tsx new file mode 100644 index 0000000..ac935b9 --- /dev/null +++ b/apps/web/src/app/files/layout.tsx @@ -0,0 +1,18 @@ +import { Metadata } from "next"; +import { getTranslations } from "next-intl/server"; + +interface LayoutProps { + children: React.ReactNode; +} + +export async function generateMetadata(): Promise { + const t = await getTranslations(); + + return { + title: `${t("files.pageTitle")} `, + }; +} + +export default function FilesLayout({ children }: LayoutProps) { + return <>{children}; +} diff --git a/apps/web/src/pages/files/modals/files-modals.tsx b/apps/web/src/app/files/modals/files-modals.tsx similarity index 100% rename from apps/web/src/pages/files/modals/files-modals.tsx rename to apps/web/src/app/files/modals/files-modals.tsx index 51d4030..df54ce6 100644 --- a/apps/web/src/pages/files/modals/files-modals.tsx +++ b/apps/web/src/app/files/modals/files-modals.tsx @@ -1,7 +1,7 @@ -import type { FilesModalsProps } from "../types"; import { FileActionsModals } from "@/components/modals/file-actions-modals"; import { FilePreviewModal } from "@/components/modals/file-preview-modal"; import { UploadFileModal } from "@/components/modals/upload-file-modal"; +import type { FilesModalsProps } from "../types"; export function FilesModals({ fileManager, modals, onSuccess }: FilesModalsProps) { return ( diff --git a/apps/web/src/app/files/page.tsx b/apps/web/src/app/files/page.tsx new file mode 100644 index 0000000..56832bc --- /dev/null +++ b/apps/web/src/app/files/page.tsx @@ -0,0 +1,42 @@ +"use client"; + +import { IconFolderOpen } from "@tabler/icons-react"; +import { useTranslations } from "next-intl"; + +import { ProtectedRoute } from "@/components/auth/protected-route"; +import { FileManagerLayout } from "@/components/layout/file-manager-layout"; +import { LoadingScreen } from "@/components/layout/loading-screen"; +import { FileList } from "./components/file-list"; +import { useFiles } from "./hooks/use-files"; +import { FilesModals } from "./modals/files-modals"; + +export default function FilesPage() { + const t = useTranslations(); + + const { isLoading, files, searchQuery, modals, fileManager, filteredFiles, handleSearch, loadFiles } = useFiles(); + + if (isLoading) { + return ; + } + + return ( + + } + title={t("files.pageTitle")} + > + + + + + + ); +} diff --git a/apps/web/src/pages/files/types/index.ts b/apps/web/src/app/files/types/index.ts similarity index 100% rename from apps/web/src/pages/files/types/index.ts rename to apps/web/src/app/files/types/index.ts diff --git a/apps/web/src/app/forgot-password/components/forgot-password-form.tsx b/apps/web/src/app/forgot-password/components/forgot-password-form.tsx new file mode 100644 index 0000000..48d490e --- /dev/null +++ b/apps/web/src/app/forgot-password/components/forgot-password-form.tsx @@ -0,0 +1,48 @@ +import Link from "next/link"; +import { useTranslations } from "next-intl"; + +import { Button } from "@/components/ui/button"; +import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form"; +import { Input } from "@/components/ui/input"; +import { ForgotPasswordFormProps } from "../types"; + +export function ForgotPasswordForm({ form, onSubmit }: ForgotPasswordFormProps) { + const t = useTranslations(); + const isSubmitting = form.formState.isSubmitting; + + return ( +
    + + ( + + {t("forgotPassword.emailLabel")} + + + + + + )} + /> + + + +
    + + {t("forgotPassword.backToLogin")} + +
    + + + ); +} diff --git a/apps/web/src/pages/forgot-password/components/forgot-password-header.tsx b/apps/web/src/app/forgot-password/components/forgot-password-header.tsx similarity index 51% rename from apps/web/src/pages/forgot-password/components/forgot-password-header.tsx rename to apps/web/src/app/forgot-password/components/forgot-password-header.tsx index 029cc37..07eea69 100644 --- a/apps/web/src/pages/forgot-password/components/forgot-password-header.tsx +++ b/apps/web/src/app/forgot-password/components/forgot-password-header.tsx @@ -1,16 +1,16 @@ -import { useTranslation } from "react-i18next"; -import { RiLockPasswordFill } from "react-icons/ri"; +import { IconLock } from "@tabler/icons-react"; +import { useTranslations } from "next-intl"; export function ForgotPasswordHeader() { - const { t } = useTranslation(); + const t = useTranslations(); return (
    - +

    {t("forgotPassword.title")}

    -

    {t("forgotPassword.description")}

    +

    {t("forgotPassword.description")}

    ); } diff --git a/apps/web/src/pages/forgot-password/hooks/use-forgot-password.ts b/apps/web/src/app/forgot-password/hooks/use-forgot-password.ts similarity index 83% rename from apps/web/src/pages/forgot-password/hooks/use-forgot-password.ts rename to apps/web/src/app/forgot-password/hooks/use-forgot-password.ts index fc7e762..f35af22 100644 --- a/apps/web/src/pages/forgot-password/hooks/use-forgot-password.ts +++ b/apps/web/src/app/forgot-password/hooks/use-forgot-password.ts @@ -1,19 +1,22 @@ -import { requestPasswordReset } from "@/http/endpoints"; +"use client"; + +import { useRouter } from "next/navigation"; import { zodResolver } from "@hookform/resolvers/zod"; import axios from "axios"; +import { useTranslations } from "next-intl"; import { useForm } from "react-hook-form"; -import { useTranslation } from "react-i18next"; -import { useNavigate } from "react-router-dom"; import { toast } from "sonner"; import { z } from "zod"; +import { requestPasswordReset } from "@/http/endpoints"; + export type ForgotPasswordFormData = { email: string; }; export function useForgotPassword() { - const { t } = useTranslation(); - const navigate = useNavigate(); + const t = useTranslations(); + const router = useRouter(); const forgotPasswordSchema = z.object({ email: z.string().email(t("validation.invalidEmail")), @@ -27,7 +30,7 @@ export function useForgotPassword() { try { await requestPasswordReset(data); toast.success(t("forgotPassword.resetInstructions")); - navigate("/login"); + router.push("/login"); } catch (err) { if (axios.isAxiosError(err) && err.response?.data?.message) { toast.error(t(err.response.data.message)); diff --git a/apps/web/src/app/forgot-password/layout.tsx b/apps/web/src/app/forgot-password/layout.tsx new file mode 100644 index 0000000..b66218e --- /dev/null +++ b/apps/web/src/app/forgot-password/layout.tsx @@ -0,0 +1,18 @@ +import { Metadata } from "next"; +import { getTranslations } from "next-intl/server"; + +interface LayoutProps { + children: React.ReactNode; +} + +export async function generateMetadata(): Promise { + const t = await getTranslations(); + + return { + title: `${t("forgotPassword.pageTitle")}`, + }; +} + +export default function ForgotPasswordLayout({ children }: LayoutProps) { + return <>{children}; +} diff --git a/apps/web/src/pages/forgot-password/page.tsx b/apps/web/src/app/forgot-password/page.tsx similarity index 78% rename from apps/web/src/pages/forgot-password/page.tsx rename to apps/web/src/app/forgot-password/page.tsx index 115fc73..d421b01 100644 --- a/apps/web/src/pages/forgot-password/page.tsx +++ b/apps/web/src/app/forgot-password/page.tsx @@ -1,24 +1,20 @@ +"use client"; + +import { motion } from "framer-motion"; + +import { DefaultFooter } from "@/components/ui/default-footer"; import { StaticBackgroundLights } from "../login/components/static-background-lights"; import { ForgotPasswordForm } from "./components/forgot-password-form"; import { ForgotPasswordHeader } from "./components/forgot-password-header"; import { useForgotPassword } from "./hooks/use-forgot-password"; -import { DefaultFooter } from "@/components/ui/default-footer"; -import { GridPattern } from "@/components/ui/grid-pattern"; -import { usePageTitle } from "@/hooks/use-page-title"; -import { motion } from "framer-motion"; -import { useTranslation } from "react-i18next"; -export function ForgotPasswordPage() { - const { t } = useTranslation(); - - usePageTitle(t("forgotPassword.pageTitle")); +export default function ForgotPasswordPage() { const forgotPassword = useForgotPassword(); return (
    -
    ; onSubmit: (data: ForgotPasswordFormData) => Promise; diff --git a/apps/web/src/app/globals.css b/apps/web/src/app/globals.css new file mode 100644 index 0000000..fa695d8 --- /dev/null +++ b/apps/web/src/app/globals.css @@ -0,0 +1,122 @@ +@import "tailwindcss"; +@import "tw-animate-css"; + +@custom-variant dark (&:is(.dark *)); + +@theme inline { + --color-background: var(--background); + --color-foreground: var(--foreground); + --font-sans: var(--font-geist-sans); + --font-mono: var(--font-geist-mono); + --color-sidebar-ring: var(--sidebar-ring); + --color-sidebar-border: var(--sidebar-border); + --color-sidebar-accent-foreground: var(--sidebar-accent-foreground); + --color-sidebar-accent: var(--sidebar-accent); + --color-sidebar-primary-foreground: var(--sidebar-primary-foreground); + --color-sidebar-primary: var(--sidebar-primary); + --color-sidebar-foreground: var(--sidebar-foreground); + --color-sidebar: var(--sidebar); + --color-chart-5: var(--chart-5); + --color-chart-4: var(--chart-4); + --color-chart-3: var(--chart-3); + --color-chart-2: var(--chart-2); + --color-chart-1: var(--chart-1); + --color-ring: var(--ring); + --color-input: var(--input); + --color-border: var(--border); + --color-destructive: var(--destructive); + --color-accent-foreground: var(--accent-foreground); + --color-accent: var(--accent); + --color-muted-foreground: var(--muted-foreground); + --color-muted: var(--muted); + --color-secondary-foreground: var(--secondary-foreground); + --color-secondary: var(--secondary); + --color-primary-foreground: var(--primary-foreground); + --color-primary: var(--primary); + --color-popover-foreground: var(--popover-foreground); + --color-popover: var(--popover); + --color-card-foreground: var(--card-foreground); + --color-card: var(--card); + --radius-sm: calc(var(--radius) - 4px); + --radius-md: calc(var(--radius) - 2px); + --radius-lg: var(--radius); + --radius-xl: calc(var(--radius) + 4px); +} + +:root { + --radius: 0.75rem; + --background: oklch(1 0 0); + --foreground: oklch(0.141 0.005 285.823); + --card: oklch(1 0 0); + --card-foreground: oklch(0.141 0.005 285.823); + --popover: oklch(1 0 0); + --popover-foreground: oklch(0.141 0.005 285.823); + --primary: oklch(0.723 0.219 149.579); + --primary-foreground: oklch(0.982 0.018 155.826); + --secondary: oklch(0.967 0.001 286.375); + --secondary-foreground: oklch(0.21 0.006 285.885); + --muted: oklch(0.967 0.001 286.375); + --muted-foreground: oklch(0.552 0.016 285.938); + --accent: oklch(0.967 0.001 286.375); + --accent-foreground: oklch(0.21 0.006 285.885); + --destructive: oklch(0.577 0.245 27.325); + --border: oklch(0.92 0.004 286.32); + --input: oklch(0.92 0.004 286.32); + --ring: oklch(0.723 0.219 149.579); + --chart-1: oklch(0.646 0.222 41.116); + --chart-2: oklch(0.6 0.118 184.704); + --chart-3: oklch(0.398 0.07 227.392); + --chart-4: oklch(0.828 0.189 84.429); + --chart-5: oklch(0.769 0.188 70.08); + --sidebar: oklch(0.985 0 0); + --sidebar-foreground: oklch(0.141 0.005 285.823); + --sidebar-primary: oklch(0.723 0.219 149.579); + --sidebar-primary-foreground: oklch(0.982 0.018 155.826); + --sidebar-accent: oklch(0.967 0.001 286.375); + --sidebar-accent-foreground: oklch(0.21 0.006 285.885); + --sidebar-border: oklch(0.92 0.004 286.32); + --sidebar-ring: oklch(0.723 0.219 149.579); +} + +.dark { + --background: oklch(0 0 0); + --foreground: oklch(0.985 0 0); + --card: oklch(0.21 0.006 285.885); + --card-foreground: oklch(0.985 0 0); + --popover: oklch(0.21 0.006 285.885); + --popover-foreground: oklch(0.985 0 0); + --primary: oklch(0.723 0.219 149.579); + --primary-foreground: oklch(0.393 0.095 152.535); + --secondary: oklch(0.274 0.006 286.033); + --secondary-foreground: oklch(0.985 0 0); + --muted: oklch(0.274 0.006 286.033); + --muted-foreground: oklch(0.705 0.015 286.067); + --accent: oklch(0.274 0.006 286.033); + --accent-foreground: oklch(0.985 0 0); + --destructive: oklch(0.704 0.191 22.216); + --border: oklch(1 0 0 / 15%); + --input: oklch(1 0 0 / 15%); + --ring: oklch(0.527 0.154 150.069); + --chart-1: oklch(0.488 0.243 264.376); + --chart-2: oklch(0.723 0.219 149.579); + --chart-3: oklch(0.769 0.188 70.08); + --chart-4: oklch(0.627 0.265 303.9); + --chart-5: oklch(0.645 0.246 16.439); + --sidebar: oklch(0.21 0.006 285.885); + --sidebar-foreground: oklch(0.985 0 0); + --sidebar-primary: oklch(0.723 0.219 149.579); + --sidebar-primary-foreground: oklch(0.393 0.095 152.535); + --sidebar-accent: oklch(0.274 0.006 286.033); + --sidebar-accent-foreground: oklch(0.985 0 0); + --sidebar-border: oklch(1 0 0 / 10%); + --sidebar-ring: oklch(0.527 0.154 150.069); +} + +@layer base { + * { + @apply border-border outline-ring/50; + } + body { + @apply bg-background text-foreground; + } +} diff --git a/apps/web/src/app/layout.tsx b/apps/web/src/app/layout.tsx new file mode 100644 index 0000000..b67fbcd --- /dev/null +++ b/apps/web/src/app/layout.tsx @@ -0,0 +1,56 @@ +import { Geist, Geist_Mono } from "next/font/google"; +import { NextIntlClientProvider } from "next-intl"; +import { getLocale } from "next-intl/server"; + +import "./globals.css"; + +import { Toaster } from "sonner"; + +import { Favicon } from "@/components/layout/favicon"; +import { useAppInfo } from "@/contexts/app-info-context"; +import { AuthProvider } from "@/contexts/auth-context"; +import { ShareProvider } from "@/contexts/share-context"; +import { ThemeProvider } from "../providers/theme-provider"; + +const geistSans = Geist({ + variable: "--font-geist-sans", + subsets: ["latin"], +}); + +const geistMono = Geist_Mono({ + variable: "--font-geist-mono", + subsets: ["latin"], +}); + +export default async function RootLayout({ + children, +}: Readonly<{ + children: React.ReactNode; +}>) { + const locale = await getLocale(); + const isRTL = locale === "ar-SA"; + + if (typeof window !== "undefined") { + useAppInfo.getState().refreshAppInfo(); + } + + return ( + + + + + + + + + + {children} + + + + + + + + ); +} diff --git a/apps/web/src/app/login/components/login-form.tsx b/apps/web/src/app/login/components/login-form.tsx new file mode 100644 index 0000000..b9632a5 --- /dev/null +++ b/apps/web/src/app/login/components/login-form.tsx @@ -0,0 +1,106 @@ +import Link from "next/link"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { useTranslations } from "next-intl"; +import { useForm } from "react-hook-form"; + +import { Button } from "@/components/ui/button"; +import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form"; +import { Input } from "@/components/ui/input"; +import { createLoginSchema, type LoginFormValues } from "../schemas/schema"; +import { PasswordVisibilityToggle } from "./password-visibility-toggle"; + +interface LoginFormProps { + error?: string; + isVisible: boolean; + onToggleVisibility: () => void; + onSubmit: (data: LoginFormValues) => Promise; +} + +export function LoginForm({ error, isVisible, onToggleVisibility, onSubmit }: LoginFormProps) { + const t = useTranslations(); + const loginSchema = createLoginSchema(t); + const form = useForm({ + resolver: zodResolver(loginSchema), + defaultValues: { + email: "", + password: "", + }, + }); + + const isSubmitting = form.formState.isSubmitting; + + const renderErrorMessage = () => + error && ( +

    + {error.replace("errors.", "")} +

    + ); + + const renderEmailField = () => ( + ( + + {t("login.emailLabel")} + + + + + + )} + /> + ); + + const renderPasswordField = () => ( + ( + + {t("login.passwordLabel")} + +
    + + +
    +
    + +
    + )} + /> + ); + + return ( + <> + {renderErrorMessage()} +
    + + {renderEmailField()} + {renderPasswordField()} + +
    + + +
    + + {t("login.forgotPassword")} + +
    + + ); +} diff --git a/apps/web/src/app/login/components/login-header.tsx b/apps/web/src/app/login/components/login-header.tsx new file mode 100644 index 0000000..8b641fb --- /dev/null +++ b/apps/web/src/app/login/components/login-header.tsx @@ -0,0 +1,28 @@ +import { useEffect } from "react"; +import { motion } from "framer-motion"; +import { useTranslations } from "next-intl"; + +import { useAppInfo } from "@/contexts/app-info-context"; + +export function LoginHeader() { + const t = useTranslations(); + const { appName, refreshAppInfo } = useAppInfo(); + + useEffect(() => { + refreshAppInfo(); + }, [refreshAppInfo]); + + return ( + +

    + {t("login.welcome")} {appName} +

    +

    {t("login.signInToContinue")}

    +
    + ); +} diff --git a/apps/web/src/app/login/components/password-visibility-toggle.tsx b/apps/web/src/app/login/components/password-visibility-toggle.tsx new file mode 100644 index 0000000..fa12fa6 --- /dev/null +++ b/apps/web/src/app/login/components/password-visibility-toggle.tsx @@ -0,0 +1,25 @@ +import { IconEye, IconEyeClosed } from "@tabler/icons-react"; + +import { Button } from "@/components/ui/button"; + +interface PasswordVisibilityToggleProps { + isVisible: boolean; + onToggle: () => void; +} + +export function PasswordVisibilityToggle({ isVisible, onToggle }: PasswordVisibilityToggleProps) { + return ( + + ); +} diff --git a/apps/web/src/pages/login/components/static-background-lights.tsx b/apps/web/src/app/login/components/static-background-lights.tsx similarity index 100% rename from apps/web/src/pages/login/components/static-background-lights.tsx rename to apps/web/src/app/login/components/static-background-lights.tsx diff --git a/apps/web/src/app/login/hooks/use-login.ts b/apps/web/src/app/login/hooks/use-login.ts new file mode 100644 index 0000000..06ff14c --- /dev/null +++ b/apps/web/src/app/login/hooks/use-login.ts @@ -0,0 +1,87 @@ +"use client"; + +import { useEffect, useState } from "react"; +import { useRouter } from "next/navigation"; +import axios from "axios"; +import { useTranslations } from "next-intl"; +import { z } from "zod"; + +import { useAuth } from "@/contexts/auth-context"; +import { getCurrentUser, login } from "@/http/endpoints"; +import { LoginFormValues } from "../schemas/schema"; + +export const loginSchema = z.object({ + email: z.string(), + password: z.string(), +}); + +export type LoginFormData = z.infer; + +export function useLogin() { + const router = useRouter(); + const t = useTranslations(); + const { isAuthenticated, setUser, setIsAdmin, setIsAuthenticated } = useAuth(); + const [isVisible, setIsVisible] = useState(false); + const [error, setError] = useState(); + const [isInitialized, setIsInitialized] = useState(false); + + useEffect(() => { + const checkAuth = async () => { + try { + const userResponse = await getCurrentUser(); + if (!userResponse?.data?.user) { + throw new Error("No user data"); + } + + const { isAdmin, ...userData } = userResponse.data.user; + setUser(userData); + setIsAdmin(isAdmin); + setIsAuthenticated(true); + router.push("/dashboard"); + } catch (err) { + console.error(err); + setUser(null); + setIsAdmin(false); + setIsAuthenticated(false); + } finally { + setIsInitialized(true); + } + }; + + checkAuth(); + }, [router, setUser, setIsAdmin, setIsAuthenticated]); + + const toggleVisibility = () => setIsVisible(!isVisible); + + const onSubmit = async (data: LoginFormValues) => { + setError(undefined); + + try { + await login(data); + const userResponse = await getCurrentUser(); + const { isAdmin, ...userData } = userResponse.data.user; + + setUser(userData); + setIsAdmin(isAdmin); + setIsAuthenticated(true); + router.replace("/dashboard"); + } catch (err) { + if (axios.isAxiosError(err) && err.response?.data?.error) { + setError(t(`errors.${err.response.data.error}`)); + } else { + setError(t("errors.unexpectedError")); + } + setIsAuthenticated(false); + setUser(null); + setIsAdmin(false); + } + }; + + return { + isAuthenticated: !isInitialized ? null : isAuthenticated, + error, + isVisible, + toggleVisibility, + onSubmit, + }; +} diff --git a/apps/web/src/app/login/layout.tsx b/apps/web/src/app/login/layout.tsx new file mode 100644 index 0000000..31aba1d --- /dev/null +++ b/apps/web/src/app/login/layout.tsx @@ -0,0 +1,18 @@ +import { Metadata } from "next"; +import { getTranslations } from "next-intl/server"; + +interface LayoutProps { + children: React.ReactNode; +} + +export async function generateMetadata(): Promise { + const t = await getTranslations(); + + return { + title: `${t("login.pageTitle")} `, + }; +} + +export default function LoginLayout({ children }: LayoutProps) { + return <>{children}; +} diff --git a/apps/web/src/pages/login/page.tsx b/apps/web/src/app/login/page.tsx similarity index 77% rename from apps/web/src/pages/login/page.tsx rename to apps/web/src/app/login/page.tsx index 91170a3..378ee0a 100644 --- a/apps/web/src/pages/login/page.tsx +++ b/apps/web/src/app/login/page.tsx @@ -1,19 +1,16 @@ +"use client"; + +import { motion } from "framer-motion"; + +import { LanguageSwitcher } from "@/components/general/language-switcher"; +import { LoadingScreen } from "@/components/layout/loading-screen"; +import { DefaultFooter } from "@/components/ui/default-footer"; import { LoginForm } from "./components/login-form"; import { LoginHeader } from "./components/login-header"; import { StaticBackgroundLights } from "./components/static-background-lights"; import { useLogin } from "./hooks/use-login"; -import { LoadingScreen } from "@/components/layout/loading-screen"; -import { DefaultFooter } from "@/components/ui/default-footer"; -import { GridPattern } from "@/components/ui/grid-pattern"; -import { usePageTitle } from "@/hooks/use-page-title"; -import { motion } from "framer-motion"; -import { useTranslation } from "react-i18next"; - -export function LoginPage() { - const { t } = useTranslation(); - - usePageTitle(t("login.pageTitle")); +export default function LoginPage() { const login = useLogin(); if (login.isAuthenticated === null) { @@ -22,20 +19,22 @@ export function LoginPage() { return (
    +
    + +
    +
    -
    ; + +export const createLoginSchema = (t: TFunction) => + z.object({ + email: z.string().min(1, t("validation.emailRequired")).email(t("validation.invalidEmail")), + password: z.string().min(1, t("validation.passwordRequired")), + }); + +export type LoginFormValues = z.infer>; diff --git a/apps/web/src/pages/login/types/index.ts b/apps/web/src/app/login/types/index.ts similarity index 99% rename from apps/web/src/pages/login/types/index.ts rename to apps/web/src/app/login/types/index.ts index d98fa6f..8853e6c 100644 --- a/apps/web/src/pages/login/types/index.ts +++ b/apps/web/src/app/login/types/index.ts @@ -1,6 +1,7 @@ -import { LoginFormData } from "../hooks/use-login"; import { UseFormReturn } from "react-hook-form"; +import { LoginFormData } from "../hooks/use-login"; + export interface LoginFormProps { form: UseFormReturn; error: string | null; diff --git a/apps/web/src/app/profile/components/password-form.tsx b/apps/web/src/app/profile/components/password-form.tsx new file mode 100644 index 0000000..3dee8dd --- /dev/null +++ b/apps/web/src/app/profile/components/password-form.tsx @@ -0,0 +1,79 @@ +import { IconEye, IconEyeClosed, IconLock } from "@tabler/icons-react"; +import { useTranslations } from "next-intl"; + +import { Button } from "@/components/ui/button"; +import { Card, CardContent, CardHeader } from "@/components/ui/card"; +import { Input } from "@/components/ui/input"; +import { PasswordFormProps } from "../types"; + +export function PasswordForm({ + form, + isNewPasswordVisible, + isConfirmPasswordVisible, + onToggleNewPassword, + onToggleConfirmPassword, + onSubmit, +}: PasswordFormProps) { + const t = useTranslations(); + const { + register, + handleSubmit, + formState: { errors, isSubmitting }, + } = form; + + return ( + + +

    {t("profile.password.title")}

    +
    + +
    +
    + + + {errors.newPassword &&

    {errors.newPassword.message}

    } +
    + +
    + + + {errors.confirmPassword && ( +

    {errors.confirmPassword.message}

    + )} +
    + +
    + +
    +
    +
    +
    + ); +} diff --git a/apps/web/src/app/profile/components/profile-form.tsx b/apps/web/src/app/profile/components/profile-form.tsx new file mode 100644 index 0000000..939d7fe --- /dev/null +++ b/apps/web/src/app/profile/components/profile-form.tsx @@ -0,0 +1,77 @@ +import { IconUserEdit } from "@tabler/icons-react"; +import { useTranslations } from "next-intl"; + +import { Button } from "@/components/ui/button"; +import { Card, CardContent, CardHeader } from "@/components/ui/card"; +import { Input } from "@/components/ui/input"; +import { ProfileFormProps } from "../types"; + +export function ProfileForm({ form, onSubmit }: ProfileFormProps) { + const t = useTranslations(); + const { + register, + handleSubmit, + formState: { errors, isSubmitting }, + } = form; + + return ( + + +

    {t("profile.form.title")}

    +
    + +
    +
    +
    + + {errors.firstName && {errors.firstName.message}} +
    +
    + + {errors.lastName && {errors.lastName.message}} +
    +
    +
    + + {errors.username && {errors.username.message}} +
    +
    + + {errors.email && {errors.email.message}} +
    +
    + +
    +
    +
    +
    + ); +} diff --git a/apps/web/src/app/profile/components/profile-header.tsx b/apps/web/src/app/profile/components/profile-header.tsx new file mode 100644 index 0000000..26afe32 --- /dev/null +++ b/apps/web/src/app/profile/components/profile-header.tsx @@ -0,0 +1,44 @@ +import Link from "next/link"; +import { IconLayoutDashboard, IconUser } from "@tabler/icons-react"; +import { useTranslations } from "next-intl"; + +import { + Breadcrumb, + BreadcrumbItem, + BreadcrumbLink, + BreadcrumbList, + BreadcrumbSeparator, +} from "@/components/ui/breadcrumb"; +import { Separator } from "@/components/ui/separator"; + +export function ProfileHeader() { + const t = useTranslations(); + + return ( +
    +
    + +

    {t("profile.header.title")}

    +
    + + + + + + + + {t("navigation.dashboard")} + + + + + + + {t("profile.header.title")} + + + + +
    + ); +} diff --git a/apps/web/src/app/profile/components/profile-picture.tsx b/apps/web/src/app/profile/components/profile-picture.tsx new file mode 100644 index 0000000..8c1b470 --- /dev/null +++ b/apps/web/src/app/profile/components/profile-picture.tsx @@ -0,0 +1,84 @@ +"use client"; + +import { useRef } from "react"; +import { IconCamera, IconTrash } from "@tabler/icons-react"; +import { useTranslations } from "next-intl"; + +import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; +import { Button } from "@/components/ui/button"; +import { Card, CardHeader } from "@/components/ui/card"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu"; +import { Input } from "@/components/ui/input"; +import type { ProfilePictureProps } from "../types"; + +export function ProfilePicture({ userData, onImageChange, onImageRemove }: ProfilePictureProps) { + const t = useTranslations(); + const fileInputRef = useRef(null); + + const handleAvatarClick = () => { + fileInputRef.current?.click(); + }; + + const handleFileChange = (e: React.ChangeEvent) => { + const file = e.target.files?.[0]; + + if (file) { + onImageChange(file); + } + }; + + return ( + + +
    + + + + {userData?.firstName + ? userData.firstName + .split(" ") + .map((firstName) => firstName[0]) + .join("") + .toUpperCase() + : ""} + + + + + + + + {!!userData?.image ? ( + + + {t("profile.picture.removePhoto")} + + ) : ( + + + {t("profile.picture.uploadPhoto")} + + )} + + + +
    +
    +

    {t("profile.picture.title")}

    +

    {t("profile.picture.description")}

    +
    +
    +
    + ); +} diff --git a/apps/web/src/pages/profile/hooks/use-profile.ts b/apps/web/src/app/profile/hooks/use-profile.ts similarity index 95% rename from apps/web/src/pages/profile/hooks/use-profile.ts rename to apps/web/src/app/profile/hooks/use-profile.ts index 4e94449..29a8a71 100644 --- a/apps/web/src/pages/profile/hooks/use-profile.ts +++ b/apps/web/src/app/profile/hooks/use-profile.ts @@ -1,14 +1,16 @@ -import { useAuth } from "@/contexts/auth-context"; -import { getCurrentUser, updateUser, uploadAvatar, removeAvatar } from "@/http/endpoints"; -import { zodResolver } from "@hookform/resolvers/zod"; -import { TFunction } from "i18next"; +"use client"; + import { useEffect, useState } from "react"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { useTranslations } from "next-intl"; import { useForm } from "react-hook-form"; -import { useTranslation } from "react-i18next"; import { toast } from "sonner"; import { z } from "zod"; -const createSchemas = (t: TFunction) => ({ +import { useAuth } from "@/contexts/auth-context"; +import { getCurrentUser, removeAvatar, updateUser, uploadAvatar } from "@/http/endpoints"; + +const createSchemas = (t: (key: string) => string) => ({ profileSchema: z.object({ firstName: z.string().min(1, t("validation.firstNameRequired")), lastName: z.string().min(1, t("validation.lastNameRequired")), @@ -34,7 +36,7 @@ export type PasswordFormData = z.infer["passwor export type ProfileFormData = z.infer["profileSchema"]>; export function useProfile() { - const { t } = useTranslation(); + const t = useTranslations(); const { profileSchema, passwordSchema } = createSchemas(t); const { setUser } = useAuth(); diff --git a/apps/web/src/app/profile/layout.tsx b/apps/web/src/app/profile/layout.tsx new file mode 100644 index 0000000..0fd4b28 --- /dev/null +++ b/apps/web/src/app/profile/layout.tsx @@ -0,0 +1,18 @@ +import { Metadata } from "next"; +import { getTranslations } from "next-intl/server"; + +interface LayoutProps { + children: React.ReactNode; +} + +export async function generateMetadata(): Promise { + const t = await getTranslations(); + + return { + title: `${t("profile.pageTitle")}`, + }; +} + +export default function ProfileLayout({ children }: LayoutProps) { + return <>{children}; +} diff --git a/apps/web/src/app/profile/page.tsx b/apps/web/src/app/profile/page.tsx new file mode 100644 index 0000000..b71b3e9 --- /dev/null +++ b/apps/web/src/app/profile/page.tsx @@ -0,0 +1,49 @@ +"use client"; + +import { ProtectedRoute } from "@/components/auth/protected-route"; +import { LoadingScreen } from "@/components/layout/loading-screen"; +import { Navbar } from "@/components/layout/navbar"; +import { DefaultFooter } from "@/components/ui/default-footer"; +import { PasswordForm } from "./components/password-form"; +import { ProfileForm } from "./components/profile-form"; +import { ProfileHeader } from "./components/profile-header"; +import { ProfilePicture } from "./components/profile-picture"; +import { useProfile } from "./hooks/use-profile"; + +export default function ProfilePage() { + const profile = useProfile(); + + if (profile.isLoading) { + return ; + } + + return ( + +
    + +
    +
    + +
    + + + profile.setIsConfirmPasswordVisible(!profile.isConfirmPasswordVisible)} + onToggleNewPassword={() => profile.setIsNewPasswordVisible(!profile.isNewPasswordVisible)} + /> +
    +
    +
    + +
    +
    + ); +} diff --git a/apps/web/src/pages/profile/types/index.ts b/apps/web/src/app/profile/types/index.ts similarity index 99% rename from apps/web/src/pages/profile/types/index.ts rename to apps/web/src/app/profile/types/index.ts index b36ba96..023a0da 100644 --- a/apps/web/src/pages/profile/types/index.ts +++ b/apps/web/src/app/profile/types/index.ts @@ -1,6 +1,7 @@ -import { PasswordFormData, ProfileFormData } from "../hooks/use-profile"; import { UseFormReturn } from "react-hook-form"; +import { PasswordFormData, ProfileFormData } from "../hooks/use-profile"; + export interface PasswordFormProps { form: UseFormReturn; isNewPasswordVisible: boolean; diff --git a/apps/web/src/app/reset-password/components/reset-password-form.tsx b/apps/web/src/app/reset-password/components/reset-password-form.tsx new file mode 100644 index 0000000..f211a01 --- /dev/null +++ b/apps/web/src/app/reset-password/components/reset-password-form.tsx @@ -0,0 +1,94 @@ +import Link from "next/link"; +import { IconEye, IconEyeOff } from "@tabler/icons-react"; +import { useTranslations } from "next-intl"; + +import { Button } from "@/components/ui/button"; +import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form"; +import { Input } from "@/components/ui/input"; +import { ResetPasswordFormProps } from "../types"; + +export function ResetPasswordForm({ + form, + isPasswordVisible, + isConfirmPasswordVisible, + onTogglePassword, + onToggleConfirmPassword, + onSubmit, +}: ResetPasswordFormProps) { + const t = useTranslations(); + const isSubmitting = form.formState.isSubmitting; + + return ( +
    + + ( + + {t("resetPassword.form.newPassword")} + +
    + + +
    +
    + +
    + )} + /> + + ( + + {t("resetPassword.form.confirmPassword")} + +
    + + +
    +
    + +
    + )} + /> + + + +
    + + {t("resetPassword.form.backToLogin")} + +
    + + + ); +} diff --git a/apps/web/src/pages/reset-password/components/reset-password-header.tsx b/apps/web/src/app/reset-password/components/reset-password-header.tsx similarity index 66% rename from apps/web/src/pages/reset-password/components/reset-password-header.tsx rename to apps/web/src/app/reset-password/components/reset-password-header.tsx index 2a5f05e..57dbde1 100644 --- a/apps/web/src/pages/reset-password/components/reset-password-header.tsx +++ b/apps/web/src/app/reset-password/components/reset-password-header.tsx @@ -1,13 +1,13 @@ -import { useTranslation } from "react-i18next"; -import { RiLockPasswordFill } from "react-icons/ri"; +import { IconLock } from "@tabler/icons-react"; +import { useTranslations } from "next-intl"; export function ResetPasswordHeader() { - const { t } = useTranslation(); + const t = useTranslations(); return (
    - +

    {t("resetPassword.header.title")}

    {t("resetPassword.header.description")}

    diff --git a/apps/web/src/pages/reset-password/hooks/use-reset-password.ts b/apps/web/src/app/reset-password/hooks/use-reset-password.ts similarity index 83% rename from apps/web/src/pages/reset-password/hooks/use-reset-password.ts rename to apps/web/src/app/reset-password/hooks/use-reset-password.ts index d53f02e..18e1676 100644 --- a/apps/web/src/pages/reset-password/hooks/use-reset-password.ts +++ b/apps/web/src/app/reset-password/hooks/use-reset-password.ts @@ -1,15 +1,17 @@ -import { resetPassword } from "@/http/endpoints"; +"use client"; + +import { useState } from "react"; +import { useRouter, useSearchParams } from "next/navigation"; import { zodResolver } from "@hookform/resolvers/zod"; import axios from "axios"; -import { TFunction } from "i18next"; -import { useState } from "react"; +import { useTranslations } from "next-intl"; import { useForm } from "react-hook-form"; -import { useTranslation } from "react-i18next"; -import { useNavigate, useSearchParams } from "react-router-dom"; import { toast } from "sonner"; import { z } from "zod"; -const createSchema = (t: TFunction) => +import { resetPassword } from "@/http/endpoints"; + +const createSchema = (t: (key: string) => string) => z .object({ password: z.string().min(8, t("validation.passwordLength")), @@ -23,10 +25,10 @@ const createSchema = (t: TFunction) => export type ResetPasswordFormData = z.infer>; export function useResetPassword() { - const { t } = useTranslation(); + const t = useTranslations(); const schema = createSchema(t); - const navigate = useNavigate(); - const [searchParams] = useSearchParams(); + const router = useRouter(); + const searchParams = useSearchParams(); const token = searchParams.get("token"); const [isPasswordVisible, setIsPasswordVisible] = useState(false); const [isConfirmPasswordVisible, setIsConfirmPasswordVisible] = useState(false); @@ -45,7 +47,7 @@ export function useResetPassword() { }); toast.success(t("resetPassword.messages.success")); - navigate("/login"); + router.push("/login"); } catch (err) { if (axios.isAxiosError(err) && err.response?.data?.error) { toast.error(t("resetPassword.errors.serverError")); diff --git a/apps/web/src/app/reset-password/layout.tsx b/apps/web/src/app/reset-password/layout.tsx new file mode 100644 index 0000000..82cb6d9 --- /dev/null +++ b/apps/web/src/app/reset-password/layout.tsx @@ -0,0 +1,18 @@ +import { Metadata } from "next"; +import { getTranslations } from "next-intl/server"; + +interface LayoutProps { + children: React.ReactNode; +} + +export async function generateMetadata(): Promise { + const t = await getTranslations(); + + return { + title: `${t("resetPassword.pageTitle")} `, + }; +} + +export default function ResetPasswordLayout({ children }: LayoutProps) { + return <>{children}; +} diff --git a/apps/web/src/pages/reset-password/page.tsx b/apps/web/src/app/reset-password/page.tsx similarity index 79% rename from apps/web/src/pages/reset-password/page.tsx rename to apps/web/src/app/reset-password/page.tsx index 5c4a24a..dffe5b6 100644 --- a/apps/web/src/pages/reset-password/page.tsx +++ b/apps/web/src/app/reset-password/page.tsx @@ -1,35 +1,34 @@ +"use client"; + +import { useEffect } from "react"; +import { useRouter } from "next/navigation"; +import { motion } from "framer-motion"; +import { useTranslations } from "next-intl"; +import { toast } from "sonner"; + +import { DefaultFooter } from "@/components/ui/default-footer"; import { StaticBackgroundLights } from "../login/components/static-background-lights"; import { ResetPasswordForm } from "./components/reset-password-form"; import { ResetPasswordHeader } from "./components/reset-password-header"; import { useResetPassword } from "./hooks/use-reset-password"; -import { DefaultFooter } from "@/components/ui/default-footer"; -import { GridPattern } from "@/components/ui/grid-pattern"; -import { usePageTitle } from "@/hooks/use-page-title"; -import { motion } from "framer-motion"; -import { useEffect } from "react"; -import { useTranslation } from "react-i18next"; -import { useNavigate } from "react-router-dom"; -import { toast } from "sonner"; -export function ResetPasswordPage() { - const { t } = useTranslation(); +export default function ResetPasswordPage() { + const t = useTranslations(); - usePageTitle(t("resetPassword.pageTitle")); - const navigate = useNavigate(); + const router = useRouter(); const resetPassword = useResetPassword(); useEffect(() => { if (!resetPassword.token) { toast.error(t("resetPassword.errors.invalidToken")); - navigate("/login"); + router.push("/login"); } - }, [resetPassword.token, navigate, t]); + }, [resetPassword.token, router, t]); return (
    -
    ; isPasswordVisible: boolean; diff --git a/apps/web/src/pages/settings/components/logo-input.tsx b/apps/web/src/app/settings/components/logo-input.tsx similarity index 72% rename from apps/web/src/pages/settings/components/logo-input.tsx rename to apps/web/src/app/settings/components/logo-input.tsx index 256a269..4cdba72 100644 --- a/apps/web/src/pages/settings/components/logo-input.tsx +++ b/apps/web/src/app/settings/components/logo-input.tsx @@ -1,11 +1,13 @@ +"use client"; + +import { useEffect, useRef, useState } from "react"; +import { IconCloudUpload, IconTrash } from "@tabler/icons-react"; +import { useTranslations } from "next-intl"; +import { toast } from "sonner"; + +import { Button } from "@/components/ui/button"; import { useAppInfo } from "@/contexts/app-info-context"; import { removeLogo, uploadLogo } from "@/http/endpoints"; -import { Button } from "@heroui/button"; -import { Image } from "@heroui/image"; -import { useEffect, useRef, useState } from "react"; -import { useTranslation } from "react-i18next"; -import { FaCloudUploadAlt, FaTrash } from "react-icons/fa"; -import { toast } from "sonner"; interface LogoInputProps { value?: string; @@ -14,7 +16,7 @@ interface LogoInputProps { } export function LogoInput({ value, onChange, isDisabled }: LogoInputProps) { - const { t } = useTranslation(); + const t = useTranslations(); const [isUploading, setIsUploading] = useState(false); const [currentLogo, setCurrentLogo] = useState(value); const fileInputRef = useRef(null); @@ -78,31 +80,22 @@ export function LogoInput({ value, onChange, isDisabled }: LogoInputProps) { {currentLogo ? (
    - {t("logo.labels.appLogo")} -
    ) : ( )} diff --git a/apps/web/src/pages/settings/components/settings-form.tsx b/apps/web/src/app/settings/components/settings-form.tsx similarity index 92% rename from apps/web/src/pages/settings/components/settings-form.tsx rename to apps/web/src/app/settings/components/settings-form.tsx index ceb2ab1..7ba737a 100644 --- a/apps/web/src/pages/settings/components/settings-form.tsx +++ b/apps/web/src/app/settings/components/settings-form.tsx @@ -1,5 +1,4 @@ -import { ValidGroup } from "../types"; -import { SettingsFormProps } from "../types"; +import { SettingsFormProps, ValidGroup } from "../types"; import { SettingsGroup } from "./settings-group"; const GROUP_ORDER: ValidGroup[] = ["general", "email", "security", "storage"]; diff --git a/apps/web/src/pages/settings/components/settings-group.tsx b/apps/web/src/app/settings/components/settings-group.tsx similarity index 63% rename from apps/web/src/pages/settings/components/settings-group.tsx rename to apps/web/src/app/settings/components/settings-group.tsx index 1074719..f7a11d7 100644 --- a/apps/web/src/pages/settings/components/settings-group.tsx +++ b/apps/web/src/app/settings/components/settings-group.tsx @@ -1,15 +1,16 @@ -import { createGroupMetadata, createFieldDescriptions } from "../constants"; +import React from "react"; +import { IconChevronDown, IconChevronUp, IconDeviceFloppy } from "@tabler/icons-react"; +import { useTranslations } from "next-intl"; + +import { Button } from "@/components/ui/button"; +import { Card, CardContent, CardHeader } from "@/components/ui/card"; +import { Separator } from "@/components/ui/separator"; +import { createFieldDescriptions, createGroupMetadata } from "../constants"; import { SettingsGroupProps } from "../types"; import { SettingsInput } from "./settings-input"; -import { Button } from "@heroui/button"; -import { Card, CardBody, CardHeader } from "@heroui/card"; -import { Divider } from "@heroui/divider"; -import React from "react"; -import { useTranslation } from "react-i18next"; -import { FaChevronDown, FaChevronUp, FaSave } from "react-icons/fa"; export function SettingsGroup({ group, configs, form, isCollapsed, onToggleCollapse, onSubmit }: SettingsGroupProps) { - const { t } = useTranslation(); + const t = useTranslations(); const GROUP_METADATA = createGroupMetadata(t); const FIELD_DESCRIPTIONS = createFieldDescriptions(t); @@ -20,23 +21,30 @@ export function SettingsGroup({ group, configs, form, isCollapsed, onToggleColla return (
    - - + +
    - {metadata.icon && React.createElement(metadata.icon, { className: "text-xl text-gray-500" })} + {metadata.icon && React.createElement(metadata.icon, { className: "text-xl text-muted-foreground" })}

    {t(`settings.groups.${group}.title`, { defaultValue: metadata.title })}

    -

    +

    {t(`settings.groups.${group}.description`, { defaultValue: metadata.description })}

    - {isCollapsed ? : } + {isCollapsed ? ( + + ) : ( + + )}
    - - + +
    {configs.map((config) => (
    @@ -47,7 +55,7 @@ export function SettingsGroup({ group, configs, form, isCollapsed, onToggleColla smtpEnabled={form.watch("configs.smtpEnabled")} watch={form.watch} /> -

    +

    {t(`settings.fields.${config.key}.description`, { defaultValue: FIELD_DESCRIPTIONS[config.key as keyof typeof FIELD_DESCRIPTIONS] || @@ -60,17 +68,18 @@ export function SettingsGroup({ group, configs, form, isCollapsed, onToggleColla

    - + ); diff --git a/apps/web/src/app/settings/components/settings-header.tsx b/apps/web/src/app/settings/components/settings-header.tsx new file mode 100644 index 0000000..5fa6f4c --- /dev/null +++ b/apps/web/src/app/settings/components/settings-header.tsx @@ -0,0 +1,44 @@ +import Link from "next/link"; +import { IconLayoutDashboard, IconSettings } from "@tabler/icons-react"; +import { useTranslations } from "next-intl"; + +import { + Breadcrumb, + BreadcrumbItem, + BreadcrumbLink, + BreadcrumbList, + BreadcrumbSeparator, +} from "@/components/ui/breadcrumb"; +import { Separator } from "@/components/ui/separator"; + +export function SettingsHeader() { + const t = useTranslations(); + + return ( +
    +
    + +

    {t("settings.title")}

    +
    + + + + + + + + {t("navigation.dashboard")} + + + + + + + {t("settings.breadcrumb")} + + + + +
    + ); +} diff --git a/apps/web/src/pages/settings/components/settings-input.tsx b/apps/web/src/app/settings/components/settings-input.tsx similarity index 60% rename from apps/web/src/pages/settings/components/settings-input.tsx rename to apps/web/src/app/settings/components/settings-input.tsx index a5d9ebe..9b00b03 100644 --- a/apps/web/src/pages/settings/components/settings-input.tsx +++ b/apps/web/src/app/settings/components/settings-input.tsx @@ -1,10 +1,10 @@ +import { useTranslations } from "next-intl"; +import { UseFormRegister, UseFormWatch } from "react-hook-form"; + +import { Input } from "@/components/ui/input"; import { createFieldTitles } from "../constants"; import { Config } from "../types"; import { LogoInput } from "./logo-input"; -import { Input } from "@heroui/input"; -import { Select, SelectItem } from "@heroui/select"; -import { UseFormRegister, UseFormWatch } from "react-hook-form"; -import { useTranslation } from "react-i18next"; export interface ConfigInputProps { config: Config; @@ -15,7 +15,7 @@ export interface ConfigInputProps { } export function SettingsInput({ config, register, watch, error, smtpEnabled }: ConfigInputProps) { - const { t } = useTranslation(); + const t = useTranslations(); const FIELD_TITLES = createFieldTitles(t); const isSmtpField = config.group === "email" && config.key !== "smtpEnabled"; const isDisabled = isSmtpField && smtpEnabled === "false"; @@ -44,25 +44,14 @@ export function SettingsInput({ config, register, watch, error, smtpEnabled }: C switch (config.type) { case "boolean": return ( - + + + ); case "number": @@ -72,15 +61,9 @@ export function SettingsInput({ config, register, watch, error, smtpEnabled }: C {...register(`configs.${config.key}`, { valueAsNumber: true, })} - classNames={{ - label: "font-semibold", - }} - errorMessage={error?.message} - isDisabled={isDisabled} - isInvalid={!!error} - label={friendlyLabel} - labelPlacement="outside" - size="md" + className="w-full" + disabled={isDisabled} + aria-invalid={!!error} type="number" /> ); @@ -90,15 +73,9 @@ export function SettingsInput({ config, register, watch, error, smtpEnabled }: C return ( ); diff --git a/apps/web/src/pages/settings/constants.ts b/apps/web/src/app/settings/constants.ts similarity index 85% rename from apps/web/src/pages/settings/constants.ts rename to apps/web/src/app/settings/constants.ts index 889650a..fedf335 100644 --- a/apps/web/src/pages/settings/constants.ts +++ b/apps/web/src/app/settings/constants.ts @@ -1,30 +1,30 @@ -import { TFunction } from "i18next"; -import { FaEnvelope, FaCog, FaShieldAlt, FaDatabase } from "react-icons/fa"; +import { IconDatabase, IconMail, IconSettings, IconShield } from "@tabler/icons-react"; +import { createTranslator } from "next-intl"; -export const createGroupMetadata = (t: TFunction) => ({ +export const createGroupMetadata = (t: ReturnType) => ({ email: { title: t("settings.groups.email.title"), description: t("settings.groups.email.description"), - icon: FaEnvelope, + icon: IconMail, }, general: { title: t("settings.groups.general.title"), description: t("settings.groups.general.description"), - icon: FaCog, + icon: IconSettings, }, security: { title: t("settings.groups.security.title"), description: t("settings.groups.security.description"), - icon: FaShieldAlt, + icon: IconShield, }, storage: { title: t("settings.groups.storage.title"), description: t("settings.groups.storage.description"), - icon: FaDatabase, + icon: IconDatabase, }, }); -export const createFieldDescriptions = (t: TFunction) => ({ +export const createFieldDescriptions = (t: ReturnType) => ({ // General settings appLogo: t("settings.fields.appLogo.description"), appName: t("settings.fields.appName.description"), @@ -51,7 +51,7 @@ export const createFieldDescriptions = (t: TFunction) => ({ maxTotalStoragePerUser: t("settings.fields.maxTotalStoragePerUser.description"), }); -export const createFieldTitles = (t: TFunction) => ({ +export const createFieldTitles = (t: ReturnType) => ({ // General settings appLogo: t("settings.fields.appLogo.title"), appName: t("settings.fields.appName.title"), diff --git a/apps/web/src/pages/settings/hooks/use-settings.ts b/apps/web/src/app/settings/hooks/use-settings.ts similarity index 86% rename from apps/web/src/pages/settings/hooks/use-settings.ts rename to apps/web/src/app/settings/hooks/use-settings.ts index 7e4078f..bd52167 100644 --- a/apps/web/src/pages/settings/hooks/use-settings.ts +++ b/apps/web/src/app/settings/hooks/use-settings.ts @@ -1,28 +1,25 @@ -import { ConfigType, GroupFormData } from "../types"; -import { Config } from "../types"; -import { useShareContext } from "@/contexts/ShareContext"; -import { useAppInfo } from "@/contexts/app-info-context"; -import { getAllConfigs, bulkUpdateConfigs } from "@/http/endpoints"; -import { zodResolver } from "@hookform/resolvers/zod"; +"use client"; + import { useEffect, useState } from "react"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { useTranslations } from "next-intl"; import { useForm } from "react-hook-form"; -import { useTranslation } from "react-i18next"; import { toast } from "sonner"; import { z } from "zod"; +import { useAppInfo } from "@/contexts/app-info-context"; +import { useShareContext } from "@/contexts/share-context"; +import { bulkUpdateConfigs, getAllConfigs } from "@/http/endpoints"; +import { Config, ConfigType, GroupFormData } from "../types"; + const createSchemas = () => ({ settingsSchema: z.object({ - configs: z.record( - z - .string() - .or(z.number()) - .transform((val) => String(val)) - ), + configs: z.record(z.union([z.string(), z.number()]).transform((val) => String(val))), }), }); export function useSettings() { - const { t } = useTranslation(); + const t = useTranslations(); const { settingsSchema } = createSchemas(); const [isLoading, setIsLoading] = useState(true); const [configs, setConfigs] = useState>({}); @@ -64,21 +61,17 @@ export function useSettings() { type: (config.type as ConfigType) || "text", }); - // Sort configs by key to maintain consistent order acc[group].sort((a, b) => { - // Para o grupo general, coloca appLogo primeiro if (group === "general") { if (a.key === "appLogo") return -1; if (b.key === "appLogo") return 1; } - // Para o grupo email, coloca smtpEnabled primeiro if (group === "email") { if (a.key === "smtpEnabled") return -1; if (b.key === "smtpEnabled") return 1; } - // Ordenação padrão alfabética para os demais casos return a.key.localeCompare(b.key); }); diff --git a/apps/web/src/app/settings/layout.tsx b/apps/web/src/app/settings/layout.tsx new file mode 100644 index 0000000..ab70efe --- /dev/null +++ b/apps/web/src/app/settings/layout.tsx @@ -0,0 +1,18 @@ +import { Metadata } from "next"; +import { getTranslations } from "next-intl/server"; + +interface LayoutProps { + children: React.ReactNode; +} + +export async function generateMetadata(): Promise { + const t = await getTranslations(); + + return { + title: `${t("settings.pageTitle")}`, + }; +} + +export default function SettingsLayout({ children }: LayoutProps) { + return <>{children}; +} diff --git a/apps/web/src/app/settings/page.tsx b/apps/web/src/app/settings/page.tsx new file mode 100644 index 0000000..b07a365 --- /dev/null +++ b/apps/web/src/app/settings/page.tsx @@ -0,0 +1,38 @@ +"use client"; + +import { ProtectedRoute } from "@/components/auth/protected-route"; +import { LoadingScreen } from "@/components/layout/loading-screen"; +import { Navbar } from "@/components/layout/navbar"; +import { DefaultFooter } from "@/components/ui/default-footer"; +import { SettingsForm } from "./components/settings-form"; +import { SettingsHeader } from "./components/settings-header"; +import { useSettings } from "./hooks/use-settings"; + +export default function SettingsPage() { + const settings = useSettings(); + + if (settings.isLoading) { + return ; + } + + return ( + +
    + +
    +
    + + +
    +
    + +
    +
    + ); +} diff --git a/apps/web/src/pages/settings/types/index.ts b/apps/web/src/app/settings/types/index.ts similarity index 95% rename from apps/web/src/pages/settings/types/index.ts rename to apps/web/src/app/settings/types/index.ts index afa808d..b3cd9c8 100644 --- a/apps/web/src/pages/settings/types/index.ts +++ b/apps/web/src/app/settings/types/index.ts @@ -29,7 +29,7 @@ export interface ConfigInputProps { } export type GroupFormData = { - configs: Record; + configs: Record; }; export type ConfigType = "text" | "number" | "boolean" | "bigint"; diff --git a/apps/web/src/app/users-management/components/user-actions-dropdown.tsx b/apps/web/src/app/users-management/components/user-actions-dropdown.tsx new file mode 100644 index 0000000..7fd42f0 --- /dev/null +++ b/apps/web/src/app/users-management/components/user-actions-dropdown.tsx @@ -0,0 +1,45 @@ +import { IconBan, IconCheck, IconDotsVertical, IconEdit, IconTrash } from "@tabler/icons-react"; +import { useTranslations } from "next-intl"; + +import { Button } from "@/components/ui/button"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu"; +import { UserActionsDropdownProps } from "../types"; + +export function UserActionsDropdown({ + user, + isCurrentUser, + onEdit, + onDelete, + onToggleStatus, +}: UserActionsDropdownProps) { + const t = useTranslations(); + + return ( + + + + + + onEdit(user)}> + + {t("users.actions.edit")} + + onToggleStatus(user)}> + {user.isActive ? : } + {user.isActive ? t("users.actions.deactivate") : t("users.actions.activate")} + + onDelete(user)} className="text-destructive"> + + {t("users.actions.delete")} + + + + ); +} diff --git a/apps/web/src/app/users-management/components/user-delete-modal.tsx b/apps/web/src/app/users-management/components/user-delete-modal.tsx new file mode 100644 index 0000000..794a861 --- /dev/null +++ b/apps/web/src/app/users-management/components/user-delete-modal.tsx @@ -0,0 +1,35 @@ +import { useTranslations } from "next-intl"; + +import { Button } from "@/components/ui/button"; +import { Dialog, DialogContent, DialogFooter, DialogHeader } from "@/components/ui/dialog"; +import { UserDeleteModalProps } from "../types"; + +export function UserDeleteModal({ isOpen, onClose, user, onConfirm }: UserDeleteModalProps) { + const t = useTranslations(); + + return ( + + + {t("users.delete.title")} +
    + {user && ( +

    + {t("users.delete.confirmation", { + firstName: user.firstName, + lastName: user.lastName, + })} +

    + )} +
    + + + + +
    +
    + ); +} diff --git a/apps/web/src/app/users-management/components/user-form-modal.tsx b/apps/web/src/app/users-management/components/user-form-modal.tsx new file mode 100644 index 0000000..c7cb355 --- /dev/null +++ b/apps/web/src/app/users-management/components/user-form-modal.tsx @@ -0,0 +1,109 @@ +import { IconDeviceFloppy } from "@tabler/icons-react"; +import { useTranslations } from "next-intl"; + +import { Button } from "@/components/ui/button"; +import { Dialog, DialogContent, DialogFooter, DialogHeader } from "@/components/ui/dialog"; +import { Form, FormField, FormItem, FormMessage } from "@/components/ui/form"; +import { Input } from "@/components/ui/input"; +import { Label } from "@/components/ui/label"; +import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; +import { UserFormModalProps } from "../types"; + +export function UserFormModal({ isOpen, onClose, modalMode, selectedUser, formMethods, onSubmit }: UserFormModalProps) { + const t = useTranslations(); + const { + register, + formState: { errors, isSubmitting }, + control, + } = formMethods; + + return ( + + +
    + + + {modalMode === "create" ? t("users.form.titleCreate") : t("users.form.titleEdit")} + +
    +
    +
    + ( + + + + {errors.firstName && {errors.firstName.message}} + + )} + /> + ( + + + + {errors.lastName && {errors.lastName.message}} + + )} + /> +
    + +
    + + + {errors.username && {errors.username.message}} +
    + +
    + + + {errors.email && {errors.email.message}} +
    + +
    + + + {errors.password && {errors.password.message}} +
    + + {modalMode === "edit" && ( +
    + + + {errors.isAdmin && {errors.isAdmin.message}} +
    + )} +
    +
    + + + + +
    + +
    +
    + ); +} diff --git a/apps/web/src/pages/users-management/components/user-management-modals.tsx b/apps/web/src/app/users-management/components/user-management-modals.tsx similarity index 100% rename from apps/web/src/pages/users-management/components/user-management-modals.tsx rename to apps/web/src/app/users-management/components/user-management-modals.tsx diff --git a/apps/web/src/pages/users-management/components/user-status-modal.tsx b/apps/web/src/app/users-management/components/user-status-modal.tsx similarity index 50% rename from apps/web/src/pages/users-management/components/user-status-modal.tsx rename to apps/web/src/app/users-management/components/user-status-modal.tsx index 81284cb..6c1ae84 100644 --- a/apps/web/src/pages/users-management/components/user-status-modal.tsx +++ b/apps/web/src/app/users-management/components/user-status-modal.tsx @@ -1,16 +1,17 @@ +import { useTranslations } from "next-intl"; + +import { Button } from "@/components/ui/button"; +import { Dialog, DialogContent, DialogFooter, DialogHeader } from "@/components/ui/dialog"; import { UserStatusModalProps } from "../types"; -import { Button } from "@heroui/button"; -import { Modal, ModalContent, ModalHeader, ModalBody, ModalFooter } from "@heroui/modal"; -import { useTranslation } from "react-i18next"; export function UserStatusModal({ isOpen, onClose, user, onConfirm }: UserStatusModalProps) { - const { t } = useTranslation(); + const t = useTranslations(); return ( - - - {t("users.status.title")} - + + + {t("users.status.title")} +
    {user && (

    {t("users.status.confirmation", { @@ -20,16 +21,16 @@ export function UserStatusModal({ isOpen, onClose, user, onConfirm }: UserStatus })}

    )} - - -
    + + - - -
    -
    + + + ); } diff --git a/apps/web/src/app/users-management/components/users-header.tsx b/apps/web/src/app/users-management/components/users-header.tsx new file mode 100644 index 0000000..8cd2131 --- /dev/null +++ b/apps/web/src/app/users-management/components/users-header.tsx @@ -0,0 +1,52 @@ +import Link from "next/link"; +import { IconLayoutDashboard, IconUserPlus, IconUsers } from "@tabler/icons-react"; +import { useTranslations } from "next-intl"; + +import { + Breadcrumb, + BreadcrumbItem, + BreadcrumbLink, + BreadcrumbList, + BreadcrumbSeparator, +} from "@/components/ui/breadcrumb"; +import { Button } from "@/components/ui/button"; +import { Separator } from "@/components/ui/separator"; +import { UsersHeaderProps } from "../types"; + +export function UsersHeader({ onCreateUser }: UsersHeaderProps) { + const t = useTranslations(); + + return ( +
    +
    +
    + +

    {t("users.header.title")}

    +
    + +
    + + + + + + + + {t("common.dashboard")} + + + + + + + {t("users.header.management")} + + + + +
    + ); +} diff --git a/apps/web/src/app/users-management/components/users-table.tsx b/apps/web/src/app/users-management/components/users-table.tsx new file mode 100644 index 0000000..d240884 --- /dev/null +++ b/apps/web/src/app/users-management/components/users-table.tsx @@ -0,0 +1,78 @@ +import { useTranslations } from "next-intl"; + +import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; +import { Badge } from "@/components/ui/badge"; +import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"; +import { UsersTableProps } from "../types"; +import { UserActionsDropdown } from "./user-actions-dropdown"; + +export function UsersTable({ users, currentUser, onEdit, onDelete, onToggleStatus }: UsersTableProps) { + const t = useTranslations(); + const isCurrentUser = (userId: string) => currentUser?.id === userId; + + return ( +
    + + + + + {t("users.table.user")} + + + {t("users.table.email")} + + + {t("users.table.status")} + + + {t("users.table.role")} + + + {t("users.table.actions")} + + + + + {users.map((user) => ( + + +
    + + + + {user.firstName[0]} + + +
    +

    {`${user.firstName} ${user.lastName}`}

    +

    {user.username}

    +
    +
    +
    + {user.email} + + + {user.isActive ? t("users.table.active") : t("users.table.inactive")} + + + + + {user.isAdmin ? t("users.table.admin") : t("users.table.userr")} + + + + + +
    + ))} +
    +
    +
    + ); +} diff --git a/apps/web/src/pages/users-management/hooks/use-user-management.ts b/apps/web/src/app/users-management/hooks/use-user-management.ts similarity index 91% rename from apps/web/src/pages/users-management/hooks/use-user-management.ts rename to apps/web/src/app/users-management/hooks/use-user-management.ts index b58cc93..2936334 100644 --- a/apps/web/src/pages/users-management/hooks/use-user-management.ts +++ b/apps/web/src/app/users-management/hooks/use-user-management.ts @@ -1,16 +1,18 @@ -import { useAuth } from "@/contexts/auth-context"; -import { listUsers, registerUser, updateUser, deleteUser, activateUser, deactivateUser } from "@/http/endpoints"; -import type { ListUsers200Item } from "@/http/models"; -import { useDisclosure } from "@heroui/modal"; -import { zodResolver } from "@hookform/resolvers/zod"; -import { TFunction } from "i18next"; +"use client"; + import { useEffect, useState } from "react"; -import { useForm } from "react-hook-form"; -import { useTranslation } from "react-i18next"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { useTranslations } from "next-intl"; +import { Resolver, useForm } from "react-hook-form"; import { toast } from "sonner"; import { z } from "zod"; -const createSchemas = (t: TFunction) => ({ +import { useAuth } from "@/contexts/auth-context"; +import { useDisclosure } from "@/hooks/use-disclosure"; +import { activateUser, deactivateUser, deleteUser, listUsers, registerUser, updateUser } from "@/http/endpoints"; +import type { ListUsers200Item } from "@/http/models"; + +const createSchemas = (t: (key: string) => string) => ({ userSchema: z.object({ firstName: z.string().min(1, t("validation.firstNameRequired")), lastName: z.string().min(1, t("validation.lastNameRequired")), @@ -30,7 +32,8 @@ const createSchemas = (t: TFunction) => ({ export type UserFormData = z.infer["userSchema"]>; export function useUserManagement() { - const { t } = useTranslation(); + const t = useTranslations(); + const { userSchema } = createSchemas(t); const [users, setUsers] = useState([]); const [isLoading, setIsLoading] = useState(true); @@ -45,7 +48,7 @@ export function useUserManagement() { const { isOpen: isStatusModalOpen, onOpen: onStatusModalOpen, onClose: onStatusModalClose } = useDisclosure(); const formMethods = useForm({ - resolver: zodResolver(userSchema), + resolver: zodResolver(userSchema) as Resolver, }); const loadUsers = async () => { diff --git a/apps/web/src/app/users-management/layout.tsx b/apps/web/src/app/users-management/layout.tsx new file mode 100644 index 0000000..3589f79 --- /dev/null +++ b/apps/web/src/app/users-management/layout.tsx @@ -0,0 +1,18 @@ +import { Metadata } from "next"; +import { getTranslations } from "next-intl/server"; + +interface LayoutProps { + children: React.ReactNode; +} + +export async function generateMetadata(): Promise { + const t = await getTranslations(); + + return { + title: `${t("settings.pageTitle")} `, + }; +} + +export default function UsersManagementLayout({ children }: LayoutProps) { + return <>{children}; +} diff --git a/apps/web/src/app/users-management/page.tsx b/apps/web/src/app/users-management/page.tsx new file mode 100644 index 0000000..3346e50 --- /dev/null +++ b/apps/web/src/app/users-management/page.tsx @@ -0,0 +1,71 @@ +"use client"; + +import { ProtectedRoute } from "@/components/auth/protected-route"; +import { LoadingScreen } from "@/components/layout/loading-screen"; +import { Navbar } from "@/components/layout/navbar"; +import { DefaultFooter } from "@/components/ui/default-footer"; +import { UserManagementModals } from "./components/user-management-modals"; +import { UsersHeader } from "./components/users-header"; +import { UsersTable } from "./components/users-table"; +import { useUserManagement } from "./hooks/use-user-management"; + +export default function AdminAreaPage() { + const { + users, + isLoading, + currentUser, + modals, + selectedUser, + deleteModalUser, + statusModalUser, + handleCreateUser, + handleEditUser, + handleDeleteUser, + handleToggleUserStatus, + onSubmit, + formMethods, + } = useUserManagement(); + + if (isLoading) { + return ; + } + + return ( + +
    + +
    +
    + + + { + modals.setDeleteModalUser(user); + modals.onDeleteModalOpen(); + }} + onEdit={handleEditUser} + onToggleStatus={(user) => { + modals.setStatusModalUser(user); + modals.onStatusModalOpen(); + }} + /> +
    +
    + + + +
    +
    + ); +} diff --git a/apps/web/src/pages/users-management/types/index.ts b/apps/web/src/app/users-management/types/index.ts similarity index 99% rename from apps/web/src/pages/users-management/types/index.ts rename to apps/web/src/app/users-management/types/index.ts index 05cc83c..aff551d 100644 --- a/apps/web/src/pages/users-management/types/index.ts +++ b/apps/web/src/app/users-management/types/index.ts @@ -1,7 +1,8 @@ -import { UserFormData } from "../hooks/use-user-management"; -import type { ListUsers200Item } from "@/http/models"; import { UseFormReturn } from "react-hook-form"; +import type { ListUsers200Item } from "@/http/models"; +import { UserFormData } from "../hooks/use-user-management"; + export interface UserActionsDropdownProps { user: ListUsers200Item; isCurrentUser: boolean; diff --git a/apps/web/src/components/auth/protected-route.tsx b/apps/web/src/components/auth/protected-route.tsx new file mode 100644 index 0000000..3509344 --- /dev/null +++ b/apps/web/src/components/auth/protected-route.tsx @@ -0,0 +1,35 @@ +"use client"; + +import { useEffect, type ReactNode } from "react"; +import { useRouter } from "next/navigation"; + +import { useAuth } from "@/contexts/auth-context"; +import { LoadingScreen } from "../layout/loading-screen"; + +type ProtectedRouteProps = { + children: ReactNode; + requireAdmin?: boolean; +}; + +export function ProtectedRoute({ children, requireAdmin = false }: ProtectedRouteProps) { + const { isAuthenticated, isAdmin } = useAuth(); + const router = useRouter(); + + useEffect(() => { + if (isAuthenticated === false) { + router.replace("/login"); + } else if (requireAdmin && isAdmin === false) { + router.replace("/dashboard"); + } + }, [isAuthenticated, isAdmin, requireAdmin, router]); + + if (isAuthenticated === null || (requireAdmin && isAdmin === null)) { + return ; + } + + if (!isAuthenticated || (requireAdmin && !isAdmin)) { + return null; + } + + return <>{children}; +} diff --git a/apps/web/src/components/general/file-selector.tsx b/apps/web/src/components/general/file-selector.tsx index ca5dff5..5ead35d 100644 --- a/apps/web/src/components/general/file-selector.tsx +++ b/apps/web/src/components/general/file-selector.tsx @@ -1,10 +1,14 @@ -import { addFiles, listFiles, removeFiles } from "@/http/endpoints"; -import { Button } from "@heroui/button"; +"use client"; + import { useEffect, useState } from "react"; -import { useTranslation } from "react-i18next"; -import { FaArrowLeft, FaArrowRight, FaFile } from "react-icons/fa"; +import { IconArrowLeft, IconArrowRight, IconFile } from "@tabler/icons-react"; +import { useTranslations } from "next-intl"; import { toast } from "sonner"; +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import { addFiles, listFiles, removeFiles } from "@/http/endpoints"; + interface FileSelectorProps { shareId: string; selectedFiles: string[]; @@ -12,7 +16,7 @@ interface FileSelectorProps { } export function FileSelector({ shareId, selectedFiles, onSave }: FileSelectorProps) { - const { t } = useTranslation(); + const t = useTranslations(); const [availableFiles, setAvailableFiles] = useState([]); const [shareFiles, setShareFiles] = useState([]); const [isLoading, setIsLoading] = useState(false); @@ -94,8 +98,8 @@ export function FileSelector({ shareId, selectedFiles, onSave }: FileSelectorPro

    {t("fileSelector.availableFiles", { count: filteredAvailableFiles.length })}

    - moveToShare(file.id)} >
    - + {file.name}
    - +
    ))}
    @@ -132,8 +136,8 @@ export function FileSelector({ shareId, selectedFiles, onSave }: FileSelectorPro

    {t("fileSelector.shareFiles", { count: filteredShareFiles.length })}

    - removeFromShare(file.id)} >
    - + {file.name}
    - +
    ))}
    @@ -169,8 +173,15 @@ export function FileSelector({ shareId, selectedFiles, onSave }: FileSelectorPro
    -
    diff --git a/apps/web/src/components/general/language-switcher.tsx b/apps/web/src/components/general/language-switcher.tsx index d09dab9..f95443f 100644 --- a/apps/web/src/components/general/language-switcher.tsx +++ b/apps/web/src/components/general/language-switcher.tsx @@ -1,8 +1,18 @@ -import { Button } from "@heroui/button"; -import { Dropdown, DropdownTrigger, DropdownMenu, DropdownItem } from "@heroui/dropdown"; +"use client"; + +import { useRouter } from "next/navigation"; +import { IconLanguage } from "@tabler/icons-react"; +import { useLocale } from "next-intl"; +import { setCookie } from "nookies"; import ReactCountryFlag from "react-country-flag"; -import { useTranslation } from "react-i18next"; -import { FaGlobe } from "react-icons/fa"; + +import { Button } from "@/components/ui/button"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu"; const languages = { "en-US": "English", @@ -19,36 +29,61 @@ const languages = { "ko-KR": "한국어 (Korean)", }; -export function LanguageSwitcher() { - const { i18n } = useTranslation(); +const COOKIE_LANG_KEY = "NEXT_LOCALE"; +const COOKIE_MAX_AGE = 365 * 24 * 60 * 60; - const changeLanguage = (lng: string) => { - i18n.changeLanguage(lng); +const RTL_LANGUAGES = ["ar-SA"]; + +export function LanguageSwitcher() { + const locale = useLocale(); + const router = useRouter(); + + const changeLanguage = (fullLocale: string) => { + const isRTL = RTL_LANGUAGES.includes(fullLocale); + document.documentElement.dir = isRTL ? "rtl" : "ltr"; + + setCookie(null, COOKIE_LANG_KEY, fullLocale, { + maxAge: COOKIE_MAX_AGE, + path: "/", + sameSite: "lax", + secure: process.env.NODE_ENV === "production", + }); + + router.refresh(); }; return ( - - - - - - {Object.entries(languages).map(([code, name]) => ( - changeLanguage(code)}> - - {name} - - ))} - - + + + {Object.entries(languages).map(([code, name]) => { + const isCurrentLocale = locale === code.split("-")[0]; + + return ( + changeLanguage(code)} + className={isCurrentLocale ? "bg-accent" : ""} + > + + {name} + + ); + })} + + ); } diff --git a/apps/web/src/components/general/mode-toggle.tsx b/apps/web/src/components/general/mode-toggle.tsx new file mode 100644 index 0000000..29df760 --- /dev/null +++ b/apps/web/src/components/general/mode-toggle.tsx @@ -0,0 +1,36 @@ +"use client"; + +import * as React from "react"; +import { IconMoon, IconSun } from "@tabler/icons-react"; +import { useTranslations } from "next-intl"; +import { useTheme } from "next-themes"; + +import { Button } from "@/components/ui/button"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu"; + +export function ModeToggle() { + const { setTheme } = useTheme(); + const t = useTranslations(); + + return ( + + + + + + setTheme("light")}>{t("theme.light")} + setTheme("dark")}>{t("theme.dark")} + setTheme("system")}>{t("theme.system")} + + + ); +} diff --git a/apps/web/src/components/general/recipient-selector.tsx b/apps/web/src/components/general/recipient-selector.tsx index 6aacaf5..8e83029 100644 --- a/apps/web/src/components/general/recipient-selector.tsx +++ b/apps/web/src/components/general/recipient-selector.tsx @@ -1,12 +1,15 @@ -import { useShareContext } from "@/contexts/ShareContext"; -import { addRecipients, removeRecipients, notifyRecipients } from "@/http/endpoints"; -import { Button } from "@heroui/button"; -import { Input } from "@heroui/input"; -import { useState, useEffect } from "react"; -import { useTranslation } from "react-i18next"; -import { FaPlus, FaTrash, FaEnvelope, FaBell } from "react-icons/fa"; +"use client"; + +import { useEffect, useState } from "react"; +import { IconBell, IconMail, IconPlus, IconTrash } from "@tabler/icons-react"; +import { useTranslations } from "next-intl"; import { toast } from "sonner"; +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import { useShareContext } from "@/contexts/share-context"; +import { addRecipients, notifyRecipients, removeRecipients } from "@/http/endpoints"; + interface Recipient { id: string; email: string; @@ -22,7 +25,7 @@ interface RecipientSelectorProps { } export function RecipientSelector({ shareId, selectedRecipients, shareAlias, onSuccess }: RecipientSelectorProps) { - const { t } = useTranslation(); + const t = useTranslations(); const { smtpEnabled } = useShareContext(); const [recipients, setRecipients] = useState(selectedRecipients?.map((recipient) => recipient.email) || []); const [newRecipient, setNewRecipient] = useState(""); @@ -78,14 +81,18 @@ export function RecipientSelector({ shareId, selectedRecipients, shareAlias, onS return (
    - } - value={newRecipient} - onChange={(e) => setNewRecipient(e.target.value)} - onKeyPress={(e) => e.key === "Enter" && handleAddRecipient()} - /> -
    @@ -94,7 +101,8 @@ export function RecipientSelector({ shareId, selectedRecipients, shareAlias, onS

    {t("recipientSelector.recipients", { count: recipients.length })}

    {recipients.length > 0 && shareAlias && smtpEnabled === "true" && ( - )} @@ -107,20 +115,19 @@ export function RecipientSelector({ shareId, selectedRecipients, shareAlias, onS recipients.map((email, index) => (
    - + {email}
    )) diff --git a/apps/web/src/components/general/theme-switch.tsx b/apps/web/src/components/general/theme-switch.tsx deleted file mode 100644 index a5e156b..0000000 --- a/apps/web/src/components/general/theme-switch.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import { useTheme } from "@/hooks/use-theme"; -import { Button } from "@heroui/button"; -import { FC, useEffect, useState } from "react"; -import { BsMoonFill, BsSunFill } from "react-icons/bs"; - -export const ThemeSwitch: FC = () => { - const [isMounted, setIsMounted] = useState(false); - const { theme, toggleTheme } = useTheme(); - const isDark = theme === "dark"; - - useEffect(() => { - setIsMounted(true); - }, []); - - if (!isMounted) return
    ; - - return ( - - ); -}; diff --git a/apps/web/src/components/layout/favicon.tsx b/apps/web/src/components/layout/favicon.tsx new file mode 100644 index 0000000..ed38e35 --- /dev/null +++ b/apps/web/src/components/layout/favicon.tsx @@ -0,0 +1,14 @@ +"use client"; + +import { useAppInfo } from "@/contexts/app-info-context"; + +export function Favicon() { + const { appLogo } = useAppInfo(); + + return ( + <> + + + + ); +} diff --git a/apps/web/src/components/layout/file-manager-layout.tsx b/apps/web/src/components/layout/file-manager-layout.tsx index ca1d88b..7f1c964 100644 --- a/apps/web/src/components/layout/file-manager-layout.tsx +++ b/apps/web/src/components/layout/file-manager-layout.tsx @@ -1,10 +1,18 @@ -import { Navbar } from "@/components/layout/navbar"; -import { DefaultFooter } from "@/components/ui/default-footer"; -import { Breadcrumbs, BreadcrumbItem } from "@heroui/breadcrumbs"; -import { Divider } from "@heroui/divider"; import { ReactNode } from "react"; -import { useTranslation } from "react-i18next"; -import { TbLayoutDashboardFilled } from "react-icons/tb"; +import Link from "next/link"; +import { IconLayoutDashboard } from "@tabler/icons-react"; +import { useTranslations } from "next-intl"; + +import { Navbar } from "@/components/layout/navbar"; +import { + Breadcrumb, + BreadcrumbItem, + BreadcrumbLink, + BreadcrumbList, + BreadcrumbSeparator, +} from "@/components/ui/breadcrumb"; +import { DefaultFooter } from "@/components/ui/default-footer"; +import { Separator } from "@/components/ui/separator"; interface FileManagerLayoutProps { children: ReactNode; @@ -21,7 +29,7 @@ export function FileManagerLayout({ breadcrumbLabel, showBreadcrumb = true, }: FileManagerLayoutProps) { - const { t } = useTranslation(); + const t = useTranslations(); return (
    @@ -33,17 +41,26 @@ export function FileManagerLayout({ {icon}

    {title}

    - + {showBreadcrumb && breadcrumbLabel && ( - - - - {t("navigation.dashboard")} - - - {icon} {breadcrumbLabel} - - + + + + + + + {t("navigation.dashboard")} + + + + + + + {icon} {breadcrumbLabel} + + + + )}
    diff --git a/apps/web/src/components/layout/loading-screen.tsx b/apps/web/src/components/layout/loading-screen.tsx index 65793c4..cc8cf32 100644 --- a/apps/web/src/components/layout/loading-screen.tsx +++ b/apps/web/src/components/layout/loading-screen.tsx @@ -1,14 +1,13 @@ -import { GridPattern } from "@/components/ui/grid-pattern"; -import { BackgroundLights } from "@/pages/home/components/background-lights"; import { motion } from "framer-motion"; -import { useTranslation } from "react-i18next"; +import { useTranslations } from "next-intl"; + +import { BackgroundLights } from "@/components/ui/background-lights"; export function LoadingScreen() { - const { t } = useTranslation(); + const t = useTranslations(); return (
    -
    { try { await logoutAPI(); logout(); - navigate("/login"); + router.push("/login"); } catch (err) { console.error("Error logging out:", err); } }; return ( - - - - - {appLogo && {t("navbar.logoAlt")}} -

    {appName}

    - -
    -
    +
    +
    +
    +
    + + {appLogo && {t("navbar.logoAlt")}} +

    {appName}

    + +
    - - - - - - - - - - - -

    - {user?.firstName} {user?.lastName} -

    -

    {user?.email}

    -
    - - - - {t("navbar.profile")} - - - {isAdmin ? ( - - - - {t("navbar.settings")} +
    + + + + + + + {user?.firstName?.[0]} + + + +
    +

    + {user?.firstName} {user?.lastName} +

    +

    {user?.email}

    +
    + + + + {t("navbar.profile")} - - ) : null} - {isAdmin ? ( - - - - {t("navbar.usersManagement")} - - - ) : null} - - - + +
    - - - - +
    +
    +
    +
    ); } diff --git a/apps/web/src/components/layout/share-manager-layout.tsx b/apps/web/src/components/layout/share-manager-layout.tsx deleted file mode 100644 index c5b91b8..0000000 --- a/apps/web/src/components/layout/share-manager-layout.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import { Breadcrumbs, BreadcrumbItem } from "@heroui/breadcrumbs"; -import { ReactNode } from "react"; -import { useTranslation } from "react-i18next"; -import { TbLayoutDashboardFilled } from "react-icons/tb"; - -interface ShareManagerLayoutProps { - children: ReactNode; - icon: ReactNode; - title: string; - breadcrumbLabel: string; -} - -export function ShareManagerLayout({ children, icon, title, breadcrumbLabel }: ShareManagerLayoutProps) { - const { t } = useTranslation(); - - return ( -
    -
    - - - - {t("navigation.dashboard")} - - - {icon} {breadcrumbLabel} - - -
    - {icon} -

    {title}

    -
    -
    - {children} -
    - ); -} diff --git a/apps/web/src/components/modals/create-share-modal.tsx b/apps/web/src/components/modals/create-share-modal.tsx index e2c1842..47627fd 100644 --- a/apps/web/src/components/modals/create-share-modal.tsx +++ b/apps/web/src/components/modals/create-share-modal.tsx @@ -1,12 +1,17 @@ -import { createShare } from "@/http/endpoints"; -import { Button } from "@heroui/button"; -import { Input } from "@heroui/input"; -import { Modal, ModalBody, ModalContent, ModalFooter, ModalHeader } from "@heroui/modal"; -import { Switch } from "@heroui/switch"; +"use client"; + import { useState } from "react"; -import { useTranslation } from "react-i18next"; +import { IconCalendar, IconEye, IconLock, IconShare } from "@tabler/icons-react"; +import { useTranslations } from "next-intl"; import { toast } from "sonner"; +import { Button } from "@/components/ui/button"; +import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from "@/components/ui/dialog"; +import { Input } from "@/components/ui/input"; +import { Label } from "@/components/ui/label"; +import { Switch } from "@/components/ui/switch"; +import { createShare } from "@/http/endpoints"; + interface CreateShareModalProps { isOpen: boolean; onClose: () => void; @@ -14,7 +19,7 @@ interface CreateShareModalProps { } export function CreateShareModal({ isOpen, onClose, onSuccess }: CreateShareModalProps) { - const { t } = useTranslation(); + const t = useTranslations(); const [formData, setFormData] = useState({ name: "", password: "", @@ -53,64 +58,85 @@ export function CreateShareModal({ isOpen, onClose, onSuccess }: CreateShareModa }; return ( - - - {t("createShare.title")} - -
    + + + + + + {t("createShare.title")} + + +
    +
    + + setFormData({ ...formData, name: e.target.value })} /> +
    + +
    + setFormData({ ...formData, name: e.target.value })} - /> - setFormData({ ...formData, expiresAt: e.target.value })} /> +
    + +
    + setFormData({ ...formData, maxViews: e.target.value })} /> -
    - - setFormData({ - ...formData, - isPasswordProtected: checked, - password: "", - }) - } - > - {t("createShare.passwordProtection")} - -
    - {formData.isPasswordProtected && ( +
    + +
    + + setFormData({ + ...formData, + isPasswordProtected: checked, + password: "", + }) + } + id="password-protection" + /> + +
    + + {formData.isPasswordProtected && ( +
    + setFormData({ ...formData, password: e.target.value })} /> - )} -
    - - -
    + )} +
    + + - - -
    -
    + + + ); } diff --git a/apps/web/src/components/modals/file-actions-modals.tsx b/apps/web/src/components/modals/file-actions-modals.tsx index 5d04c9b..2889622 100644 --- a/apps/web/src/components/modals/file-actions-modals.tsx +++ b/apps/web/src/components/modals/file-actions-modals.tsx @@ -1,7 +1,16 @@ -import { Button } from "@heroui/button"; -import { Input } from "@heroui/input"; -import { Modal, ModalContent, ModalHeader, ModalBody, ModalFooter } from "@heroui/modal"; -import { useTranslation } from "react-i18next"; +import { IconEdit, IconTrash } from "@tabler/icons-react"; +import { useTranslations } from "next-intl"; + +import { Button } from "@/components/ui/button"; +import { + Dialog, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, +} from "@/components/ui/dialog"; +import { Input } from "@/components/ui/input"; interface FileActionsModalsProps { fileToRename: { id: string; name: string; description?: string } | null; @@ -20,7 +29,7 @@ export function FileActionsModals({ onCloseRename, onCloseDelete, }: FileActionsModalsProps) { - const { t } = useTranslation(); + const t = useTranslations(); const splitFileName = (fullName: string) => { const lastDotIndex = fullName.lastIndexOf("."); @@ -35,44 +44,43 @@ export function FileActionsModals({ return ( <> - - - {t("fileActions.editFile")} - - {fileToRename && ( -
    -
    - { - if (e.key === "Enter" && fileToRename) { - const newName = e.currentTarget.value + splitFileName(fileToRename.name).extension; - - onRename(fileToRename.id, newName); - } - }} - /> -

    - {t("fileActions.extension")}: {splitFileName(fileToRename.name).extension} -

    -
    + onCloseRename()}> + + + + + {t("fileActions.editFile")} + + + {fileToRename && ( +
    +
    { + if (e.key === "Enter" && fileToRename) { + const newName = e.currentTarget.value + splitFileName(fileToRename.name).extension; + onRename(fileToRename.id, newName); + } + }} /> +

    + {t("fileActions.extension")}: {splitFileName(fileToRename.name).extension} +

    - )} - - -
    + )} + + - - - + +
    +
    - - - {t("fileActions.deleteFile")} - -

    {t("fileActions.deleteConfirmation", { fileName: fileToDelete?.name })}

    -

    {t("fileActions.deleteWarning")}

    -
    - - - - -
    -
    + + + ); } diff --git a/apps/web/src/components/modals/file-preview-modal.tsx b/apps/web/src/components/modals/file-preview-modal.tsx index c8d414b..56f4360 100644 --- a/apps/web/src/components/modals/file-preview-modal.tsx +++ b/apps/web/src/components/modals/file-preview-modal.tsx @@ -1,13 +1,16 @@ -/* eslint-disable jsx-a11y/media-has-caption */ +"use client"; + +import { useEffect, useState } from "react"; +import { IconDownload } from "@tabler/icons-react"; +import { useTranslations } from "next-intl"; +import { toast } from "sonner"; + +import { AspectRatio } from "@/components/ui/aspect-ratio"; +import { Button } from "@/components/ui/button"; +import { Dialog, DialogContent, DialogFooter, DialogHeader } from "@/components/ui/dialog"; +import { ScrollArea } from "@/components/ui/scroll-area"; import { getDownloadUrl } from "@/http/endpoints"; import { getFileIcon } from "@/utils/file-icons"; -import { Button } from "@heroui/button"; -import { Image } from "@heroui/image"; -import { Modal, ModalContent, ModalHeader, ModalBody, ModalFooter } from "@heroui/modal"; -import { useState, useEffect } from "react"; -import { useTranslation } from "react-i18next"; -import { FaDownload } from "react-icons/fa"; -import { toast } from "sonner"; interface FilePreviewModalProps { isOpen: boolean; @@ -20,7 +23,7 @@ interface FilePreviewModalProps { } export function FilePreviewModal({ isOpen, onClose, file }: FilePreviewModalProps) { - const { t } = useTranslation(); + const t = useTranslations(); const [previewUrl, setPreviewUrl] = useState(null); const [isLoading, setIsLoading] = useState(true); @@ -99,8 +102,8 @@ export function FilePreviewModal({ isOpen, onClose, file }: FilePreviewModalProp if (isLoading) { return (
    -
    -

    {t("filePreview.loading")}

    +
    +

    {t("filePreview.loading")}

    ); } @@ -108,9 +111,9 @@ export function FilePreviewModal({ isOpen, onClose, file }: FilePreviewModalProp if (!previewUrl) { return (
    - -

    {t("filePreview.notAvailable")}

    -

    {t("filePreview.downloadToView")}

    + +

    {t("filePreview.notAvailable")}

    +

    {t("filePreview.downloadToView")}

    ); } @@ -118,26 +121,15 @@ export function FilePreviewModal({ isOpen, onClose, file }: FilePreviewModalProp switch (fileType) { case "pdf": return ( -
    -

    yT_S}%6bd< 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 literal 0 HcmV?d00001 diff --git a/apps/docs/public/assets/v2/api-docs/swagger.png b/apps/docs/public/assets/v2/api-docs/swagger.png new file mode 100644 index 0000000000000000000000000000000000000000..b2374dbd65c97a5064e1c5b708e2d57405f4641a GIT binary patch literal 185853 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�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 N}F} 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 JR;XGA{RfC%j@SSI literal 0 HcmV?d00001 diff --git a/apps/docs/public/assets/v2/general/architecture.png b/apps/docs/public/assets/v2/general/architecture.png new file mode 100644 index 0000000000000000000000000000000000000000..c379fff7960e6df09b1a959c1c537a45a50cac25 GIT binary patch literal 237710 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 C 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