diff --git a/backend/Makefile b/backend/Makefile index 86ab4aa51..97b80d7d1 100644 --- a/backend/Makefile +++ b/backend/Makefile @@ -35,6 +35,7 @@ github-update-project-related-repositories: index-data: @echo "Indexing Nest data" @CMD="poetry run python manage.py algolia_reindex" $(MAKE) exec-backend-command + @CMD="poetry run python manage.py algolia_update_replicas" $(MAKE) exec-backend-command @CMD="poetry run python manage.py algolia_update_synonyms" $(MAKE) exec-backend-command @CMD="poetry run python manage.py algolia_update_suggestions" $(MAKE) exec-backend-command diff --git a/backend/apps/common/index.py b/backend/apps/common/index.py index 71a223e04..81dc41b18 100644 --- a/backend/apps/common/index.py +++ b/backend/apps/common/index.py @@ -20,7 +20,7 @@ class IndexBase: """Nest index synonyms mixin and record count.""" @staticmethod - def _get_client(): + def get_client(): """Get the Algolia client.""" return SearchClientSync( settings.ALGOLIA_APPLICATION_ID, @@ -73,7 +73,7 @@ def reindex_synonyms(app_name, index_name): if not (synonyms := IndexBase._parse_synonyms_file(file_path)): return None - client = IndexBase._get_client() + client = IndexBase.get_client() index_name = f"{settings.ENVIRONMENT.lower()}_{index_name}" try: @@ -91,7 +91,7 @@ def reindex_synonyms(app_name, index_name): @lru_cache(maxsize=1024) def get_total_count(index_name): """Get total count of records in index.""" - client = IndexBase._get_client() + client = IndexBase.get_client() try: return client.search_single_index( index_name=f"{settings.ENVIRONMENT.lower()}_{index_name}", diff --git a/backend/apps/common/management/commands/algolia_update_replicas.py b/backend/apps/common/management/commands/algolia_update_replicas.py new file mode 100644 index 000000000..9da666745 --- /dev/null +++ b/backend/apps/common/management/commands/algolia_update_replicas.py @@ -0,0 +1,14 @@ +"""A command to update OWASP Nest index replicas.""" + +from django.core.management.base import BaseCommand + +from apps.owasp.index.project import ProjectIndex + + +class Command(BaseCommand): + help = "Update OWASP Nest index replicas." + + def handle(self, *_args, **_options): + print("\n Starting replica configuration...") + ProjectIndex.configure_replicas() + print("\n Replica have been Successfully created.") diff --git a/backend/apps/owasp/index/chapter.py b/backend/apps/owasp/index/chapter.py index 041927ba8..372269d6c 100644 --- a/backend/apps/owasp/index/chapter.py +++ b/backend/apps/owasp/index/chapter.py @@ -16,6 +16,7 @@ class ChapterIndex(AlgoliaIndex): fields = ( "idx_country", "idx_created_at", + "idx_is_active", "idx_key", "idx_leaders", "idx_name", diff --git a/backend/apps/owasp/index/project.py b/backend/apps/owasp/index/project.py index bee9eceac..227c1dd30 100644 --- a/backend/apps/owasp/index/project.py +++ b/backend/apps/owasp/index/project.py @@ -2,6 +2,7 @@ from algoliasearch_django import AlgoliaIndex from algoliasearch_django.decorators import register +from django.conf import settings from apps.common.index import IS_LOCAL_BUILD, LOCAL_INDEX_LIMIT, IndexBase from apps.owasp.models.project import Project @@ -21,6 +22,7 @@ class ProjectIndex(AlgoliaIndex, IndexBase): "idx_forks_count", "idx_issues", "idx_issues_count", + "idx_is_active", "idx_key", "idx_languages", "idx_leaders", @@ -92,3 +94,24 @@ def get_queryset(self): def update_synonyms(): """Update synonyms.""" return ProjectIndex.reindex_synonyms("owasp", "projects") + + @staticmethod + def configure_replicas(): + """Configure the settings for project replicas.""" + env = settings.ENVIRONMENT.lower() + client = IndexBase.get_client() + replicas = { + f"{env}_projects_name_asc": ["asc(idx_name)"], + f"{env}_projects_name_desc": ["desc(idx_name)"], + f"{env}_projects_stars_count_asc": ["asc(idx_stars_count)"], + f"{env}_projects_stars_count_desc": ["desc(idx_stars_count)"], + f"{env}_projects_contributors_count_asc": ["asc(idx_contributors_count)"], + f"{env}_projects_contributors_count_desc": ["desc(idx_contributors_count)"], + f"{env}_projects_forks_count_asc": ["asc(idx_forks_count)"], + f"{env}_projects_forks_count_desc": ["desc(idx_forks_count)"], + } + + client.set_settings(f"{env}_projects", {"replicas": list(replicas.keys())}) + + for replica_name, ranking in replicas.items(): + client.set_settings(replica_name, {"ranking": ranking}) diff --git a/backend/apps/owasp/models/chapter.py b/backend/apps/owasp/models/chapter.py index 22217ad8b..9d716b65a 100644 --- a/backend/apps/owasp/models/chapter.py +++ b/backend/apps/owasp/models/chapter.py @@ -72,11 +72,9 @@ def active_chapters_count(): def is_indexable(self): """Chapters to index.""" return ( - self.is_active - and self.latitude is not None + self.latitude is not None and self.longitude is not None and not self.owasp_repository.is_empty - and not self.owasp_repository.is_archived ) def from_github(self, repository): @@ -114,9 +112,6 @@ def generate_geo_location(self): def generate_suggested_location(self, open_ai=None, max_tokens=100): """Generate project summary.""" - if not self.is_active: - return - if not (prompt := Prompt.get_owasp_chapter_suggested_location()): return diff --git a/backend/apps/owasp/models/common.py b/backend/apps/owasp/models/common.py index 7c997aed4..0390d4ee7 100644 --- a/backend/apps/owasp/models/common.py +++ b/backend/apps/owasp/models/common.py @@ -52,7 +52,7 @@ class Meta: @property def is_indexable(self): """Entities to index.""" - return self.is_active and self.has_active_repositories + return self.has_active_repositories @property def github_url(self): @@ -105,7 +105,7 @@ def from_github(self, field_mapping, repository): def generate_summary(self, prompt, open_ai=None, max_tokens=500): """Generate entity summary.""" - if not self.is_active or not prompt: + if not prompt: return open_ai = open_ai or OpenAi() diff --git a/backend/apps/owasp/models/managers/chapter.py b/backend/apps/owasp/models/managers/chapter.py index 4598027b7..9365c4da8 100644 --- a/backend/apps/owasp/models/managers/chapter.py +++ b/backend/apps/owasp/models/managers/chapter.py @@ -12,10 +12,8 @@ def get_queryset(self): return ( super() .get_queryset() - .filter(is_active=True) .select_related("owasp_repository") .filter( - owasp_repository__is_archived=False, owasp_repository__is_empty=False, ) ) diff --git a/backend/apps/owasp/models/mixins/chapter.py b/backend/apps/owasp/models/mixins/chapter.py index 6475e6a5b..4452a0b7a 100644 --- a/backend/apps/owasp/models/mixins/chapter.py +++ b/backend/apps/owasp/models/mixins/chapter.py @@ -21,6 +21,11 @@ def idx_geo_location(self): """Return geographic location for indexing.""" return self.latitude, self.longitude + @property + def idx_is_active(self): + """Return active status for indexing.""" + return self.is_active + @property def idx_key(self): """Return key for indexing.""" diff --git a/backend/apps/owasp/models/mixins/project.py b/backend/apps/owasp/models/mixins/project.py index 1cf591eea..99818d6e7 100644 --- a/backend/apps/owasp/models/mixins/project.py +++ b/backend/apps/owasp/models/mixins/project.py @@ -60,6 +60,11 @@ def idx_issues_count(self): """Return issues count for indexing.""" return self.open_issues.count() + @property + def idx_is_active(self): + """Return active status for indexing.""" + return self.is_active + @property def idx_key(self): """Return key for indexing.""" @@ -160,4 +165,4 @@ def idx_type(self): @property def idx_updated_at(self): """Return updated at for indexing.""" - return self.updated_at.timestamp() + return self.updated_at.timestamp() if self.updated_at else "" diff --git a/backend/apps/owasp/models/project.py b/backend/apps/owasp/models/project.py index 9f6e09df7..b54a4b2a9 100644 --- a/backend/apps/owasp/models/project.py +++ b/backend/apps/owasp/models/project.py @@ -142,7 +142,7 @@ def is_tool_type(self): @property def is_indexable(self): """Projects to index.""" - return self.is_active and self.has_active_repositories + return self.has_active_repositories @property def nest_key(self): diff --git a/backend/poetry.lock b/backend/poetry.lock index 296d6adb2..1dfe7edd3 100644 --- a/backend/poetry.lock +++ b/backend/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 2.0.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.5 and should not be changed by hand. [[package]] name = "aiohappyeyeballs" @@ -6,7 +6,6 @@ version = "2.4.4" description = "Happy Eyeballs for asyncio" optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "aiohappyeyeballs-2.4.4-py3-none-any.whl", hash = "sha256:a980909d50efcd44795c4afeca523296716d50cd756ddca6af8c65b996e27de8"}, {file = "aiohappyeyeballs-2.4.4.tar.gz", hash = "sha256:5fdd7d87889c63183afc18ce9271f9b0a7d32c2303e394468dd45d514a757745"}, @@ -18,7 +17,6 @@ version = "3.11.11" description = "Async http client/server framework (asyncio)" optional = false python-versions = ">=3.9" -groups = ["main"] files = [ {file = "aiohttp-3.11.11-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a60804bff28662cbcf340a4d61598891f12eea3a66af48ecfdc975ceec21e3c8"}, {file = "aiohttp-3.11.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4b4fa1cb5f270fb3eab079536b764ad740bb749ce69a94d4ec30ceee1b5940d5"}, @@ -116,7 +114,6 @@ version = "1.3.2" description = "aiosignal: a list of registered asynchronous callbacks" optional = false python-versions = ">=3.9" -groups = ["main"] files = [ {file = "aiosignal-1.3.2-py2.py3-none-any.whl", hash = "sha256:45cde58e409a301715980c2b01d0c28bdde3770d8290b5eb2173759d9acb31a5"}, {file = "aiosignal-1.3.2.tar.gz", hash = "sha256:a8c255c66fafb1e499c9351d0bf32ff2d8a0321595ebac3b93713656d2436f54"}, @@ -127,14 +124,13 @@ frozenlist = ">=1.1.0" [[package]] name = "algoliasearch" -version = "4.12.0" +version = "4.13.0" description = "A fully-featured and blazing-fast Python API client to interact with Algolia." optional = false python-versions = ">=3.8.1" -groups = ["main"] files = [ - {file = "algoliasearch-4.12.0-py3-none-any.whl", hash = "sha256:73c315f54604598720e6b209f25e7026a4dcdb92cc3f44ba65d9245ebd84317a"}, - {file = "algoliasearch-4.12.0.tar.gz", hash = "sha256:c2a7c5dda60562f493d55e351a796c8b66bb99e86a1813dab2038ba45e532204"}, + {file = "algoliasearch-4.13.0-py3-none-any.whl", hash = "sha256:9cbcf2f829b1badb9c855f18eeb125358faab80e3f13947b8c7add27350e7022"}, + {file = "algoliasearch-4.13.0.tar.gz", hash = "sha256:d929306623ae505ef58289b0951fe190c8262076df5e90c29fdb5c61644e9d36"}, ] [package.dependencies] @@ -151,7 +147,6 @@ version = "4.0.0" description = "Algolia Search integration for Django" optional = false python-versions = "*" -groups = ["main"] files = [ {file = "algoliasearch_django-4.0.0-py2.py3-none-any.whl", hash = "sha256:d160b86cd999607e9b3b0773a712e196e251af2b7dcb2480e40ef09440f3c80a"}, {file = "algoliasearch_django-4.0.0.tar.gz", hash = "sha256:c0acb8231163c16757d9e4c37a0ce882b89c4640a6dc836daaf479fd73c427b5"}, @@ -166,7 +161,6 @@ version = "0.7.0" description = "Reusable constraint types to use with typing.Annotated" optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53"}, {file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"}, @@ -178,7 +172,6 @@ version = "4.8.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false python-versions = ">=3.9" -groups = ["main"] files = [ {file = "anyio-4.8.0-py3-none-any.whl", hash = "sha256:b5011f270ab5eb0abf13385f851315585cc37ef330dd88e27ec3d34d651fd47a"}, {file = "anyio-4.8.0.tar.gz", hash = "sha256:1d9fe889df5212298c0c0723fa20479d1b94883a2df44bd3897aa91083316f7a"}, @@ -199,7 +192,6 @@ version = "3.8.1" description = "ASGI specs, helper code, and adapters" optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "asgiref-3.8.1-py3-none-any.whl", hash = "sha256:3e1e3ecc849832fe52ccf2cb6686b7a55f82bb1d6aee72a58826471390335e47"}, {file = "asgiref-3.8.1.tar.gz", hash = "sha256:c343bd80a0bec947a9860adb4c432ffa7db769836c64238fc34bdc3fec84d590"}, @@ -214,7 +206,6 @@ version = "5.0.1" description = "Timeout context manager for asyncio programs" optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "async_timeout-5.0.1-py3-none-any.whl", hash = "sha256:39e3809566ff85354557ec2398b55e096c8364bacac9405a7a1fa429e77fe76c"}, {file = "async_timeout-5.0.1.tar.gz", hash = "sha256:d9321a7a3d5a6a5e187e824d2fa0793ce379a202935782d555d6e9d2735677d3"}, @@ -226,7 +217,6 @@ version = "24.3.0" description = "Classes Without Boilerplate" optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308"}, {file = "attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff"}, @@ -246,7 +236,6 @@ version = "1.36.2" description = "The AWS SDK for Python" optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "boto3-1.36.2-py3-none-any.whl", hash = "sha256:76cfc9a705be46e8d22607efacc8d688c064f923d785a01c00b28e9a96425d1a"}, {file = "boto3-1.36.2.tar.gz", hash = "sha256:fde1c29996b77274a60b7bc9f741525afa6267bb1716eb644a764fb7c124a0d2"}, @@ -266,7 +255,6 @@ version = "1.36.2" description = "Low-level, data-driven core of boto 3." optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "botocore-1.36.2-py3-none-any.whl", hash = "sha256:bc3b7e3b573a48af2bd7116b80fe24f9a335b0b67314dcb2697a327d009abf29"}, {file = "botocore-1.36.2.tar.gz", hash = "sha256:a1fe6610983f0214b0c7655fe6990b6a731746baf305b182976fc7b568fc3cb0"}, @@ -286,7 +274,6 @@ version = "2024.12.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" -groups = ["main"] files = [ {file = "certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56"}, {file = "certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db"}, @@ -298,7 +285,6 @@ version = "1.17.1" description = "Foreign Function Interface for Python calling C code." optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "cffi-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14"}, {file = "cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67"}, @@ -378,7 +364,6 @@ version = "3.4.0" description = "Validate configuration and produce human readable error messages." optional = false python-versions = ">=3.8" -groups = ["dev"] files = [ {file = "cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9"}, {file = "cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560"}, @@ -390,7 +375,6 @@ version = "3.4.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false python-versions = ">=3.7" -groups = ["main"] files = [ {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, @@ -492,7 +476,6 @@ version = "8.1.8" description = "Composable command line interface toolkit" optional = false python-versions = ">=3.7" -groups = ["dev"] files = [ {file = "click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2"}, {file = "click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a"}, @@ -507,12 +490,10 @@ version = "0.4.6" description = "Cross-platform colored terminal text." optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" -groups = ["main", "dev", "test"] files = [ {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] -markers = {main = "platform_system == \"Windows\"", test = "sys_platform == \"win32\""} [[package]] name = "coverage" @@ -520,7 +501,6 @@ version = "7.6.10" description = "Code coverage measurement for Python" optional = false python-versions = ">=3.9" -groups = ["test"] files = [ {file = "coverage-7.6.10-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5c912978f7fbf47ef99cec50c4401340436d200d41d714c7a4766f377c5b7b78"}, {file = "coverage-7.6.10-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a01ec4af7dfeb96ff0078ad9a48810bb0cc8abcb0115180c6013a6b26237626c"}, @@ -595,7 +575,6 @@ version = "44.0.0" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." optional = false python-versions = "!=3.9.0,!=3.9.1,>=3.7" -groups = ["main"] files = [ {file = "cryptography-44.0.0-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:84111ad4ff3f6253820e6d3e58be2cc2a00adb29335d4cacb5ab4d4d34f2a123"}, {file = "cryptography-44.0.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b15492a11f9e1b62ba9d73c210e2416724633167de94607ec6069ef724fad092"}, @@ -645,7 +624,6 @@ version = "1.15.1" description = "CSS unobfuscator and beautifier." optional = false python-versions = "*" -groups = ["dev"] files = [ {file = "cssbeautifier-1.15.1.tar.gz", hash = "sha256:9f7064362aedd559c55eeecf6b6bed65e05f33488dcbe39044f0403c26e1c006"}, ] @@ -661,7 +639,6 @@ version = "1.2.15" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" -groups = ["main"] files = [ {file = "Deprecated-1.2.15-py2.py3-none-any.whl", hash = "sha256:353bc4a8ac4bfc96800ddab349d89c25dec1079f65fd53acdcc1e0b975b21320"}, {file = "deprecated-1.2.15.tar.gz", hash = "sha256:683e561a90de76239796e6b6feac66b99030d2dd3fcf61ef996330f14bbb9b0d"}, @@ -679,7 +656,6 @@ version = "0.3.9" description = "Distribution utilities" optional = false python-versions = "*" -groups = ["dev"] files = [ {file = "distlib-0.3.9-py2.py3-none-any.whl", hash = "sha256:47f8c22fd27c27e25a65601af709b38e4f0a45ea4fc2e710f65755fa8caaaf87"}, {file = "distlib-0.3.9.tar.gz", hash = "sha256:a60f20dea646b8a33f3e7772f74dc0b2d0772d2837ee1342a00645c81edf9403"}, @@ -691,7 +667,6 @@ version = "1.9.0" description = "Distro - an OS platform information API" optional = false python-versions = ">=3.6" -groups = ["main"] files = [ {file = "distro-1.9.0-py3-none-any.whl", hash = "sha256:7bffd925d65168f85027d8da9af6bddab658135b840670a223589bc0c8ef02b2"}, {file = "distro-1.9.0.tar.gz", hash = "sha256:2fa77c6fd8940f116ee1d6b94a2f90b13b5ea8d019b98bc8bafdcabcdd9bdbed"}, @@ -703,7 +678,6 @@ version = "5.1.5" description = "A high-level Python web framework that encourages rapid development and clean, pragmatic design." optional = false python-versions = ">=3.10" -groups = ["main"] files = [ {file = "Django-5.1.5-py3-none-any.whl", hash = "sha256:c46eb936111fffe6ec4bc9930035524a8be98ec2f74d8a0ff351226a3e52f459"}, {file = "Django-5.1.5.tar.gz", hash = "sha256:19bbca786df50b9eca23cee79d495facf55c8f5c54c529d9bf1fe7b5ea086af3"}, @@ -724,7 +698,6 @@ version = "2.5.1" description = "A helper for organizing Django settings." optional = false python-versions = "<4.0,>=3.8" -groups = ["main"] files = [ {file = "django-configurations-2.5.1.tar.gz", hash = "sha256:6e5083757e2bbdf9bb7850567536b96a93515f6b17503d74928ff628db2e0e94"}, {file = "django_configurations-2.5.1-py3-none-any.whl", hash = "sha256:ceb84858da2dac846b15e715c2fd936cfc4c7917c074aff8d31700564093955e"}, @@ -746,7 +719,6 @@ version = "4.6.0" description = "django-cors-headers is a Django application for handling the server headers required for Cross-Origin Resource Sharing (CORS)." optional = false python-versions = ">=3.9" -groups = ["main"] files = [ {file = "django_cors_headers-4.6.0-py3-none-any.whl", hash = "sha256:8edbc0497e611c24d5150e0055d3b178c6534b8ed826fb6f53b21c63f5d48ba3"}, {file = "django_cors_headers-4.6.0.tar.gz", hash = "sha256:14d76b4b4c8d39375baeddd89e4f08899051eeaf177cb02a29bd6eae8cf63aa8"}, @@ -762,7 +734,6 @@ version = "24.3" description = "Django-filter is a reusable Django application for allowing users to filter querysets dynamically." optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "django_filter-24.3-py3-none-any.whl", hash = "sha256:c4852822928ce17fb699bcfccd644b3574f1a2d80aeb2b4ff4f16b02dd49dc64"}, {file = "django_filter-24.3.tar.gz", hash = "sha256:d8ccaf6732afd21ca0542f6733b11591030fa98669f8d15599b358e24a2cd9c3"}, @@ -777,7 +748,6 @@ version = "1.14.4" description = "Support for many storage backends in Django" optional = false python-versions = ">=3.7" -groups = ["main"] files = [ {file = "django-storages-1.14.4.tar.gz", hash = "sha256:69aca94d26e6714d14ad63f33d13619e697508ee33ede184e462ed766dc2a73f"}, {file = "django_storages-1.14.4-py3-none-any.whl", hash = "sha256:d61930acb4a25e3aebebc6addaf946a3b1df31c803a6bf1af2f31c9047febaa3"}, @@ -802,7 +772,6 @@ version = "3.15.2" description = "Web APIs for Django, made easy." optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "djangorestframework-3.15.2-py3-none-any.whl", hash = "sha256:2b8871b062ba1aefc2de01f773875441a961fefbf79f5eed1e32b2f096944b20"}, {file = "djangorestframework-3.15.2.tar.gz", hash = "sha256:36fe88cd2d6c6bec23dca9804bab2ba5517a8bb9d8f47ebc68981b56840107ad"}, @@ -817,7 +786,6 @@ version = "1.36.4" description = "HTML Template Linter and Formatter" optional = false python-versions = ">=3.9" -groups = ["dev"] files = [ {file = "djlint-1.36.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a2dfb60883ceb92465201bfd392291a7597c6752baede6fbb6f1980cac8d6c5c"}, {file = "djlint-1.36.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4bc6a1320c0030244b530ac200642f883d3daa451a115920ef3d56d08b644292"}, @@ -860,7 +828,6 @@ version = "0.17.0" description = "EditorConfig File Locator and Interpreter for Python" optional = false python-versions = "*" -groups = ["dev"] files = [ {file = "EditorConfig-0.17.0-py3-none-any.whl", hash = "sha256:fe491719c5f65959ec00b167d07740e7ffec9a3f362038c72b289330b9991dfc"}, {file = "editorconfig-0.17.0.tar.gz", hash = "sha256:8739052279699840065d3a9f5c125d7d5a98daeefe53b0e5274261d77cb49aa2"}, @@ -872,7 +839,6 @@ version = "2.1.1" description = "execnet: rapid multi-Python deployment" optional = false python-versions = ">=3.8" -groups = ["test"] files = [ {file = "execnet-2.1.1-py3-none-any.whl", hash = "sha256:26dee51f1b80cebd6d0ca8e74dd8745419761d3bef34163928cbebbdc4749fdc"}, {file = "execnet-2.1.1.tar.gz", hash = "sha256:5189b52c6121c24feae288166ab41b32549c7e2348652736540b9e6e7d4e72e3"}, @@ -887,7 +853,6 @@ version = "3.16.1" description = "A platform independent file lock." optional = false python-versions = ">=3.8" -groups = ["dev"] files = [ {file = "filelock-3.16.1-py3-none-any.whl", hash = "sha256:2082e5703d51fbf98ea75855d9d5527e33d8ff23099bec374a134febee6946b0"}, {file = "filelock-3.16.1.tar.gz", hash = "sha256:c249fbfcd5db47e5e2d6d62198e565475ee65e4831e2561c8e313fa7eb961435"}, @@ -904,7 +869,6 @@ version = "1.5.0" description = "A list-like structure which implements collections.abc.MutableSequence" optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "frozenlist-1.5.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:5b6a66c18b5b9dd261ca98dffcb826a525334b2f29e7caa54e182255c5f6a65a"}, {file = "frozenlist-1.5.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d1b3eb7b05ea246510b43a7e53ed1653e55c2121019a97e60cad7efb881a97bb"}, @@ -1006,7 +970,6 @@ version = "2.0" description = "The geodesic routines from GeographicLib" optional = false python-versions = ">=3.7" -groups = ["main"] files = [ {file = "geographiclib-2.0-py3-none-any.whl", hash = "sha256:6b7225248e45ff7edcee32becc4e0a1504c606ac5ee163a5656d482e0cd38734"}, {file = "geographiclib-2.0.tar.gz", hash = "sha256:f7f41c85dc3e1c2d3d935ec86660dc3b2c848c83e17f9a9e51ba9d5146a15859"}, @@ -1018,7 +981,6 @@ version = "2.4.1" description = "Python Geocoding Toolbox" optional = false python-versions = ">=3.7" -groups = ["main"] files = [ {file = "geopy-2.4.1-py3-none-any.whl", hash = "sha256:ae8b4bc5c1131820f4d75fce9d4aaaca0c85189b3aa5d64c3dcaf5e3b7b882a7"}, {file = "geopy-2.4.1.tar.gz", hash = "sha256:50283d8e7ad07d89be5cb027338c6365a32044df3ae2556ad3f52f4840b3d0d1"}, @@ -1042,7 +1004,6 @@ version = "23.0.0" description = "WSGI HTTP Server for UNIX" optional = false python-versions = ">=3.7" -groups = ["main"] files = [ {file = "gunicorn-23.0.0-py3-none-any.whl", hash = "sha256:ec400d38950de4dfd418cff8328b2c8faed0edb0d517d3394e457c317908ca4d"}, {file = "gunicorn-23.0.0.tar.gz", hash = "sha256:f014447a0101dc57e294f6c18ca6b40227a4c90e9bdb586042628030cba004ec"}, @@ -1064,7 +1025,6 @@ version = "0.14.0" description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" optional = false python-versions = ">=3.7" -groups = ["main"] files = [ {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"}, {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, @@ -1076,7 +1036,6 @@ version = "1.0.7" description = "A minimal low-level HTTP client." optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd"}, {file = "httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c"}, @@ -1098,7 +1057,6 @@ version = "0.28.1" description = "The next generation HTTP client." optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad"}, {file = "httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc"}, @@ -1123,7 +1081,6 @@ version = "4.11.0" description = "Python humanize utilities" optional = false python-versions = ">=3.9" -groups = ["main"] files = [ {file = "humanize-4.11.0-py3-none-any.whl", hash = "sha256:b53caaec8532bcb2fff70c8826f904c35943f8cecaca29d272d9df38092736c0"}, {file = "humanize-4.11.0.tar.gz", hash = "sha256:e66f36020a2d5a974c504bd2555cf770621dbdbb6d82f94a6857c0b1ea2608be"}, @@ -1138,7 +1095,6 @@ version = "2.6.5" description = "File identification library for Python" optional = false python-versions = ">=3.9" -groups = ["dev"] files = [ {file = "identify-2.6.5-py2.py3-none-any.whl", hash = "sha256:14181a47091eb75b337af4c23078c9d09225cd4c48929f521f3bf16b09d02566"}, {file = "identify-2.6.5.tar.gz", hash = "sha256:c10b33f250e5bba374fae86fb57f3adcebf1161bce7cdf92031915fd480c13bc"}, @@ -1153,7 +1109,6 @@ version = "3.10" description = "Internationalized Domain Names in Applications (IDNA)" optional = false python-versions = ">=3.6" -groups = ["main"] files = [ {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, @@ -1168,7 +1123,6 @@ version = "2.0.0" description = "brain-dead simple config-ini parsing" optional = false python-versions = ">=3.7" -groups = ["test"] files = [ {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, @@ -1180,7 +1134,6 @@ version = "5.13.2" description = "A Python utility / library to sort Python imports." optional = false python-versions = ">=3.8.0" -groups = ["dev"] files = [ {file = "isort-5.13.2-py3-none-any.whl", hash = "sha256:8ca5e72a8d85860d5a3fa69b8745237f2939afe12dbf656afbcb47fe72d947a6"}, {file = "isort-5.13.2.tar.gz", hash = "sha256:48fdfcb9face5d58a4f6dde2e72a1fb8dcaf8ab26f95ab49fab84c2ddefb0109"}, @@ -1195,7 +1148,6 @@ version = "0.8.2" description = "Fast iterable JSON parser." optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "jiter-0.8.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:ca8577f6a413abe29b079bc30f907894d7eb07a865c4df69475e868d73e71c7b"}, {file = "jiter-0.8.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b25bd626bde7fb51534190c7e3cb97cee89ee76b76d7585580e22f34f5e3f393"}, @@ -1281,7 +1233,6 @@ version = "1.0.1" description = "JSON Matching Expressions" optional = false python-versions = ">=3.7" -groups = ["main"] files = [ {file = "jmespath-1.0.1-py3-none-any.whl", hash = "sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980"}, {file = "jmespath-1.0.1.tar.gz", hash = "sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe"}, @@ -1293,7 +1244,6 @@ version = "1.15.1" description = "JavaScript unobfuscator and beautifier." optional = false python-versions = "*" -groups = ["dev"] files = [ {file = "jsbeautifier-1.15.1.tar.gz", hash = "sha256:ebd733b560704c602d744eafc839db60a1ee9326e30a2a80c4adb8718adc1b24"}, ] @@ -1308,7 +1258,6 @@ version = "0.10.0" description = "A Python implementation of the JSON5 data format." optional = false python-versions = ">=3.8.0" -groups = ["dev"] files = [ {file = "json5-0.10.0-py3-none-any.whl", hash = "sha256:19b23410220a7271e8377f81ba8aacba2fdd56947fbb137ee5977cbe1f5e8dfa"}, {file = "json5-0.10.0.tar.gz", hash = "sha256:e66941c8f0a02026943c52c2eb34ebeb2a6f819a0be05920a6f5243cd30fd559"}, @@ -1323,7 +1272,6 @@ version = "5.3.0" description = "Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API." optional = false python-versions = ">=3.6" -groups = ["main"] files = [ {file = "lxml-5.3.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:dd36439be765e2dde7660212b5275641edbc813e7b24668831a5c8ac91180656"}, {file = "lxml-5.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ae5fe5c4b525aa82b8076c1a59d642c17b6e8739ecf852522c6321852178119d"}, @@ -1478,7 +1426,6 @@ version = "3.7" description = "Python implementation of John Gruber's Markdown." optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "Markdown-3.7-py3-none-any.whl", hash = "sha256:7eb6df5690b81a1d7942992c97fad2938e956e79df20cbc6186e9c3a77b1c803"}, {file = "markdown-3.7.tar.gz", hash = "sha256:2ae2471477cfd02dbbf038d5d9bc226d40def84b4fe2986e49b59b6b472bbed2"}, @@ -1494,7 +1441,6 @@ version = "6.1.0" description = "multidict implementation" optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "multidict-6.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3380252550e372e8511d49481bd836264c009adb826b23fefcc5dd3c69692f60"}, {file = "multidict-6.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:99f826cbf970077383d7de805c0681799491cb939c25450b9b5b3ced03ca99f1"}, @@ -1596,7 +1542,6 @@ version = "1.9.1" description = "Node.js virtual environment builder" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" -groups = ["dev"] files = [ {file = "nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9"}, {file = "nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f"}, @@ -1604,14 +1549,13 @@ files = [ [[package]] name = "openai" -version = "1.59.8" +version = "1.60.0" description = "The official Python library for the openai API" optional = false python-versions = ">=3.8" -groups = ["main"] files = [ - {file = "openai-1.59.8-py3-none-any.whl", hash = "sha256:a8b8ee35c4083b88e6da45406d883cf6bd91a98ab7dd79178b8bc24c8bfb09d9"}, - {file = "openai-1.59.8.tar.gz", hash = "sha256:ac4bda5fa9819fdc6127e8ea8a63501f425c587244bc653c7c11a8ad84f953e1"}, + {file = "openai-1.60.0-py3-none-any.whl", hash = "sha256:df06c43be8018274980ac363da07d4b417bd835ead1c66e14396f6f15a0d5dda"}, + {file = "openai-1.60.0.tar.gz", hash = "sha256:7fa536cd4b644718645b874d2706e36dbbef38b327e42ca0623275da347ee1a9"}, ] [package.dependencies] @@ -1634,7 +1578,6 @@ version = "24.2" description = "Core utilities for Python packages" optional = false python-versions = ">=3.8" -groups = ["main", "test"] files = [ {file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"}, {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, @@ -1646,7 +1589,6 @@ version = "0.12.1" description = "Utility library for gitignore style pattern matching of file paths." optional = false python-versions = ">=3.8" -groups = ["dev"] files = [ {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, @@ -1658,7 +1600,6 @@ version = "4.3.6" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." optional = false python-versions = ">=3.8" -groups = ["dev"] files = [ {file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"}, {file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"}, @@ -1675,7 +1616,6 @@ version = "1.5.0" description = "plugin and hook calling mechanisms for python" optional = false python-versions = ">=3.8" -groups = ["test"] files = [ {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, @@ -1687,14 +1627,13 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "pre-commit" -version = "4.0.1" +version = "4.1.0" description = "A framework for managing and maintaining multi-language pre-commit hooks." optional = false python-versions = ">=3.9" -groups = ["dev"] files = [ - {file = "pre_commit-4.0.1-py2.py3-none-any.whl", hash = "sha256:efde913840816312445dc98787724647c65473daefe420785f885e8ed9a06878"}, - {file = "pre_commit-4.0.1.tar.gz", hash = "sha256:80905ac375958c0444c65e9cebebd948b3cdb518f335a091a670a89d652139d2"}, + {file = "pre_commit-4.1.0-py2.py3-none-any.whl", hash = "sha256:d29e7cb346295bcc1cc75fc3e92e343495e3ea0196c9ec6ba53f49f10ab6ae7b"}, + {file = "pre_commit-4.1.0.tar.gz", hash = "sha256:ae3f018575a588e30dfddfab9a05448bfbd6b73d78709617b5a2b853549716d4"}, ] [package.dependencies] @@ -1710,7 +1649,6 @@ version = "0.2.1" description = "Accelerated property cache" optional = false python-versions = ">=3.9" -groups = ["main"] files = [ {file = "propcache-0.2.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:6b3f39a85d671436ee3d12c017f8fdea38509e4f25b28eb25877293c98c243f6"}, {file = "propcache-0.2.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:39d51fbe4285d5db5d92a929e3e21536ea3dd43732c5b177c7ef03f918dff9f2"}, @@ -1802,7 +1740,6 @@ version = "3.2.4" description = "PostgreSQL database adapter for Python" optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "psycopg-3.2.4-py3-none-any.whl", hash = "sha256:43665368ccd48180744cab26b74332f46b63b7e06e8ce0775547a3533883d381"}, {file = "psycopg-3.2.4.tar.gz", hash = "sha256:f26f1346d6bf1ef5f5ef1714dd405c67fb365cfd1c6cea07de1792747b167b92"}, @@ -1825,7 +1762,6 @@ version = "2.22" description = "C parser in Python" optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc"}, {file = "pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6"}, @@ -1837,7 +1773,6 @@ version = "2.10.5" description = "Data validation using Python type hints" optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "pydantic-2.10.5-py3-none-any.whl", hash = "sha256:4dd4e322dbe55472cb7ca7e73f4b63574eecccf2835ffa2af9021ce113c83c53"}, {file = "pydantic-2.10.5.tar.gz", hash = "sha256:278b38dbbaec562011d659ee05f63346951b3a248a6f3642e1bc68894ea2b4ff"}, @@ -1858,7 +1793,6 @@ version = "2.27.2" description = "Core functionality for Pydantic validation and serialization" optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "pydantic_core-2.27.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2d367ca20b2f14095a8f4fa1210f5a7b78b8a20009ecced6b12818f455b1e9fa"}, {file = "pydantic_core-2.27.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:491a2b73db93fab69731eaee494f320faa4e093dbed776be1a829c2eb222c34c"}, @@ -1971,7 +1905,6 @@ version = "2.5.0" description = "Use the full Github API v3" optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "PyGithub-2.5.0-py3-none-any.whl", hash = "sha256:b0b635999a658ab8e08720bdd3318893ff20e2275f6446fcf35bf3f44f2c0fd2"}, {file = "pygithub-2.5.0.tar.gz", hash = "sha256:e1613ac508a9be710920d26eb18b1905ebd9926aa49398e88151c1b526aad3cf"}, @@ -1991,7 +1924,6 @@ version = "2.10.1" description = "JSON Web Token implementation in Python" optional = false python-versions = ">=3.9" -groups = ["main"] files = [ {file = "PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb"}, {file = "pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953"}, @@ -2012,7 +1944,6 @@ version = "1.5.0" description = "Python binding to the Networking and Cryptography (NaCl) library" optional = false python-versions = ">=3.6" -groups = ["main"] files = [ {file = "PyNaCl-1.5.0-cp36-abi3-macosx_10_10_universal2.whl", hash = "sha256:401002a4aaa07c9414132aaed7f6836ff98f59277a234704ff66878c2ee4a0d1"}, {file = "PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:52cb72a79269189d4e0dc537556f4740f7f0a9ec41c1322598799b0bdad4ef92"}, @@ -2039,7 +1970,6 @@ version = "8.3.4" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.8" -groups = ["test"] files = [ {file = "pytest-8.3.4-py3-none-any.whl", hash = "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6"}, {file = "pytest-8.3.4.tar.gz", hash = "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761"}, @@ -2060,7 +1990,6 @@ version = "6.0.0" description = "Pytest plugin for measuring coverage." optional = false python-versions = ">=3.9" -groups = ["test"] files = [ {file = "pytest-cov-6.0.0.tar.gz", hash = "sha256:fde0b595ca248bb8e2d76f020b465f3b107c9632e6a1d1705f17834c89dcadc0"}, {file = "pytest_cov-6.0.0-py3-none-any.whl", hash = "sha256:eee6f1b9e61008bd34975a4d5bab25801eb31898b032dd55addc93e96fcaaa35"}, @@ -2079,7 +2008,6 @@ version = "4.9.0" description = "A Django plugin for pytest." optional = false python-versions = ">=3.8" -groups = ["test"] files = [ {file = "pytest_django-4.9.0-py3-none-any.whl", hash = "sha256:1d83692cb39188682dbb419ff0393867e9904094a549a7d38a3154d5731b2b99"}, {file = "pytest_django-4.9.0.tar.gz", hash = "sha256:8bf7bc358c9ae6f6fc51b6cebb190fe20212196e6807121f11bd6a3b03428314"}, @@ -2098,7 +2026,6 @@ version = "3.14.0" description = "Thin-wrapper around the mock package for easier use with pytest" optional = false python-versions = ">=3.8" -groups = ["test"] files = [ {file = "pytest-mock-3.14.0.tar.gz", hash = "sha256:2719255a1efeceadbc056d6bf3df3d1c5015530fb40cf347c0f9afac88410bd0"}, {file = "pytest_mock-3.14.0-py3-none-any.whl", hash = "sha256:0b72c38033392a5f4621342fe11e9219ac11ec9d375f8e2a0c164539e0d70f6f"}, @@ -2116,7 +2043,6 @@ version = "3.6.1" description = "pytest xdist plugin for distributed testing, most importantly across multiple CPUs" optional = false python-versions = ">=3.8" -groups = ["test"] files = [ {file = "pytest_xdist-3.6.1-py3-none-any.whl", hash = "sha256:9ed4adfb68a016610848639bb7e02c9352d5d9f03d04809919e2dafc3be4cca7"}, {file = "pytest_xdist-3.6.1.tar.gz", hash = "sha256:ead156a4db231eec769737f57668ef58a2084a34b2e55c4a8fa20d861107300d"}, @@ -2137,7 +2063,6 @@ version = "2.9.0.post0" description = "Extensions to the standard Python datetime module" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" -groups = ["main"] files = [ {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, @@ -2152,7 +2077,6 @@ version = "1.0.1" description = "Read key-value pairs from a .env file and set them as environment variables" optional = false python-versions = ">=3.8" -groups = ["test"] files = [ {file = "python-dotenv-1.0.1.tar.gz", hash = "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca"}, {file = "python_dotenv-1.0.1-py3-none-any.whl", hash = "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a"}, @@ -2167,7 +2091,6 @@ version = "6.0.2" description = "YAML parser and emitter for Python" optional = false python-versions = ">=3.8" -groups = ["main", "dev"] files = [ {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"}, {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"}, @@ -2230,7 +2153,6 @@ version = "2024.11.6" description = "Alternative regular expression module, to replace re." optional = false python-versions = ">=3.8" -groups = ["dev"] files = [ {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ff590880083d60acc0433f9c3f713c51f7ac6ebb9adf889c79a261ecf541aa91"}, {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:658f90550f38270639e83ce492f27d2c8d2cd63805c65a13a14d36ca126753f0"}, @@ -2334,7 +2256,6 @@ version = "2.32.3" description = "Python HTTP for Humans." optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, @@ -2356,7 +2277,6 @@ version = "0.9.2" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" -groups = ["dev"] files = [ {file = "ruff-0.9.2-py3-none-linux_armv6l.whl", hash = "sha256:80605a039ba1454d002b32139e4970becf84b5fee3a3c3bf1c2af6f61a784347"}, {file = "ruff-0.9.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b9aab82bb20afd5f596527045c01e6ae25a718ff1784cb92947bff1f83068b00"}, @@ -2384,7 +2304,6 @@ version = "0.11.1" description = "An Amazon S3 Transfer Manager" optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "s3transfer-0.11.1-py3-none-any.whl", hash = "sha256:8fa0aa48177be1f3425176dfe1ab85dcd3d962df603c3dbfc585e6bf857ef0ff"}, {file = "s3transfer-0.11.1.tar.gz", hash = "sha256:3f25c900a367c8b7f7d8f9c34edc87e300bde424f779dc9f0a8ae4f9df9264f6"}, @@ -2402,7 +2321,6 @@ version = "2.20.0" description = "Python client for Sentry (https://sentry.io)" optional = false python-versions = ">=3.6" -groups = ["main"] files = [ {file = "sentry_sdk-2.20.0-py2.py3-none-any.whl", hash = "sha256:c359a1edf950eb5e80cffd7d9111f3dbeef57994cb4415df37d39fda2cf22364"}, {file = "sentry_sdk-2.20.0.tar.gz", hash = "sha256:afa82713a92facf847df3c6f63cec71eb488d826a50965def3d7722aa6f0fdab"}, @@ -2459,7 +2377,6 @@ version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" -groups = ["main", "dev"] files = [ {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, @@ -2471,7 +2388,6 @@ version = "1.22.0" description = "The Bolt Framework for Python" optional = false python-versions = ">=3.6" -groups = ["main"] files = [ {file = "slack_bolt-1.22.0-py2.py3-none-any.whl", hash = "sha256:349097136a586617e5fb71f40f58a30fa847f664c598577f67a01f99faa1a9eb"}, {file = "slack_bolt-1.22.0.tar.gz", hash = "sha256:b9c66d088fe3ec8bdd0494278eb500fe58092c2941de86d6822d00f4b3c7c88b"}, @@ -2486,7 +2402,6 @@ version = "3.34.0" description = "The Slack API Platform SDK for Python" optional = false python-versions = ">=3.6" -groups = ["main"] files = [ {file = "slack_sdk-3.34.0-py2.py3-none-any.whl", hash = "sha256:c61f57f310d85be83466db5a98ab6ae3bb2e5587437b54fa0daa8fae6a0feffa"}, {file = "slack_sdk-3.34.0.tar.gz", hash = "sha256:ff61db7012160eed742285ea91f11c72b7a38a6500a7f6c5335662b4bc6b853d"}, @@ -2501,7 +2416,6 @@ version = "1.3.1" description = "Sniff out which async library your code is running under" optional = false python-versions = ">=3.7" -groups = ["main"] files = [ {file = "sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2"}, {file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"}, @@ -2513,7 +2427,6 @@ version = "0.5.3" description = "A non-validating SQL parser." optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "sqlparse-0.5.3-py3-none-any.whl", hash = "sha256:cf2196ed3418f3ba5de6af7e82c694a9fbdbfecccdfc72e281548517081f16ca"}, {file = "sqlparse-0.5.3.tar.gz", hash = "sha256:09f67787f56a0b16ecdbde1bfc7f5d9c3371ca683cfeaa8e6ff60b4807ec9272"}, @@ -2529,7 +2442,6 @@ version = "4.67.1" description = "Fast, Extensible Progress Meter" optional = false python-versions = ">=3.7" -groups = ["main", "dev"] files = [ {file = "tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2"}, {file = "tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2"}, @@ -2551,7 +2463,6 @@ version = "4.12.2" description = "Backported and Experimental Type Hints for Python 3.8+" optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, @@ -2563,8 +2474,6 @@ version = "2024.2" description = "Provider of IANA time zone data" optional = false python-versions = ">=2" -groups = ["main"] -markers = "sys_platform == \"win32\"" files = [ {file = "tzdata-2024.2-py2.py3-none-any.whl", hash = "sha256:a48093786cdcde33cad18c2555e8532f34422074448fbc874186f0abd79565cd"}, {file = "tzdata-2024.2.tar.gz", hash = "sha256:7d85cc416e9382e69095b7bdf4afd9e3880418a2413feec7069d533d6b4e31cc"}, @@ -2576,7 +2485,6 @@ version = "2.3.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false python-versions = ">=3.9" -groups = ["main"] files = [ {file = "urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df"}, {file = "urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d"}, @@ -2594,7 +2502,6 @@ version = "20.29.1" description = "Virtual Python Environment builder" optional = false python-versions = ">=3.8" -groups = ["dev"] files = [ {file = "virtualenv-20.29.1-py3-none-any.whl", hash = "sha256:4e4cb403c0b0da39e13b46b1b2476e505cb0046b25f242bee80f62bf990b2779"}, {file = "virtualenv-20.29.1.tar.gz", hash = "sha256:b8b8970138d32fb606192cb97f6cd4bb644fa486be9308fb9b63f81091b5dc35"}, @@ -2615,7 +2522,6 @@ version = "1.17.2" description = "Module for decorators, wrappers and monkey patching." optional = false python-versions = ">=3.8" -groups = ["main"] files = [ {file = "wrapt-1.17.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3d57c572081fed831ad2d26fd430d565b76aa277ed1d30ff4d40670b1c0dd984"}, {file = "wrapt-1.17.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b5e251054542ae57ac7f3fba5d10bfff615b6c2fb09abeb37d2f1463f841ae22"}, @@ -2704,7 +2610,6 @@ version = "1.18.3" description = "Yet another URL library" optional = false python-versions = ">=3.9" -groups = ["main"] files = [ {file = "yarl-1.18.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7df647e8edd71f000a5208fe6ff8c382a1de8edfbccdbbfe649d263de07d8c34"}, {file = "yarl-1.18.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c69697d3adff5aa4f874b19c0e4ed65180ceed6318ec856ebc423aa5850d84f7"}, @@ -2796,6 +2701,6 @@ multidict = ">=4.0" propcache = ">=0.2.0" [metadata] -lock-version = "2.1" +lock-version = "2.0" python-versions = "^3.13" -content-hash = "b20865df4c0c11b64f6a7be63fbd66ec16407943e5ce46a92d89ee6b0407ac18" +content-hash = "b67799c5b7b9c2a971560bdd33034749274ea76bebf71566b00cf1ae457c0b94" diff --git a/backend/pyproject.toml b/backend/pyproject.toml index d3d7cf2be..d84b9459e 100644 --- a/backend/pyproject.toml +++ b/backend/pyproject.toml @@ -21,7 +21,7 @@ omit = [ ] [tool.poetry.dependencies] -algoliasearch = "^4.12.0" +algoliasearch = "^4.13.0" algoliasearch-django = "^4.0.0" django = "^5.1" django-configurations = "^2.5.1" @@ -34,7 +34,7 @@ gunicorn = "^23.0.0" humanize = "^4.11.0" lxml = "^5.3.0" markdown = "^3.7" -openai = "^1.59.7" +openai = "^1.60.0" psycopg = "^3.2.4" pygithub = "^2.5.0" python = "^3.13" @@ -47,7 +47,7 @@ slack-bolt = "^1.22.0" [tool.poetry.group.dev.dependencies] djlint = "^1.36.4" isort = "^5.13.2" -pre-commit = "^4.0.0" +pre-commit = "^4.1.0" ruff = "^0.9.2" [tool.poetry.group.test.dependencies] diff --git a/backend/tests/common/management/commands/algolia_update_replicas_tests.py b/backend/tests/common/management/commands/algolia_update_replicas_tests.py new file mode 100644 index 000000000..47c71c528 --- /dev/null +++ b/backend/tests/common/management/commands/algolia_update_replicas_tests.py @@ -0,0 +1,43 @@ +"""Test cases for the algolia_update_replicas command.""" + +from io import StringIO +from unittest.mock import patch + +import pytest +from algoliasearch.http.exceptions import AlgoliaException +from django.core.management import call_command + + +class TestUpdateReplicasCommand: + """Test cases for the algolia_update_replicas command.""" + + @pytest.fixture(autouse=True) + def _setup(self): + """Set up test environment.""" + self.stdout = StringIO() + with patch("apps.owasp.index.project.ProjectIndex.configure_replicas") as replica_patch: + self.mock_replica_update = replica_patch + yield + + def test_successful_replica_configuration(self): + """Test successful replica configuration.""" + with patch("sys.stdout", new=StringIO()) as fake_out: + call_command("algolia_update_replicas") + + expected_output = ( + "\n Starting replica configuration...\n" + "\n Replica have been Successfully created.\n" + ) + assert fake_out.getvalue() == expected_output + self.mock_replica_update.assert_called_once() + + def test_handle_exception(self): + """Test handling of exceptions during replica configuration.""" + error_message = "Failed to configure replicas" + self.mock_replica_update.side_effect = AlgoliaException(error_message) + + with pytest.raises(AlgoliaException) as exc_info: + call_command("algolia_update_replicas") + + assert str(exc_info.value) == error_message + self.mock_replica_update.assert_called_once() diff --git a/backend/tests/owasp/models/chapter_tests.py b/backend/tests/owasp/models/chapter_tests.py index 4af0eb79c..7ce0d7a7e 100644 --- a/backend/tests/owasp/models/chapter_tests.py +++ b/backend/tests/owasp/models/chapter_tests.py @@ -85,16 +85,10 @@ def test_generate_suggested_location( assert chapter.suggested_location == (expected_location or "") - if is_active: - mock_open_ai.set_input.assert_called_once_with(geo_string) - mock_open_ai.set_max_tokens.assert_called_once_with(100) - mock_open_ai.set_prompt.assert_called_once_with("Tell me the location") - mock_open_ai.complete.assert_called_once() - else: - mock_open_ai.set_input.assert_not_called() - mock_open_ai.set_max_tokens.assert_not_called() - mock_open_ai.set_prompt.assert_not_called() - mock_open_ai.complete.assert_not_called() + mock_open_ai.set_input.assert_called_once_with(geo_string) + mock_open_ai.set_max_tokens.assert_called_once_with(100) + mock_open_ai.set_prompt.assert_called_once_with("Tell me the location") + mock_open_ai.complete.assert_called_once() @pytest.mark.parametrize( ("name", "key", "expected_str"), diff --git a/backend/tests/owasp/models/common_tests.py b/backend/tests/owasp/models/common_tests.py index 6a747c067..3eb53b412 100644 --- a/backend/tests/owasp/models/common_tests.py +++ b/backend/tests/owasp/models/common_tests.py @@ -13,17 +13,14 @@ class Meta: class TestRepositoryBasedEntityModel: @pytest.mark.parametrize( - ("is_active", "has_active_repositories", "expected"), + ("has_active_repositories", "expected"), [ - (True, True, True), - (True, False, False), - (False, True, False), - (False, False, False), + (True, True), + (False, False), ], ) - def test_is_indexable(self, is_active, has_active_repositories, expected): + def test_is_indexable(self, has_active_repositories, expected): model = EntityModel() - model.is_active = is_active model.has_active_repositories = has_active_repositories assert model.is_indexable == expected diff --git a/frontend/__tests__/src/data/mockChapterData.ts b/frontend/__tests__/src/data/mockChapterData.ts index 614646771..db5650e1f 100644 --- a/frontend/__tests__/src/data/mockChapterData.ts +++ b/frontend/__tests__/src/data/mockChapterData.ts @@ -23,6 +23,7 @@ export const mockChapterData = { key: 'chapter_1', url: 'https://owasp.org/www-chapter-nagoya', objectID: '539', + is_active: true, }, ], } diff --git a/frontend/__tests__/src/data/mockProjectData.ts b/frontend/__tests__/src/data/mockProjectData.ts index 666648a20..a355aa5c2 100644 --- a/frontend/__tests__/src/data/mockProjectData.ts +++ b/frontend/__tests__/src/data/mockProjectData.ts @@ -14,6 +14,7 @@ export const mockProjectData = { key: 'project_1', stars_count: 20, contributors_count: 5, + is_active: true, }, ], } diff --git a/frontend/__tests__/src/data/mockProjectDetailsData.ts b/frontend/__tests__/src/data/mockProjectDetailsData.ts index a168e9343..059d4fd12 100644 --- a/frontend/__tests__/src/data/mockProjectDetailsData.ts +++ b/frontend/__tests__/src/data/mockProjectDetailsData.ts @@ -11,6 +11,7 @@ export const mockProjectDetailsData = { forks_count: 20, stars_count: 100, issues_count: 10, + is_active: true, repositories_count: 2, summary: 'This is a summary of the test project.', languages: Array.from({ length: 15 }, (_, i) => `Language ${i + 1}`), diff --git a/frontend/__tests__/src/pages/Committees.test.tsx b/frontend/__tests__/src/pages/Committees.test.tsx index 08d28bc20..b7d7ff9d6 100644 --- a/frontend/__tests__/src/pages/Committees.test.tsx +++ b/frontend/__tests__/src/pages/Committees.test.tsx @@ -131,8 +131,5 @@ describe('Committees Component', () => { }) //suppose index_key is committee_1 expect(navigateMock).toHaveBeenCalledWith('/committees/committee_1') - - // Clean up the mock - jest.restoreAllMocks() }) }) diff --git a/frontend/__tests__/src/pages/Contribute.test.tsx b/frontend/__tests__/src/pages/Contribute.test.tsx index c1c04961f..562d82c17 100644 --- a/frontend/__tests__/src/pages/Contribute.test.tsx +++ b/frontend/__tests__/src/pages/Contribute.test.tsx @@ -258,8 +258,8 @@ describe('Contribute Component', () => { const mockMultipleIssues = { ...mockContributeData, hits: [ - { title: 'Issue 1', summary: 'Summary 1', hint: 'Hint 1' }, - { title: 'Issue 2', summary: 'Summary 2', hint: 'Hint 2' }, + { title: 'Issue 1', summary: 'Summary 1', hint: 'Hint 1', objectID: '1' }, + { title: 'Issue 2', summary: 'Summary 2', hint: 'Hint 2', objectID: '2' }, ], } ;(fetchAlgoliaData as jest.Mock).mockResolvedValue(mockMultipleIssues) diff --git a/frontend/__tests__/src/pages/ProjectDetails.test.tsx b/frontend/__tests__/src/pages/ProjectDetails.test.tsx index b831f8d39..ffb156e9e 100644 --- a/frontend/__tests__/src/pages/ProjectDetails.test.tsx +++ b/frontend/__tests__/src/pages/ProjectDetails.test.tsx @@ -1,23 +1,26 @@ -import { screen, waitFor } from '@testing-library/react' +import { within } from '@testing-library/dom' +import { screen, waitFor, fireEvent } from '@testing-library/react' import { fetchAlgoliaData } from 'api/fetchAlgoliaData' +import { useNavigate } from 'react-router-dom' import { render } from 'wrappers/testUtil' -import ProjectDetailsPage from 'pages/ProjectDetails' +import ProjectDetailsPage, { formatDate } from 'pages/ProjectDetails' import { mockProjectDetailsData } from '@tests/data/mockProjectDetailsData' jest.mock('api/fetchAlgoliaData') jest.mock('react-router-dom', () => ({ ...jest.requireActual('react-router-dom'), - useParams: () => ({ - projectKey: 'test-project', - }), + useParams: () => ({ projectKey: 'test-project' }), + useNavigate: jest.fn(), })) -describe('ProjectDetailsPage Component', () => { +describe('ProjectDetailsPage', () => { + let navigateMock: jest.Mock + beforeEach(() => { + navigateMock = jest.fn() + ;(useNavigate as jest.Mock).mockImplementation(() => navigateMock) ;(fetchAlgoliaData as jest.Mock).mockImplementation(() => - Promise.resolve({ - hits: [mockProjectDetailsData], - }) + Promise.resolve({ hits: [mockProjectDetailsData] }) ) }) @@ -25,20 +28,180 @@ describe('ProjectDetailsPage Component', () => { jest.clearAllMocks() }) - test('topics visibility check', async () => { + test('displays error when project is not found', async () => { + ;(fetchAlgoliaData as jest.Mock).mockImplementationOnce(() => Promise.resolve({ hits: [] })) render() + + await waitFor(() => { + expect(screen.getByText('Project not found')).toBeInTheDocument() + expect( + screen.getByText("Sorry, the project you're looking for doesn't exist") + ).toBeInTheDocument() + }) + }) + + test('renders project details when project is found', async () => { + render() + + await waitFor(() => { + expect(screen.getByText(mockProjectDetailsData.name)).toBeInTheDocument() + expect(screen.getByText(mockProjectDetailsData.description)).toBeInTheDocument() + expect(screen.getByText('Project Details')).toBeInTheDocument() + expect(screen.getByText('Statistics')).toBeInTheDocument() + expect(screen.getByText('Top Contributors')).toBeInTheDocument() + expect(screen.getByText('Recent Issues')).toBeInTheDocument() + expect(screen.getByText('Recent Releases')).toBeInTheDocument() + }) + }) + + test('formats date correctly using formatDate function', () => { + const timestamp = 1674249600 // January 21, 2023 (UTC) + const formatted = formatDate(timestamp) + expect(formatted).toContain('2023') + }) + + test('toggles languages list when show more/less is clicked', async () => { + const projectWithManyLanguages = { + ...mockProjectDetailsData, + languages: Array.from({ length: 12 }, (_, i) => `Language ${i + 1}`), + } + ;(fetchAlgoliaData as jest.Mock).mockImplementationOnce(() => + Promise.resolve({ hits: [projectWithManyLanguages] }) + ) + + render() + await waitFor(() => { + expect(screen.getByText('Language 10')).toBeInTheDocument() + expect(screen.queryByText('Language 11')).not.toBeInTheDocument() + }) + + const languagesSection = screen.getByRole('heading', { name: /Languages/i }).closest('div') + const showMoreButton = within(languagesSection!).getByRole('button', { name: /Show more/i }) + fireEvent.click(showMoreButton) + + await waitFor(() => { + expect(screen.getByText('Language 11')).toBeInTheDocument() + expect(screen.getByText('Language 12')).toBeInTheDocument() + }) + + const showLessButton = within(languagesSection!).getByRole('button', { name: /Show less/i }) + fireEvent.click(showLessButton) + await waitFor(() => { - expect(screen.getByText('Topic 1')).toBeInTheDocument() + expect(screen.queryByText('Language 11')).not.toBeInTheDocument() }) - expect(screen.queryByText('Topic 11')).not.toBeInTheDocument() }) - test('contributors visibility check', async () => { + test('toggles topics list when show more/less is clicked', async () => { + const projectWithManyTopics = { + ...mockProjectDetailsData, + topics: Array.from({ length: 12 }, (_, i) => `Topic ${i + 1}`), + } + ;(fetchAlgoliaData as jest.Mock).mockImplementationOnce(() => + Promise.resolve({ hits: [projectWithManyTopics] }) + ) + + render() + await waitFor(() => { + expect(screen.getByText('Topic 10')).toBeInTheDocument() + expect(screen.queryByText('Topic 11')).not.toBeInTheDocument() + }) + + const topicsSection = screen.getByRole('heading', { name: /Topics/i }).closest('div') + const showMoreButton = within(topicsSection!).getByRole('button', { name: /Show more/i }) + fireEvent.click(showMoreButton) + + await waitFor(() => { + expect(screen.getByText('Topic 11')).toBeInTheDocument() + expect(screen.getByText('Topic 12')).toBeInTheDocument() + }) + + const showLessButton = within(topicsSection!).getByRole('button', { name: /Show less/i }) + fireEvent.click(showLessButton) + + await waitFor(() => { + expect(screen.queryByText('Topic 11')).not.toBeInTheDocument() + }) + }) + + test('toggles contributors list when show more/less is clicked', async () => { + const projectWithManyContributors = { + ...mockProjectDetailsData, + top_contributors: Array.from({ length: 8 }, (_, i) => ({ + login: `contributor${i + 1}`, + name: `Contributor ${i + 1}`, + avatar_url: 'https://example.com/avatarX.jpg', + contributions_count: i * 10, + })), + } + ;(fetchAlgoliaData as jest.Mock).mockImplementationOnce(() => + Promise.resolve({ hits: [projectWithManyContributors] }) + ) + + render() + await waitFor(() => { + expect(screen.getByText('Contributor 6')).toBeInTheDocument() + expect(screen.queryByText('Contributor 7')).not.toBeInTheDocument() + }) + + const contributorsSection = screen + .getByRole('heading', { name: /Top Contributors/i }) + .closest('div') + const showMoreButton = within(contributorsSection!).getByRole('button', { name: /Show more/i }) + fireEvent.click(showMoreButton) + + await waitFor(() => { + expect(screen.getByText('Contributor 7')).toBeInTheDocument() + expect(screen.getByText('Contributor 8')).toBeInTheDocument() + }) + + const showLessButton = within(contributorsSection!).getByRole('button', { name: /Show less/i }) + fireEvent.click(showLessButton) + + await waitFor(() => { + expect(screen.queryByText('Contributor 7')).not.toBeInTheDocument() + }) + }) + + test('displays "No recent issues" when there are no issues', async () => { + const projectNoIssues = { + ...mockProjectDetailsData, + issues: [], + } + ;(fetchAlgoliaData as jest.Mock).mockImplementationOnce(() => + Promise.resolve({ hits: [projectNoIssues] }) + ) + + render() + await waitFor(() => { + expect(screen.getByText('No recent issues.')).toBeInTheDocument() + }) + }) + + test('displays "No recent releases" when there are no releases', async () => { + const projectNoReleases = { + ...mockProjectDetailsData, + releases: [], + } + ;(fetchAlgoliaData as jest.Mock).mockImplementationOnce(() => + Promise.resolve({ hits: [projectNoReleases] }) + ) + + render() + await waitFor(() => { + expect(screen.getByText('No recent releases.')).toBeInTheDocument() + }) + }) + + test('navigates to user page when contributor is clicked', async () => { render() await waitFor(() => { expect(screen.getByText('Contributor 1')).toBeInTheDocument() }) - expect(screen.queryByText('Contributor 6')).not.toBeInTheDocument() + + screen.getByText('Contributor 1').closest('div')?.click() + + expect(navigateMock).toHaveBeenCalledWith('/community/users/contributor1') }) test('handles contributors with missing names gracefully', async () => { @@ -52,11 +215,8 @@ describe('ProjectDetailsPage Component', () => { }, ], } - - ;(fetchAlgoliaData as jest.Mock).mockImplementation(() => - Promise.resolve({ - hits: [projectDataWithIncompleteContributors], - }) + ;(fetchAlgoliaData as jest.Mock).mockImplementationOnce(() => + Promise.resolve({ hits: [projectDataWithIncompleteContributors] }) ) render() diff --git a/frontend/__tests__/src/pages/UserDetails.test.tsx b/frontend/__tests__/src/pages/UserDetails.test.tsx index 2fb2de1ba..0237fb53e 100644 --- a/frontend/__tests__/src/pages/UserDetails.test.tsx +++ b/frontend/__tests__/src/pages/UserDetails.test.tsx @@ -94,4 +94,19 @@ describe('UserDetailsPage', () => { expect(screen.getByText('User not found')).toBeInTheDocument() }) }) + test('logs error to logger when fetchUserData fails', async () => { + const { fetchAlgoliaData } = require('api/fetchAlgoliaData') + const logger = require('utils/logger') + logger.error.mockClear() + + fetchAlgoliaData.mockRejectedValueOnce(new Error('Test fetch error')) + + await act(async () => { + renderWithRouter() + }) + + await waitFor(() => { + expect(logger.error).toHaveBeenCalledWith(expect.any(Error)) + }) + }) }) diff --git a/frontend/__tests__/src/pages/Users.test.tsx b/frontend/__tests__/src/pages/Users.test.tsx index 227cdd83c..f12617140 100644 --- a/frontend/__tests__/src/pages/Users.test.tsx +++ b/frontend/__tests__/src/pages/Users.test.tsx @@ -125,4 +125,23 @@ describe('UsersPage Component', () => { expect(navigateMock).toHaveBeenCalledWith('/community/users/user_1') }) + test('renders fallback username if user name is missing', async () => { + ;(fetchAlgoliaData as jest.Mock).mockResolvedValue({ + hits: [ + { + key: 'user_3', + login: 'fallback_login', + avatar_url: 'https://example.com/avatar.jpg', + company: 'Some Company', + }, + ], + totalPages: 1, + }) + + render() + + await waitFor(() => { + expect(screen.getByText('@fallback_login')).toBeInTheDocument() + }) + }) }) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index f52f709b8..dbdd3ef0f 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -11,19 +11,24 @@ "@algolia/autocomplete-js": "^1.17.9", "@algolia/autocomplete-plugin-query-suggestions": "^1.17.9", "@algolia/autocomplete-theme-classic": "^1.17.9", + "@chakra-ui/react": "^3.4.0", + "@emotion/react": "^11.14.0", + "@emotion/styled": "^11.14.0", "@fortawesome/fontawesome-svg-core": "^6.7.0", "@fortawesome/free-brands-svg-icons": "^6.7.0", "@fortawesome/free-regular-svg-icons": "^6.7.0", "@fortawesome/free-solid-svg-icons": "^6.7.0", "@fortawesome/react-fontawesome": "^0.2.2", + "@radix-ui/react-dropdown-menu": "^2.1.4", + "@radix-ui/react-select": "^2.1.4", "@radix-ui/react-slot": "^1.1.1", "@radix-ui/react-toast": "^1.2.4", "@sentry/browser": "^8.46.0", - "@sentry/react": "^8.48.0", + "@sentry/react": "^8.51.0", "@sentry/tracing": "^7.120.3", - "@testing-library/user-event": "^14.6.0", + "@testing-library/user-event": "^14.6.1", "@types/lodash": "^4.17.14", - "algoliasearch": "^5.19.0", + "algoliasearch": "^5.20.0", "axios": "^1.7.9", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", @@ -47,18 +52,18 @@ }, "devDependencies": { "@eslint/js": "^9.15.0", - "@swc/core": "^1.10.7", + "@swc/core": "^1.10.9", "@swc/jest": "^0.2.37", "@testing-library/jest-dom": "^6.6.3", "@testing-library/react": "^16.2.0", "@types/jest": "^29.5.14", "@types/mocha": "^10.0.10", - "@types/node": "^22.10.7", + "@types/node": "^22.10.8", "@types/react": "^19.0.6", "@types/react-dom": "^19.0.3", "@types/react-gtm-module": "^2.0.4", - "@typescript-eslint/eslint-plugin": "^8.18.0", - "@typescript-eslint/parser": "^8.20.0", + "@typescript-eslint/eslint-plugin": "^8.21.0", + "@typescript-eslint/parser": "^8.21.0", "@vitejs/plugin-react": "^4.3.4", "autoprefixer": "^10.4.20", "babel-plugin-transform-import-meta": "^2.3.2", @@ -83,9 +88,9 @@ "ts-jest": "^29.2.5", "ts-node": "^10.9.2", "typescript": "~5.7.3", - "typescript-eslint": "^8.19.1", + "typescript-eslint": "^8.21.0", "util": "^0.12.5", - "vite": "^6.0.8", + "vite": "^6.0.11", "vite-plugin-environment": "^1.1.3" }, "engines": { @@ -184,180 +189,180 @@ "license": "MIT" }, "node_modules/@algolia/client-abtesting": { - "version": "5.19.0", - "resolved": "https://registry.npmjs.org/@algolia/client-abtesting/-/client-abtesting-5.19.0.tgz", - "integrity": "sha512-dMHwy2+nBL0SnIsC1iHvkBao64h4z+roGelOz11cxrDBrAdASxLxmfVMop8gmodQ2yZSacX0Rzevtxa+9SqxCw==", + "version": "5.20.0", + "resolved": "https://registry.npmjs.org/@algolia/client-abtesting/-/client-abtesting-5.20.0.tgz", + "integrity": "sha512-YaEoNc1Xf2Yk6oCfXXkZ4+dIPLulCx8Ivqj0OsdkHWnsI3aOJChY5qsfyHhDBNSOhqn2ilgHWxSfyZrjxBcAww==", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.19.0", - "@algolia/requester-browser-xhr": "5.19.0", - "@algolia/requester-fetch": "5.19.0", - "@algolia/requester-node-http": "5.19.0" + "@algolia/client-common": "5.20.0", + "@algolia/requester-browser-xhr": "5.20.0", + "@algolia/requester-fetch": "5.20.0", + "@algolia/requester-node-http": "5.20.0" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/client-analytics": { - "version": "5.19.0", - "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-5.19.0.tgz", - "integrity": "sha512-CDW4RwnCHzU10upPJqS6N6YwDpDHno7w6/qXT9KPbPbt8szIIzCHrva4O9KIfx1OhdsHzfGSI5hMAiOOYl4DEQ==", + "version": "5.20.0", + "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-5.20.0.tgz", + "integrity": "sha512-CIT9ni0+5sYwqehw+t5cesjho3ugKQjPVy/iPiJvtJX4g8Cdb6je6SPt2uX72cf2ISiXCAX9U3cY0nN0efnRDw==", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.19.0", - "@algolia/requester-browser-xhr": "5.19.0", - "@algolia/requester-fetch": "5.19.0", - "@algolia/requester-node-http": "5.19.0" + "@algolia/client-common": "5.20.0", + "@algolia/requester-browser-xhr": "5.20.0", + "@algolia/requester-fetch": "5.20.0", + "@algolia/requester-node-http": "5.20.0" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/client-common": { - "version": "5.19.0", - "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.19.0.tgz", - "integrity": "sha512-2ERRbICHXvtj5kfFpY5r8qu9pJII/NAHsdgUXnUitQFwPdPL7wXiupcvZJC7DSntOnE8AE0lM7oDsPhrJfj5nQ==", + "version": "5.20.0", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.20.0.tgz", + "integrity": "sha512-iSTFT3IU8KNpbAHcBUJw2HUrPnMXeXLyGajmCL7gIzWOsYM4GabZDHXOFx93WGiXMti1dymz8k8R+bfHv1YZmA==", "license": "MIT", "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/client-insights": { - "version": "5.19.0", - "resolved": "https://registry.npmjs.org/@algolia/client-insights/-/client-insights-5.19.0.tgz", - "integrity": "sha512-xPOiGjo6I9mfjdJO7Y+p035aWePcbsItizIp+qVyfkfZiGgD+TbNxM12g7QhFAHIkx/mlYaocxPY/TmwPzTe+A==", + "version": "5.20.0", + "resolved": "https://registry.npmjs.org/@algolia/client-insights/-/client-insights-5.20.0.tgz", + "integrity": "sha512-w9RIojD45z1csvW1vZmAko82fqE/Dm+Ovsy2ElTsjFDB0HMAiLh2FO86hMHbEXDPz6GhHKgGNmBRiRP8dDPgJg==", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.19.0", - "@algolia/requester-browser-xhr": "5.19.0", - "@algolia/requester-fetch": "5.19.0", - "@algolia/requester-node-http": "5.19.0" + "@algolia/client-common": "5.20.0", + "@algolia/requester-browser-xhr": "5.20.0", + "@algolia/requester-fetch": "5.20.0", + "@algolia/requester-node-http": "5.20.0" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/client-personalization": { - "version": "5.19.0", - "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-5.19.0.tgz", - "integrity": "sha512-B9eoce/fk8NLboGje+pMr72pw+PV7c5Z01On477heTZ7jkxoZ4X92dobeGuEQop61cJ93Gaevd1of4mBr4hu2A==", + "version": "5.20.0", + "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-5.20.0.tgz", + "integrity": "sha512-p/hftHhrbiHaEcxubYOzqVV4gUqYWLpTwK+nl2xN3eTrSW9SNuFlAvUBFqPXSVBqc6J5XL9dNKn3y8OA1KElSQ==", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.19.0", - "@algolia/requester-browser-xhr": "5.19.0", - "@algolia/requester-fetch": "5.19.0", - "@algolia/requester-node-http": "5.19.0" + "@algolia/client-common": "5.20.0", + "@algolia/requester-browser-xhr": "5.20.0", + "@algolia/requester-fetch": "5.20.0", + "@algolia/requester-node-http": "5.20.0" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/client-query-suggestions": { - "version": "5.19.0", - "resolved": "https://registry.npmjs.org/@algolia/client-query-suggestions/-/client-query-suggestions-5.19.0.tgz", - "integrity": "sha512-6fcP8d4S8XRDtVogrDvmSM6g5g6DndLc0pEm1GCKe9/ZkAzCmM3ZmW1wFYYPxdjMeifWy1vVEDMJK7sbE4W7MA==", + "version": "5.20.0", + "resolved": "https://registry.npmjs.org/@algolia/client-query-suggestions/-/client-query-suggestions-5.20.0.tgz", + "integrity": "sha512-m4aAuis5vZi7P4gTfiEs6YPrk/9hNTESj3gEmGFgfJw3hO2ubdS4jSId1URd6dGdt0ax2QuapXufcrN58hPUcw==", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.19.0", - "@algolia/requester-browser-xhr": "5.19.0", - "@algolia/requester-fetch": "5.19.0", - "@algolia/requester-node-http": "5.19.0" + "@algolia/client-common": "5.20.0", + "@algolia/requester-browser-xhr": "5.20.0", + "@algolia/requester-fetch": "5.20.0", + "@algolia/requester-node-http": "5.20.0" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/client-search": { - "version": "5.19.0", - "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.19.0.tgz", - "integrity": "sha512-Ctg3xXD/1VtcwmkulR5+cKGOMj4r0wC49Y/KZdGQcqpydKn+e86F6l3tb3utLJQVq4lpEJud6kdRykFgcNsp8Q==", + "version": "5.20.0", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.20.0.tgz", + "integrity": "sha512-KL1zWTzrlN4MSiaK1ea560iCA/UewMbS4ZsLQRPoDTWyrbDKVbztkPwwv764LAqgXk0fvkNZvJ3IelcK7DqhjQ==", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.19.0", - "@algolia/requester-browser-xhr": "5.19.0", - "@algolia/requester-fetch": "5.19.0", - "@algolia/requester-node-http": "5.19.0" + "@algolia/client-common": "5.20.0", + "@algolia/requester-browser-xhr": "5.20.0", + "@algolia/requester-fetch": "5.20.0", + "@algolia/requester-node-http": "5.20.0" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/ingestion": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/@algolia/ingestion/-/ingestion-1.19.0.tgz", - "integrity": "sha512-LO7w1MDV+ZLESwfPmXkp+KLeYeFrYEgtbCZG6buWjddhYraPQ9MuQWLhLLiaMlKxZ/sZvFTcZYuyI6Jx4WBhcg==", + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/@algolia/ingestion/-/ingestion-1.20.0.tgz", + "integrity": "sha512-shj2lTdzl9un4XJblrgqg54DoK6JeKFO8K8qInMu4XhE2JuB8De6PUuXAQwiRigZupbI0xq8aM0LKdc9+qiLQA==", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.19.0", - "@algolia/requester-browser-xhr": "5.19.0", - "@algolia/requester-fetch": "5.19.0", - "@algolia/requester-node-http": "5.19.0" + "@algolia/client-common": "5.20.0", + "@algolia/requester-browser-xhr": "5.20.0", + "@algolia/requester-fetch": "5.20.0", + "@algolia/requester-node-http": "5.20.0" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/monitoring": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/@algolia/monitoring/-/monitoring-1.19.0.tgz", - "integrity": "sha512-Mg4uoS0aIKeTpu6iv6O0Hj81s8UHagi5TLm9k2mLIib4vmMtX7WgIAHAcFIaqIZp5D6s5EVy1BaDOoZ7buuJHA==", + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/@algolia/monitoring/-/monitoring-1.20.0.tgz", + "integrity": "sha512-aF9blPwOhKtWvkjyyXh9P5peqmhCA1XxLBRgItT+K6pbT0q4hBDQrCid+pQZJYy4HFUKjB/NDDwyzFhj/rwKhw==", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.19.0", - "@algolia/requester-browser-xhr": "5.19.0", - "@algolia/requester-fetch": "5.19.0", - "@algolia/requester-node-http": "5.19.0" + "@algolia/client-common": "5.20.0", + "@algolia/requester-browser-xhr": "5.20.0", + "@algolia/requester-fetch": "5.20.0", + "@algolia/requester-node-http": "5.20.0" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/recommend": { - "version": "5.19.0", - "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-5.19.0.tgz", - "integrity": "sha512-PbgrMTbUPlmwfJsxjFhal4XqZO2kpBNRjemLVTkUiti4w/+kzcYO4Hg5zaBgVqPwvFDNQ8JS4SS3TBBem88u+g==", + "version": "5.20.0", + "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-5.20.0.tgz", + "integrity": "sha512-T6B/WPdZR3b89/F9Vvk6QCbt/wrLAtrGoL8z4qPXDFApQ8MuTFWbleN/4rHn6APWO3ps+BUePIEbue2rY5MlRw==", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.19.0", - "@algolia/requester-browser-xhr": "5.19.0", - "@algolia/requester-fetch": "5.19.0", - "@algolia/requester-node-http": "5.19.0" + "@algolia/client-common": "5.20.0", + "@algolia/requester-browser-xhr": "5.20.0", + "@algolia/requester-fetch": "5.20.0", + "@algolia/requester-node-http": "5.20.0" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/requester-browser-xhr": { - "version": "5.19.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.19.0.tgz", - "integrity": "sha512-GfnhnQBT23mW/VMNs7m1qyEyZzhZz093aY2x8p0era96MMyNv8+FxGek5pjVX0b57tmSCZPf4EqNCpkGcGsmbw==", + "version": "5.20.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.20.0.tgz", + "integrity": "sha512-t6//lXsq8E85JMenHrI6mhViipUT5riNhEfCcvtRsTV+KIBpC6Od18eK864dmBhoc5MubM0f+sGpKOqJIlBSCg==", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.19.0" + "@algolia/client-common": "5.20.0" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/requester-fetch": { - "version": "5.19.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-fetch/-/requester-fetch-5.19.0.tgz", - "integrity": "sha512-oyTt8ZJ4T4fYvW5avAnuEc6Laedcme9fAFryMD9ndUTIUe/P0kn3BuGcCLFjN3FDmdrETHSFkgPPf1hGy3sLCw==", + "version": "5.20.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-fetch/-/requester-fetch-5.20.0.tgz", + "integrity": "sha512-FHxYGqRY+6bgjKsK4aUsTAg6xMs2S21elPe4Y50GB0Y041ihvw41Vlwy2QS6K9ldoftX4JvXodbKTcmuQxywdQ==", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.19.0" + "@algolia/client-common": "5.20.0" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/requester-node-http": { - "version": "5.19.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.19.0.tgz", - "integrity": "sha512-p6t8ue0XZNjcRiqNkb5QAM0qQRAKsCiebZ6n9JjWA+p8fWf8BvnhO55y2fO28g3GW0Imj7PrAuyBuxq8aDVQwQ==", + "version": "5.20.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.20.0.tgz", + "integrity": "sha512-kmtQClq/w3vtPteDSPvaW9SPZL/xrIgMrxZyAgsFwrJk0vJxqyC5/hwHmrCraDnStnGSADnLpBf4SpZnwnkwWw==", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.19.0" + "@algolia/client-common": "5.20.0" }, "engines": { "node": ">= 14.0.0" @@ -389,6 +394,70 @@ "node": ">=6.0.0" } }, + "node_modules/@ark-ui/react": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/@ark-ui/react/-/react-4.8.1.tgz", + "integrity": "sha512-KjWQWyg5I95RJFNosNMWFjbDSSoN5SQRR1vorbP0n8kukzRIS0hJKX64JPOdfW5ndyp2gQ3OVN65WaFQDwM0pA==", + "license": "MIT", + "dependencies": { + "@internationalized/date": "3.6.0", + "@zag-js/accordion": "0.81.2", + "@zag-js/anatomy": "0.81.2", + "@zag-js/auto-resize": "0.81.2", + "@zag-js/avatar": "0.81.2", + "@zag-js/carousel": "0.81.2", + "@zag-js/checkbox": "0.81.2", + "@zag-js/clipboard": "0.81.2", + "@zag-js/collapsible": "0.81.2", + "@zag-js/collection": "0.81.2", + "@zag-js/color-picker": "0.81.2", + "@zag-js/color-utils": "0.81.2", + "@zag-js/combobox": "0.81.2", + "@zag-js/core": "0.81.2", + "@zag-js/date-picker": "0.81.2", + "@zag-js/date-utils": "0.81.2", + "@zag-js/dialog": "0.81.2", + "@zag-js/dom-query": "0.81.2", + "@zag-js/editable": "0.81.2", + "@zag-js/file-upload": "0.81.2", + "@zag-js/file-utils": "0.81.2", + "@zag-js/focus-trap": "0.81.2", + "@zag-js/highlight-word": "0.81.2", + "@zag-js/hover-card": "0.81.2", + "@zag-js/i18n-utils": "0.81.2", + "@zag-js/menu": "0.81.2", + "@zag-js/number-input": "0.81.2", + "@zag-js/pagination": "0.81.2", + "@zag-js/pin-input": "0.81.2", + "@zag-js/popover": "0.81.2", + "@zag-js/presence": "0.81.2", + "@zag-js/progress": "0.81.2", + "@zag-js/qr-code": "0.81.2", + "@zag-js/radio-group": "0.81.2", + "@zag-js/rating-group": "0.81.2", + "@zag-js/react": "0.81.2", + "@zag-js/select": "0.81.2", + "@zag-js/signature-pad": "0.81.2", + "@zag-js/slider": "0.81.2", + "@zag-js/splitter": "0.81.2", + "@zag-js/steps": "0.81.2", + "@zag-js/switch": "0.81.2", + "@zag-js/tabs": "0.81.2", + "@zag-js/tags-input": "0.81.2", + "@zag-js/time-picker": "0.81.2", + "@zag-js/timer": "0.81.2", + "@zag-js/toast": "0.81.2", + "@zag-js/toggle-group": "0.81.2", + "@zag-js/tooltip": "0.81.2", + "@zag-js/tour": "0.81.2", + "@zag-js/tree-view": "0.81.2", + "@zag-js/types": "0.81.2" + }, + "peerDependencies": { + "react": ">=18.0.0", + "react-dom": ">=18.0.0" + } + }, "node_modules/@babel/code-frame": { "version": "7.26.2", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", @@ -448,7 +517,6 @@ "version": "7.26.5", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.5.tgz", "integrity": "sha512-2caSP6fN9I7HOe6nqhtft7V4g7/V/gfDsC3Ag4W7kEzzvRGKqiv0pu0HogPiZ3KaVSoNDhUws6IJjDjpfmYIXw==", - "dev": true, "license": "MIT", "dependencies": { "@babel/parser": "^7.26.5", @@ -482,7 +550,6 @@ "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", - "dev": true, "license": "MIT", "dependencies": { "@babel/traverse": "^7.25.9", @@ -524,7 +591,6 @@ "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", - "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -567,7 +633,6 @@ "version": "7.26.5", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.5.tgz", "integrity": "sha512-SRJ4jYmXRqV1/Xc+TIVG84WjHBXKlxO9sHQnA2Pf12QQEAp1LOh6kDzNHXcUnbH1QI0FDoPPVOt+vyUDucxpaw==", - "dev": true, "license": "MIT", "dependencies": { "@babel/types": "^7.26.5" @@ -866,7 +931,6 @@ "version": "7.25.9", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz", "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==", - "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.25.9", @@ -881,7 +945,6 @@ "version": "7.26.5", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.5.tgz", "integrity": "sha512-rkOSPOw+AXbgtwUga3U4u8RpoK9FEFWBNAlTpcnkLFjL5CT+oyHNuUUC/xx6XefEJ16r38r8Bc/lfp6rYuHeJQ==", - "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.26.2", @@ -900,7 +963,6 @@ "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, "license": "MIT", "engines": { "node": ">=4" @@ -910,7 +972,6 @@ "version": "7.26.5", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.5.tgz", "integrity": "sha512-L6mZmwFDK6Cjh1nRCLXpa6no13ZIioJDz7mdkzHv399pThrTa/k0nUlNaenOeh2kWu/iaOQYElEpKPUswUa9Vg==", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.25.9", @@ -927,6 +988,26 @@ "dev": true, "license": "MIT" }, + "node_modules/@chakra-ui/react": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@chakra-ui/react/-/react-3.4.0.tgz", + "integrity": "sha512-ImnUqpZspxVbEMiKUbkIb1ReA9sXioQawKMbW/bGY21O3MjPpNPs9KX1bMk5n4VfsEUlyN0BXwK51lqhFDCEUg==", + "license": "MIT", + "dependencies": { + "@ark-ui/react": "4.8.1", + "@emotion/is-prop-valid": "1.3.1", + "@emotion/serialize": "1.3.3", + "@emotion/use-insertion-effect-with-fallbacks": "1.2.0", + "@emotion/utils": "1.4.2", + "@pandacss/is-valid-prop": "0.41.0", + "csstype": "3.1.3" + }, + "peerDependencies": { + "@emotion/react": ">=11", + "react": ">=18", + "react-dom": ">=18" + } + }, "node_modules/@cspotcode/source-map-support": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", @@ -951,6 +1032,167 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, + "node_modules/@emotion/babel-plugin": { + "version": "11.13.5", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.13.5.tgz", + "integrity": "sha512-pxHCpT2ex+0q+HH91/zsdHkw/lXd468DIN2zvfvLtPKLLMo6gQj7oLObq8PhkrxOZb/gGCq03S3Z7PDhS8pduQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.16.7", + "@babel/runtime": "^7.18.3", + "@emotion/hash": "^0.9.2", + "@emotion/memoize": "^0.9.0", + "@emotion/serialize": "^1.3.3", + "babel-plugin-macros": "^3.1.0", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^4.0.0", + "find-root": "^1.1.0", + "source-map": "^0.5.7", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/babel-plugin/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "license": "MIT" + }, + "node_modules/@emotion/babel-plugin/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@emotion/cache": { + "version": "11.14.0", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.14.0.tgz", + "integrity": "sha512-L/B1lc/TViYk4DcpGxtAVbx0ZyiKM5ktoIyafGkH6zg/tj+mA+NE//aPYKG0k8kCHSHVJrpLpcAlOBEXQ3SavA==", + "license": "MIT", + "dependencies": { + "@emotion/memoize": "^0.9.0", + "@emotion/sheet": "^1.4.0", + "@emotion/utils": "^1.4.2", + "@emotion/weak-memoize": "^0.4.0", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/hash": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz", + "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==", + "license": "MIT" + }, + "node_modules/@emotion/is-prop-valid": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.3.1.tgz", + "integrity": "sha512-/ACwoqx7XQi9knQs/G0qKvv5teDMhD7bXYns9N/wM8ah8iNb8jZ2uNO0YOgiq2o2poIvVtJS2YALasQuMSQ7Kw==", + "license": "MIT", + "dependencies": { + "@emotion/memoize": "^0.9.0" + } + }, + "node_modules/@emotion/memoize": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", + "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==", + "license": "MIT" + }, + "node_modules/@emotion/react": { + "version": "11.14.0", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.14.0.tgz", + "integrity": "sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.13.5", + "@emotion/cache": "^11.14.0", + "@emotion/serialize": "^1.3.3", + "@emotion/use-insertion-effect-with-fallbacks": "^1.2.0", + "@emotion/utils": "^1.4.2", + "@emotion/weak-memoize": "^0.4.0", + "hoist-non-react-statics": "^3.3.1" + }, + "peerDependencies": { + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/serialize": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.3.tgz", + "integrity": "sha512-EISGqt7sSNWHGI76hC7x1CksiXPahbxEOrC5RjmFRJTqLyEK9/9hZvBbiYn70dw4wuwMKiEMCUlR6ZXTSWQqxA==", + "license": "MIT", + "dependencies": { + "@emotion/hash": "^0.9.2", + "@emotion/memoize": "^0.9.0", + "@emotion/unitless": "^0.10.0", + "@emotion/utils": "^1.4.2", + "csstype": "^3.0.2" + } + }, + "node_modules/@emotion/sheet": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz", + "integrity": "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==", + "license": "MIT" + }, + "node_modules/@emotion/styled": { + "version": "11.14.0", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.14.0.tgz", + "integrity": "sha512-XxfOnXFffatap2IyCeJyNov3kiDQWoR08gPUQxvbL7fxKryGBKUZUkG6Hz48DZwVrJSVh9sJboyV1Ds4OW6SgA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.13.5", + "@emotion/is-prop-valid": "^1.3.0", + "@emotion/serialize": "^1.3.3", + "@emotion/use-insertion-effect-with-fallbacks": "^1.2.0", + "@emotion/utils": "^1.4.2" + }, + "peerDependencies": { + "@emotion/react": "^11.0.0-rc.0", + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/unitless": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.10.0.tgz", + "integrity": "sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==", + "license": "MIT" + }, + "node_modules/@emotion/use-insertion-effect-with-fallbacks": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.2.0.tgz", + "integrity": "sha512-yJMtVdH59sxi/aVJBpk9FQq+OR8ll5GT8oWd57UpeaKEVGab41JWaCFA7FRLoMLloOZF/c/wsPoe+bfGmRKgDg==", + "license": "MIT", + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@emotion/utils": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.2.tgz", + "integrity": "sha512-3vLclRofFziIa3J2wDh9jjbkUz9qk5Vi3IZ/FSTKViB0k+ef0fPV7dYrUIugbgupYDx7v9ud/SjrtEP8Y4xLoA==", + "license": "MIT" + }, + "node_modules/@emotion/weak-memoize": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz", + "integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==", + "license": "MIT" + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.24.2", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.2.tgz", @@ -1571,6 +1813,19 @@ "@floating-ui/utils": "^0.2.9" } }, + "node_modules/@floating-ui/react-dom": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.2.tgz", + "integrity": "sha512-06okr5cgPzMNBy+Ycse2A6udMi4bqwW/zgBF/rwjcNqWkyr82Mcg8b0vjX8OJpZFy/FKjJmw6wV7t44kK6kW7A==", + "license": "MIT", + "dependencies": { + "@floating-ui/dom": "^1.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, "node_modules/@floating-ui/utils": { "version": "0.2.9", "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.9.tgz", @@ -1713,6 +1968,24 @@ "url": "https://github.com/sponsors/nzakas" } }, + "node_modules/@internationalized/date": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@internationalized/date/-/date-3.6.0.tgz", + "integrity": "sha512-+z6ti+CcJnRlLHok/emGEsWQhe7kfSmEW+/6qCzvKY67YPh7YOBfvc7+/+NXq+zJlbArg30tYpqLjNgcAYv2YQ==", + "license": "Apache-2.0", + "dependencies": { + "@swc/helpers": "^0.5.0" + } + }, + "node_modules/@internationalized/number": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@internationalized/number/-/number-3.6.0.tgz", + "integrity": "sha512-PtrRcJVy7nw++wn4W2OuePQQfTqDzfusSuY1QTtui4wa7r+rGVtR75pO8CyKvHvzyQYi3Q1uO5sY0AsB4e65Bw==", + "license": "Apache-2.0", + "dependencies": { + "@swc/helpers": "^0.5.0" + } + }, "node_modules/@isaacs/cliui": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", @@ -2349,6 +2622,11 @@ "node": ">= 8" } }, + "node_modules/@pandacss/is-valid-prop": { + "version": "0.41.0", + "resolved": "https://registry.npmjs.org/@pandacss/is-valid-prop/-/is-valid-prop-0.41.0.tgz", + "integrity": "sha512-BE6h6CsJk14ugIRrsazJtN3fcg+KDFRat1Bs93YFKH6jd4DOb1yUyVvC70jKqPVvg70zEcV8acZ7VdcU5TLu+w==" + }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", @@ -2372,12 +2650,41 @@ "url": "https://opencollective.com/unts" } }, + "node_modules/@radix-ui/number": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.0.tgz", + "integrity": "sha512-V3gRzhVNU1ldS5XhAPTom1fOIo4ccrjjJgmE+LI2h/WaFpHmx0MQApT+KZHnx8abG6Avtfcz4WoEciMnpFT3HQ==", + "license": "MIT" + }, "node_modules/@radix-ui/primitive": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.1.tgz", "integrity": "sha512-SJ31y+Q/zAyShtXJc8x83i9TYdbAfHZ++tUZnvjJJqFjzsdUnKsxPL6IEtBlxKkU7yzer//GQtZSV4GbldL3YA==", "license": "MIT" }, + "node_modules/@radix-ui/react-arrow": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.1.tgz", + "integrity": "sha512-NaVpZfmv8SKeZbn4ijN2V3jlHA9ngBG16VnIIm22nUR0Yk8KUALyBxT3KYEUnNuch9sTE8UTsS3whzBgKOL30w==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-collection": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.1.tgz", @@ -2434,6 +2741,21 @@ } } }, + "node_modules/@radix-ui/react-direction": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.0.tgz", + "integrity": "sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-dismissable-layer": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.3.tgz", @@ -2461,14 +2783,19 @@ } } }, - "node_modules/@radix-ui/react-portal": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.3.tgz", - "integrity": "sha512-NciRqhXnGojhT93RPyDaMPfLH3ZSl4jjIFbZQ1b/vxvZEdHsBZ49wP9w8L3HzUQwep01LcWtkUvm0OVB5JAHTw==", + "node_modules/@radix-ui/react-dropdown-menu": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.1.4.tgz", + "integrity": "sha512-iXU1Ab5ecM+yEepGAWK8ZhMyKX4ubFdCNtol4sT9D0OVErG9PNElfx3TQhjw7n7BC5nFVz68/5//clWy+8TXzA==", "license": "MIT", "dependencies": { + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-menu": "2.1.4", "@radix-ui/react-primitive": "2.0.1", - "@radix-ui/react-use-layout-effect": "1.1.0" + "@radix-ui/react-use-controllable-state": "1.1.0" }, "peerDependencies": { "@types/react": "*", @@ -2485,37 +2812,30 @@ } } }, - "node_modules/@radix-ui/react-presence": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.2.tgz", - "integrity": "sha512-18TFr80t5EVgL9x1SwF/YGtfG+l0BS0PRAlCWBDoBEiDQjeKgnNZRVJp/oVBl24sr3Gbfwc/Qpj4OcWTQMsAEg==", + "node_modules/@radix-ui/react-focus-guards": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.1.tgz", + "integrity": "sha512-pSIwfrT1a6sIoDASCSpFwOasEwKTZWDw/iBdtnqKO7v6FeOzYJ7U53cPzYFVR3geGGXgVHaH+CdngrrAzqUGxg==", "license": "MIT", - "dependencies": { - "@radix-ui/react-compose-refs": "1.1.1", - "@radix-ui/react-use-layout-effect": "1.1.0" - }, "peerDependencies": { "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { "optional": true - }, - "@types/react-dom": { - "optional": true } } }, - "node_modules/@radix-ui/react-primitive": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.1.tgz", - "integrity": "sha512-sHCWTtxwNn3L3fH8qAfnF3WbUZycW93SM1j3NFDzXBiz8D6F5UTTy8G1+WFEaiCdvCVRJWj6N2R4Xq6HdiHmDg==", + "node_modules/@radix-ui/react-focus-scope": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.1.tgz", + "integrity": "sha512-01omzJAYRxXdG2/he/+xy+c8a8gCydoQ1yOxnWNcRhrrBW5W+RQJ22EK1SaO8tb3WoUsuEw7mJjBozPzihDFjA==", "license": "MIT", "dependencies": { - "@radix-ui/react-slot": "1.1.1" + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-use-callback-ref": "1.1.0" }, "peerDependencies": { "@types/react": "*", @@ -2532,13 +2852,13 @@ } } }, - "node_modules/@radix-ui/react-slot": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.1.tgz", - "integrity": "sha512-RApLLOcINYJA+dMVbOju7MYv1Mb2EBp2nH4HdDzXTSyaR5optlm6Otrz1euW3HbdOR8UmmFK06TD+A9frYWv+g==", + "node_modules/@radix-ui/react-id": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.0.tgz", + "integrity": "sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==", "license": "MIT", "dependencies": { - "@radix-ui/react-compose-refs": "1.1.1" + "@radix-ui/react-use-layout-effect": "1.1.0" }, "peerDependencies": { "@types/react": "*", @@ -2550,24 +2870,30 @@ } } }, - "node_modules/@radix-ui/react-toast": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@radix-ui/react-toast/-/react-toast-1.2.4.tgz", - "integrity": "sha512-Sch9idFJHJTMH9YNpxxESqABcAFweJG4tKv+0zo0m5XBvUSL8FM5xKcJLFLXononpePs8IclyX1KieL5SDUNgA==", + "node_modules/@radix-ui/react-menu": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.1.4.tgz", + "integrity": "sha512-BnOgVoL6YYdHAG6DtXONaR29Eq4nvbi8rutrV/xlr3RQCMMb3yqP85Qiw/3NReozrSW+4dfLkK+rc1hb4wPU/A==", "license": "MIT", "dependencies": { "@radix-ui/primitive": "1.1.1", "@radix-ui/react-collection": "1.1.1", "@radix-ui/react-compose-refs": "1.1.1", "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-direction": "1.1.0", "@radix-ui/react-dismissable-layer": "1.1.3", + "@radix-ui/react-focus-guards": "1.1.1", + "@radix-ui/react-focus-scope": "1.1.1", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-popper": "1.2.1", "@radix-ui/react-portal": "1.1.3", "@radix-ui/react-presence": "1.1.2", "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-roving-focus": "1.1.1", + "@radix-ui/react-slot": "1.1.1", "@radix-ui/react-use-callback-ref": "1.1.0", - "@radix-ui/react-use-controllable-state": "1.1.0", - "@radix-ui/react-use-layout-effect": "1.1.0", - "@radix-ui/react-visually-hidden": "1.1.1" + "aria-hidden": "^1.1.1", + "react-remove-scroll": "^2.6.1" }, "peerDependencies": { "@types/react": "*", @@ -2584,65 +2910,345 @@ } } }, - "node_modules/@radix-ui/react-use-callback-ref": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz", - "integrity": "sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==", + "node_modules/@radix-ui/react-popper": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.1.tgz", + "integrity": "sha512-3kn5Me69L+jv82EKRuQCXdYyf1DqHwD2U/sxoNgBGCB7K9TRc3bQamQ+5EPM9EvyPdli0W41sROd+ZU1dTCztw==", "license": "MIT", + "dependencies": { + "@floating-ui/react-dom": "^2.0.0", + "@radix-ui/react-arrow": "1.1.1", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0", + "@radix-ui/react-use-rect": "1.1.0", + "@radix-ui/react-use-size": "1.1.0", + "@radix-ui/rect": "1.1.0" + }, "peerDependencies": { "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { "optional": true + }, + "@types/react-dom": { + "optional": true } } }, - "node_modules/@radix-ui/react-use-controllable-state": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.1.0.tgz", - "integrity": "sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==", + "node_modules/@radix-ui/react-portal": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.3.tgz", + "integrity": "sha512-NciRqhXnGojhT93RPyDaMPfLH3ZSl4jjIFbZQ1b/vxvZEdHsBZ49wP9w8L3HzUQwep01LcWtkUvm0OVB5JAHTw==", "license": "MIT", "dependencies": { - "@radix-ui/react-use-callback-ref": "1.1.0" + "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-use-layout-effect": "1.1.0" }, "peerDependencies": { "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { "optional": true + }, + "@types/react-dom": { + "optional": true } } }, - "node_modules/@radix-ui/react-use-escape-keydown": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.0.tgz", - "integrity": "sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw==", + "node_modules/@radix-ui/react-presence": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.2.tgz", + "integrity": "sha512-18TFr80t5EVgL9x1SwF/YGtfG+l0BS0PRAlCWBDoBEiDQjeKgnNZRVJp/oVBl24sr3Gbfwc/Qpj4OcWTQMsAEg==", "license": "MIT", "dependencies": { - "@radix-ui/react-use-callback-ref": "1.1.0" + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-use-layout-effect": "1.1.0" }, "peerDependencies": { "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { "optional": true + }, + "@types/react-dom": { + "optional": true } } }, - "node_modules/@radix-ui/react-use-layout-effect": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz", - "integrity": "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==", + "node_modules/@radix-ui/react-primitive": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.1.tgz", + "integrity": "sha512-sHCWTtxwNn3L3fH8qAfnF3WbUZycW93SM1j3NFDzXBiz8D6F5UTTy8G1+WFEaiCdvCVRJWj6N2R4Xq6HdiHmDg==", "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.1.1" + }, "peerDependencies": { "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-roving-focus": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.1.tgz", + "integrity": "sha512-QE1RoxPGJ/Nm8Qmk0PxP8ojmoaS67i0s7hVssS7KuI2FQoc/uzVlZsqKfQvxPE6D8hICCPHJ4D88zNhT3OOmkw==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-collection": "1.1.1", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-direction": "1.1.0", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-controllable-state": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-select": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.1.4.tgz", + "integrity": "sha512-pOkb2u8KgO47j/h7AylCj7dJsm69BXcjkrvTqMptFqsE2i0p8lHkfgneXKjAgPzBMivnoMyt8o4KiV4wYzDdyQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/number": "1.1.0", + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-collection": "1.1.1", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-direction": "1.1.0", + "@radix-ui/react-dismissable-layer": "1.1.3", + "@radix-ui/react-focus-guards": "1.1.1", + "@radix-ui/react-focus-scope": "1.1.1", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-popper": "1.2.1", + "@radix-ui/react-portal": "1.1.3", + "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-slot": "1.1.1", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-controllable-state": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0", + "@radix-ui/react-use-previous": "1.1.0", + "@radix-ui/react-visually-hidden": "1.1.1", + "aria-hidden": "^1.1.1", + "react-remove-scroll": "^2.6.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-slot": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.1.tgz", + "integrity": "sha512-RApLLOcINYJA+dMVbOju7MYv1Mb2EBp2nH4HdDzXTSyaR5optlm6Otrz1euW3HbdOR8UmmFK06TD+A9frYWv+g==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-toast": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-toast/-/react-toast-1.2.4.tgz", + "integrity": "sha512-Sch9idFJHJTMH9YNpxxESqABcAFweJG4tKv+0zo0m5XBvUSL8FM5xKcJLFLXononpePs8IclyX1KieL5SDUNgA==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.1", + "@radix-ui/react-collection": "1.1.1", + "@radix-ui/react-compose-refs": "1.1.1", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-dismissable-layer": "1.1.3", + "@radix-ui/react-portal": "1.1.3", + "@radix-ui/react-presence": "1.1.2", + "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-controllable-state": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0", + "@radix-ui/react-visually-hidden": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-callback-ref": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz", + "integrity": "sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-controllable-state": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.1.0.tgz", + "integrity": "sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-callback-ref": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-escape-keydown": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.0.tgz", + "integrity": "sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-callback-ref": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-layout-effect": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz", + "integrity": "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-previous": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.0.tgz", + "integrity": "sha512-Z/e78qg2YFnnXcW88A4JmTtm4ADckLno6F7OXotmkQfeuCVaKuYzqAATPhVzl3delXE7CxIV8shofPn3jPc5Og==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-rect": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.0.tgz", + "integrity": "sha512-0Fmkebhr6PiseyZlYAOtLS+nb7jLmpqTrJyv61Pe68MKYW6OWdRE2kI70TaYY27u7H0lajqM3hSMMLFq18Z7nQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/rect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-size": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.0.tgz", + "integrity": "sha512-XW3/vWuIXHa+2Uwcc2ABSfcCledmXhhQPlGbfcRXbiUQI5Icjcg19BGCZVKKInYbvUCut/ufbbLLPFC5cbb1hw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { @@ -2673,6 +3279,12 @@ } } }, + "node_modules/@radix-ui/rect": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.0.tgz", + "integrity": "sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg==", + "license": "MIT" + }, "node_modules/@react-leaflet/core": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@react-leaflet/core/-/core-3.0.0.tgz", @@ -2958,50 +3570,50 @@ "license": "MIT" }, "node_modules/@sentry-internal/browser-utils": { - "version": "8.50.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-8.50.0.tgz", - "integrity": "sha512-hZm6ngWTEzZhaMHpLIKB4wWp0Od1MdCZdvR5FRdIThUMLa1P8rXeolovTRfOE81NE755EiwJHzj4O7rq3EjA+A==", + "version": "8.51.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/browser-utils/-/browser-utils-8.51.0.tgz", + "integrity": "sha512-r94yfRK17zNJER0hgQE4qOSy5pWzsnFcGTJQSqhSEKUcC4KK37qSfoPrPejFxtIqXhqlkd/dTWKvrMwXWcn0MQ==", "license": "MIT", "dependencies": { - "@sentry/core": "8.50.0" + "@sentry/core": "8.51.0" }, "engines": { "node": ">=14.18" } }, "node_modules/@sentry-internal/feedback": { - "version": "8.50.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-8.50.0.tgz", - "integrity": "sha512-79WlvSJYCXL/D0PBC8AIT4JbyS44AE3h6lP05IESXMqzTZl3KeSqCx317rwJw1KaxzeFd/JQwkFq95jaKAcLhg==", + "version": "8.51.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-8.51.0.tgz", + "integrity": "sha512-VgfxSZWLYUPKDnkt2zG+Oe5ccv8U3WPM6Mo4kfABIJT3Ai4VbZB7+vb2a4pm6lUCF9DeOPXHb5o9Tg17SHDAHw==", "license": "MIT", "dependencies": { - "@sentry/core": "8.50.0" + "@sentry/core": "8.51.0" }, "engines": { "node": ">=14.18" } }, "node_modules/@sentry-internal/replay": { - "version": "8.50.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/replay/-/replay-8.50.0.tgz", - "integrity": "sha512-mhRPujzO6n+mb6ZR+wQNkSpjqIqDriR0hZEvdzHQdyXu9zVdCHUJ3sINkzpT1XwiypQVCEfxB6Oh9y/NmcQfGg==", + "version": "8.51.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/replay/-/replay-8.51.0.tgz", + "integrity": "sha512-lkm7id3a2n3yMZeF5socCVQUeEeShNOGr7Wtsmb5RORacEnld0z+NfbMTilo1mDwiWBzI5OYBjm62eglm1HFsQ==", "license": "MIT", "dependencies": { - "@sentry-internal/browser-utils": "8.50.0", - "@sentry/core": "8.50.0" + "@sentry-internal/browser-utils": "8.51.0", + "@sentry/core": "8.51.0" }, "engines": { "node": ">=14.18" } }, "node_modules/@sentry-internal/replay-canvas": { - "version": "8.50.0", - "resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-8.50.0.tgz", - "integrity": "sha512-Hv1bBaPpe62xFPLpuaUxVBUHd/Ed9bnGndeqN4hueeEGDT9T6NyVokgm35O5xE9/op6Yodm/3NfUkEg8oE++Aw==", + "version": "8.51.0", + "resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-8.51.0.tgz", + "integrity": "sha512-ERXIbwdULkdtIQnfkMLRVfpoGV2rClwySGRlTPepFKeLxlcXo9o09cPu+qbukiDnGK0cgEgRnrV961hMg21Bmw==", "license": "MIT", "dependencies": { - "@sentry-internal/replay": "8.50.0", - "@sentry/core": "8.50.0" + "@sentry-internal/replay": "8.51.0", + "@sentry/core": "8.51.0" }, "engines": { "node": ">=14.18" @@ -3035,38 +3647,38 @@ } }, "node_modules/@sentry/browser": { - "version": "8.50.0", - "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-8.50.0.tgz", - "integrity": "sha512-aGJSpuKiHVKkLvd1VklJSZ2oCsl4wcKUVxKIa8dhJC8KjDY0vREQCywrlWuS5KYP0xFy4k28pg6PPR3HKkUlNw==", + "version": "8.51.0", + "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-8.51.0.tgz", + "integrity": "sha512-1kbbyVfBBAx5Xyynp+lC5lLnAHo0qJ2r4mtmdT6koPjesvoOocEK0QQnouQBmdUbm3L0L/bPI1SgXjbeJyhzHQ==", "license": "MIT", "dependencies": { - "@sentry-internal/browser-utils": "8.50.0", - "@sentry-internal/feedback": "8.50.0", - "@sentry-internal/replay": "8.50.0", - "@sentry-internal/replay-canvas": "8.50.0", - "@sentry/core": "8.50.0" + "@sentry-internal/browser-utils": "8.51.0", + "@sentry-internal/feedback": "8.51.0", + "@sentry-internal/replay": "8.51.0", + "@sentry-internal/replay-canvas": "8.51.0", + "@sentry/core": "8.51.0" }, "engines": { "node": ">=14.18" } }, "node_modules/@sentry/core": { - "version": "8.50.0", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-8.50.0.tgz", - "integrity": "sha512-q71m8Ha9YGwqn4Gd7sWvcFTRgbHXxEfU4QeIFtwMBpwHfq2Q+9koiF8DOoOHqIEOsnlvZWRQgGggIOdHzajnVw==", + "version": "8.51.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-8.51.0.tgz", + "integrity": "sha512-Go0KxCYLw+OBIlLSv5YsYX+x9NW43fNVcyB6rhkSp2Q5Zme3tAE6KtZFvyu4SO7G/903wisW5Q6qV6UuK/ee4A==", "license": "MIT", "engines": { "node": ">=14.18" } }, "node_modules/@sentry/react": { - "version": "8.50.0", - "resolved": "https://registry.npmjs.org/@sentry/react/-/react-8.50.0.tgz", - "integrity": "sha512-qkDW5dieROPDf0uk1usXib/SLZTEveN5jvKgBFd+HKWz5JNu+M7L53t9KdZ7ryn4T68utI/LWs4qR3QhmXzUbQ==", + "version": "8.51.0", + "resolved": "https://registry.npmjs.org/@sentry/react/-/react-8.51.0.tgz", + "integrity": "sha512-Gqa6THfBJu3kagUr9B9kUWvOwzu7L2c1Wdvo7Wcy1yq6rcB2F2Ihxo9okNvb7cAez//UBtEYFebRJAaFKZqN0g==", "license": "MIT", "dependencies": { - "@sentry/browser": "8.50.0", - "@sentry/core": "8.50.0", + "@sentry/browser": "8.51.0", + "@sentry/core": "8.51.0", "hoist-non-react-statics": "^3.3.2" }, "engines": { @@ -3137,9 +3749,9 @@ } }, "node_modules/@swc/core": { - "version": "1.10.8", - "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.10.8.tgz", - "integrity": "sha512-I3G+n9qbHNu6KNraaAG1+Z1S1x5S7MGRA6OEppT8Pt3Z9uD5a/kYAGU33eXy7zY+BoKuKA2X1H0r4vSimAgU8w==", + "version": "1.10.9", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.10.9.tgz", + "integrity": "sha512-MQ97YSXu2oibzm7wi4GNa7hhndjLuVt/lmO2sq53+P37oZmyg/JQ/IYYtSiC6UGK3+cHoiVAykrK+glxLjJbag==", "dev": true, "hasInstallScript": true, "license": "Apache-2.0", @@ -3155,16 +3767,16 @@ "url": "https://opencollective.com/swc" }, "optionalDependencies": { - "@swc/core-darwin-arm64": "1.10.8", - "@swc/core-darwin-x64": "1.10.8", - "@swc/core-linux-arm-gnueabihf": "1.10.8", - "@swc/core-linux-arm64-gnu": "1.10.8", - "@swc/core-linux-arm64-musl": "1.10.8", - "@swc/core-linux-x64-gnu": "1.10.8", - "@swc/core-linux-x64-musl": "1.10.8", - "@swc/core-win32-arm64-msvc": "1.10.8", - "@swc/core-win32-ia32-msvc": "1.10.8", - "@swc/core-win32-x64-msvc": "1.10.8" + "@swc/core-darwin-arm64": "1.10.9", + "@swc/core-darwin-x64": "1.10.9", + "@swc/core-linux-arm-gnueabihf": "1.10.9", + "@swc/core-linux-arm64-gnu": "1.10.9", + "@swc/core-linux-arm64-musl": "1.10.9", + "@swc/core-linux-x64-gnu": "1.10.9", + "@swc/core-linux-x64-musl": "1.10.9", + "@swc/core-win32-arm64-msvc": "1.10.9", + "@swc/core-win32-ia32-msvc": "1.10.9", + "@swc/core-win32-x64-msvc": "1.10.9" }, "peerDependencies": { "@swc/helpers": "*" @@ -3176,9 +3788,9 @@ } }, "node_modules/@swc/core-darwin-arm64": { - "version": "1.10.8", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.10.8.tgz", - "integrity": "sha512-FtacTu9zS5YuepujQqujveNw8BQ8ESJ+pN1Z7C+WrKCHlCl+5dh0n6gMAlEj+3iRvY6UAYqkzTVeiX/bOMoJKA==", + "version": "1.10.9", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.10.9.tgz", + "integrity": "sha512-XTHLtijFervv2B+i1ngM993umhSj9K1IeMomvU/Db84Asjur2XmD4KXt9QPnGDRFgv2kLSjZ+DDL25Qk0f4r+w==", "cpu": [ "arm64" ], @@ -3193,9 +3805,9 @@ } }, "node_modules/@swc/core-darwin-x64": { - "version": "1.10.8", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.10.8.tgz", - "integrity": "sha512-nfk+iq7EKQwADaCERzZLSi9ovzjJcqDWaO4e2ztyCNaLFi6fP1m6+ij21aki5KAd8AXoY4fue4Mo2fuYbesX9Q==", + "version": "1.10.9", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.10.9.tgz", + "integrity": "sha512-bi3el9/FV/la8HIsolSjeDar+tM7m9AmSF1w7X6ZByW2qgc4Z1tmq0A4M4H9aH3TfHesZbfq8hgaNtc2/VtzzQ==", "cpu": [ "x64" ], @@ -3210,9 +3822,9 @@ } }, "node_modules/@swc/core-linux-arm-gnueabihf": { - "version": "1.10.8", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.10.8.tgz", - "integrity": "sha512-CL2zfbnrEc6nIiWbgshOz0mjn/zY8JcYqO12vGcTxmZOrh0n+mmHN2ejX91pYWQnQDtbhCmFTaEndExFpA7Gww==", + "version": "1.10.9", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.10.9.tgz", + "integrity": "sha512-xsLHV02S+RTDuI+UJBkA2muNk/s0ETRpoc1K/gNt0i8BqTurPYkrvGDDALN9+leiUPydHvZi9P1qdExbgUJnXw==", "cpu": [ "arm" ], @@ -3227,9 +3839,9 @@ } }, "node_modules/@swc/core-linux-arm64-gnu": { - "version": "1.10.8", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.10.8.tgz", - "integrity": "sha512-quS8F18DDScW3B7qnbWkz95abZ5p0xp/W8N498NAAls/YQj4jQIlf8WlAWoxVVjY/SmSus5kN5tuwhHD8t0NPw==", + "version": "1.10.9", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.10.9.tgz", + "integrity": "sha512-41hJgPoGhIa12U6Tud+yLF/m64YA3mGut3TmBEkj2R7rdJdE0mljdtR0tf4J2RoQaWZPPi0DBSqGdROiAEx9dg==", "cpu": [ "arm64" ], @@ -3244,9 +3856,9 @@ } }, "node_modules/@swc/core-linux-arm64-musl": { - "version": "1.10.8", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.10.8.tgz", - "integrity": "sha512-wI0Hny8fHbBK/OjJ7eFYP0uDKiCMMMr5OBWGKMRRUvWs2zlGeJQZbwUeCnWuLLXzDfL+feMfh5TieYlqKTTtRw==", + "version": "1.10.9", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.10.9.tgz", + "integrity": "sha512-DUMRhl49b9r7bLg9oNzCdW4lLcDJKrRBn87Iq5APPvixsm1auGnsVQycGkQcDDKvVllxIFSbmCYzjagx3l8Hnw==", "cpu": [ "arm64" ], @@ -3261,9 +3873,9 @@ } }, "node_modules/@swc/core-linux-x64-gnu": { - "version": "1.10.8", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.10.8.tgz", - "integrity": "sha512-24FCRUFO8gzPP2eu3soHTm3lk+ktcsIhdM2DTOlXGA+2TBYFWgAZX/yZV+eeRrtIZYSr4OcOWsNWnQ5Ma4budA==", + "version": "1.10.9", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.10.9.tgz", + "integrity": "sha512-xW0y88vQvmzYo3Gn7yFnY03TfHMwuca4aFH3ZmhwDNOYHmTOi6fmhAkg/13F/NrwjMYO+GnF5uJTjdjb3B6tdQ==", "cpu": [ "x64" ], @@ -3278,9 +3890,9 @@ } }, "node_modules/@swc/core-linux-x64-musl": { - "version": "1.10.8", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.10.8.tgz", - "integrity": "sha512-mBo7M/FmUhoWpUG17MLbS98iRA7t6ThxQBWDJZd322whkN1GqrvumYm2wvvjmoMTeDOPwAL3hIIa5H+Q4vb1zA==", + "version": "1.10.9", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.10.9.tgz", + "integrity": "sha512-jYs32BEx+CPVuxN6NdsWEpdehjnmAag25jyJzwjQx+NCGYwHEV3bT5y8TX4eFhaVB1rafmqJOlYQPs4+MSyGCg==", "cpu": [ "x64" ], @@ -3295,9 +3907,9 @@ } }, "node_modules/@swc/core-win32-arm64-msvc": { - "version": "1.10.8", - "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.10.8.tgz", - "integrity": "sha512-rXJ9y77JZZXoZkgFR0mObKa3TethRBJ6Exs/pwhScl9pz4qsfxhj/bQbEu1g1i/ihmd0l+IKZwGSC7Ibh3HA2Q==", + "version": "1.10.9", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.10.9.tgz", + "integrity": "sha512-Uhh5T3Fq3Nyom96Bm3ACBNASH3iqNc76in7ewZz8PooUqeTIO8aZpsghnncjctRNE9T819/8btpiFIhHo3sKtg==", "cpu": [ "arm64" ], @@ -3312,9 +3924,9 @@ } }, "node_modules/@swc/core-win32-ia32-msvc": { - "version": "1.10.8", - "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.10.8.tgz", - "integrity": "sha512-n6ekYFJEBPvTpRIqJiu6EHXVzVnuCtDTpFnn/0KVGJI1yQHriGVEovnb/+qyLh8Rwx2AZM9qgZVgMhVtfcFQJg==", + "version": "1.10.9", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.10.9.tgz", + "integrity": "sha512-bD5BpbojEsDfrAvT+1qjQPf5RCKLg4UL+3Uwm019+ZR02hd8qO538BlOnQdOqRqccu+75DF6aRglQ7AJ24Cs0Q==", "cpu": [ "ia32" ], @@ -3329,9 +3941,9 @@ } }, "node_modules/@swc/core-win32-x64-msvc": { - "version": "1.10.8", - "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.10.8.tgz", - "integrity": "sha512-vplXxtH/lFc/epELnAyvdCvqlDJrM+OKtkphYcbPqq50g/dEZYZ8FYHU5Df9Uo19UooWSo1LaxPk4R7n6i1Axw==", + "version": "1.10.9", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.10.9.tgz", + "integrity": "sha512-NwkuUNeBBQnAaXVvcGw8Zr6RR8kylyjFUnlYZZ3G0QkQZ4rYLXYTafAmiRjrfzgVb0LcMF/sBzJvGOk7SwtIDg==", "cpu": [ "x64" ], @@ -3352,6 +3964,15 @@ "dev": true, "license": "Apache-2.0" }, + "node_modules/@swc/helpers": { + "version": "0.5.15", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz", + "integrity": "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.8.0" + } + }, "node_modules/@swc/jest": { "version": "0.2.37", "resolved": "https://registry.npmjs.org/@swc/jest/-/jest-0.2.37.tgz", @@ -3471,9 +4092,9 @@ } }, "node_modules/@testing-library/user-event": { - "version": "14.6.0", - "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.6.0.tgz", - "integrity": "sha512-+jsfK7kVJbqnCYtLTln8Ja/NmVrZRwBJHmHR9IxIVccMWSOZ6Oy0FkDJNeyVu4QSpMNmRfy10Xb76ObRDlWWBQ==", + "version": "14.6.1", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.6.1.tgz", + "integrity": "sha512-vq7fv0rnt+QTXgPxr5Hjc210p6YKq2kmdziLgnsZGgLJ9e6VAShx1pACLuRjd/AS/sr7phAR58OIIpf0LlmQNw==", "license": "MIT", "engines": { "node": ">=12", @@ -3709,15 +4330,21 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "22.10.7", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.7.tgz", - "integrity": "sha512-V09KvXxFiutGp6B7XkpaDXlNadZxrzajcY50EuoLIpQ6WWYCSvf19lVIazzfIzQvhUN2HjX12spLojTnhuKlGg==", + "version": "22.10.8", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.8.tgz", + "integrity": "sha512-rk+QvAEGsbX/ZPiiyel6hJHNUS9cnSbPWVaZLvE+Er3tLqQFzWMz9JOfWW7XUmKvRPfxJfbl3qYWve+RGXncFw==", "devOptional": true, "license": "MIT", "dependencies": { "undici-types": "~6.20.0" } }, + "node_modules/@types/parse-json": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", + "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", + "license": "MIT" + }, "node_modules/@types/react": { "version": "19.0.7", "resolved": "https://registry.npmjs.org/@types/react/-/react-19.0.7.tgz", @@ -3784,17 +4411,17 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.20.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.20.0.tgz", - "integrity": "sha512-naduuphVw5StFfqp4Gq4WhIBE2gN1GEmMUExpJYknZJdRnc+2gDzB8Z3+5+/Kv33hPQRDGzQO/0opHE72lZZ6A==", + "version": "8.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.21.0.tgz", + "integrity": "sha512-eTH+UOR4I7WbdQnG4Z48ebIA6Bgi7WO8HvFEneeYBxG8qCOYgTOFPSg6ek9ITIDvGjDQzWHcoWHCDO2biByNzA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.20.0", - "@typescript-eslint/type-utils": "8.20.0", - "@typescript-eslint/utils": "8.20.0", - "@typescript-eslint/visitor-keys": "8.20.0", + "@typescript-eslint/scope-manager": "8.21.0", + "@typescript-eslint/type-utils": "8.21.0", + "@typescript-eslint/utils": "8.21.0", + "@typescript-eslint/visitor-keys": "8.21.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", @@ -3814,16 +4441,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.20.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.20.0.tgz", - "integrity": "sha512-gKXG7A5HMyjDIedBi6bUrDcun8GIjnI8qOwVLiY3rx6T/sHP/19XLJOnIq/FgQvWLHja5JN/LSE7eklNBr612g==", + "version": "8.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.21.0.tgz", + "integrity": "sha512-Wy+/sdEH9kI3w9civgACwabHbKl+qIOu0uFZ9IMKzX3Jpv9og0ZBJrZExGrPpFAY7rWsXuxs5e7CPPP17A4eYA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.20.0", - "@typescript-eslint/types": "8.20.0", - "@typescript-eslint/typescript-estree": "8.20.0", - "@typescript-eslint/visitor-keys": "8.20.0", + "@typescript-eslint/scope-manager": "8.21.0", + "@typescript-eslint/types": "8.21.0", + "@typescript-eslint/typescript-estree": "8.21.0", + "@typescript-eslint/visitor-keys": "8.21.0", "debug": "^4.3.4" }, "engines": { @@ -3839,14 +4466,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.20.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.20.0.tgz", - "integrity": "sha512-J7+VkpeGzhOt3FeG1+SzhiMj9NzGD/M6KoGn9f4dbz3YzK9hvbhVTmLj/HiTp9DazIzJ8B4XcM80LrR9Dm1rJw==", + "version": "8.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.21.0.tgz", + "integrity": "sha512-G3IBKz0/0IPfdeGRMbp+4rbjfSSdnGkXsM/pFZA8zM9t9klXDnB/YnKOBQ0GoPmoROa4bCq2NeHgJa5ydsQ4mA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.20.0", - "@typescript-eslint/visitor-keys": "8.20.0" + "@typescript-eslint/types": "8.21.0", + "@typescript-eslint/visitor-keys": "8.21.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3857,14 +4484,14 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.20.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.20.0.tgz", - "integrity": "sha512-bPC+j71GGvA7rVNAHAtOjbVXbLN5PkwqMvy1cwGeaxUoRQXVuKCebRoLzm+IPW/NtFFpstn1ummSIasD5t60GA==", + "version": "8.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.21.0.tgz", + "integrity": "sha512-95OsL6J2BtzoBxHicoXHxgk3z+9P3BEcQTpBKriqiYzLKnM2DeSqs+sndMKdamU8FosiadQFT3D+BSL9EKnAJQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "8.20.0", - "@typescript-eslint/utils": "8.20.0", + "@typescript-eslint/typescript-estree": "8.21.0", + "@typescript-eslint/utils": "8.21.0", "debug": "^4.3.4", "ts-api-utils": "^2.0.0" }, @@ -3876,139 +4503,924 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.8.0" + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.21.0.tgz", + "integrity": "sha512-PAL6LUuQwotLW2a8VsySDBwYMm129vFm4tMVlylzdoTybTHaAi0oBp7Ac6LhSrHHOdLM3efH+nAR6hAWoMF89A==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.21.0.tgz", + "integrity": "sha512-x+aeKh/AjAArSauz0GiQZsjT8ciadNMHdkUSwBB9Z6PrKc/4knM4g3UfHml6oDJmKC88a6//cdxnO/+P2LkMcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.21.0", + "@typescript-eslint/visitor-keys": "8.21.0", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^2.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.21.0.tgz", + "integrity": "sha512-xcXBfcq0Kaxgj7dwejMbFyq7IOHgpNMtVuDveK7w3ZGwG9owKzhALVwKpTF2yrZmEwl9SWdetf3fxNzJQaVuxw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "8.21.0", + "@typescript-eslint/types": "8.21.0", + "@typescript-eslint/typescript-estree": "8.21.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.21.0.tgz", + "integrity": "sha512-BkLMNpdV6prozk8LlyK/SOoWLmUFi+ZD+pcqti9ILCbVvHGk1ui1g4jJOc2WDLaeExz2qWwojxlPce5PljcT3w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.21.0", + "eslint-visitor-keys": "^4.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@vitejs/plugin-react": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.3.4.tgz", + "integrity": "sha512-SCCPBJtYLdE8PX/7ZQAs1QAZ8Jqwih+0VBLum1EGqmCCQal+MIUqLCzj3ZUy8ufbC0cAM4LRlSTm7IQJwWT4ug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.26.0", + "@babel/plugin-transform-react-jsx-self": "^7.25.9", + "@babel/plugin-transform-react-jsx-source": "^7.25.9", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.14.2" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0" + } + }, + "node_modules/@zag-js/accordion": { + "version": "0.81.2", + "resolved": "https://registry.npmjs.org/@zag-js/accordion/-/accordion-0.81.2.tgz", + "integrity": "sha512-xmA5GxSlme4zqpeahVpf3uC1zhSHB81c7LFfSpRDfe2KjwTAffnKAWL3thU4I4MXnIQkIXvt604yh7BWYXTrUA==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "0.81.2", + "@zag-js/core": "0.81.2", + "@zag-js/dom-query": "0.81.2", + "@zag-js/types": "0.81.2", + "@zag-js/utils": "0.81.2" + } + }, + "node_modules/@zag-js/anatomy": { + "version": "0.81.2", + "resolved": "https://registry.npmjs.org/@zag-js/anatomy/-/anatomy-0.81.2.tgz", + "integrity": "sha512-wTjaT0n4bdgwd75z9x3FztYprBzmcKJj2VhgJ1OnOFFdMz+EX0mnY5PqCY8sIZQ7jfIimXcZF/xYQmqIGhQnZw==", + "license": "MIT" + }, + "node_modules/@zag-js/aria-hidden": { + "version": "0.81.2", + "resolved": "https://registry.npmjs.org/@zag-js/aria-hidden/-/aria-hidden-0.81.2.tgz", + "integrity": "sha512-QpqapPBe97GsOIv9zm+4nnQB3hMwRBGJZ48/KWUABsKH1YQYX+BLHj97HY7FF3+ML6hdBXKiHYDVfWPBQCzeDw==", + "license": "MIT" + }, + "node_modules/@zag-js/auto-resize": { + "version": "0.81.2", + "resolved": "https://registry.npmjs.org/@zag-js/auto-resize/-/auto-resize-0.81.2.tgz", + "integrity": "sha512-A2ueJOZhp/DkofwxZa0Wo6YQsfEmuWb5FEy38oVSctznR6yEypBms849GC3efd4/IDKYwvdt/4cGeGU2FVLfWQ==", + "license": "MIT", + "dependencies": { + "@zag-js/dom-query": "0.81.2" + } + }, + "node_modules/@zag-js/avatar": { + "version": "0.81.2", + "resolved": "https://registry.npmjs.org/@zag-js/avatar/-/avatar-0.81.2.tgz", + "integrity": "sha512-eyIEtk2yA+Apl4a/fIiKrSD8C0tFD0+g/JgKcvkiP/OFG4WaBeAg4/URr9dl2Ytg0+1GkRYJzB+wcEUBOqOX8w==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "0.81.2", + "@zag-js/core": "0.81.2", + "@zag-js/dom-query": "0.81.2", + "@zag-js/types": "0.81.2", + "@zag-js/utils": "0.81.2" + } + }, + "node_modules/@zag-js/carousel": { + "version": "0.81.2", + "resolved": "https://registry.npmjs.org/@zag-js/carousel/-/carousel-0.81.2.tgz", + "integrity": "sha512-IoJZ6WMGOiyZqm+uya6VBuZGQRNH/6RdVQpoUYgzkf7RRf7uCUs89il7iPf9IB0qO7JZ8eYOa8ZRRRZ1qGos4g==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "0.81.2", + "@zag-js/core": "0.81.2", + "@zag-js/dom-query": "0.81.2", + "@zag-js/scroll-snap": "0.81.2", + "@zag-js/types": "0.81.2", + "@zag-js/utils": "0.81.2" + } + }, + "node_modules/@zag-js/checkbox": { + "version": "0.81.2", + "resolved": "https://registry.npmjs.org/@zag-js/checkbox/-/checkbox-0.81.2.tgz", + "integrity": "sha512-lvqo8M6zsuAluBpp1RbFKhkn7VZI8vNHdzyi14iacWNtzkORbGI0+PXvXQcs0m8mDhTrfk21fnv/rpjsQe+3lg==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "0.81.2", + "@zag-js/core": "0.81.2", + "@zag-js/dom-query": "0.81.2", + "@zag-js/focus-visible": "0.81.2", + "@zag-js/types": "0.81.2", + "@zag-js/utils": "0.81.2" + } + }, + "node_modules/@zag-js/clipboard": { + "version": "0.81.2", + "resolved": "https://registry.npmjs.org/@zag-js/clipboard/-/clipboard-0.81.2.tgz", + "integrity": "sha512-+o2kZ0wUxKWI5qIM5CqwzYBEksZKY8/FvomcRv19N8Dr5zXzoVIf8Cub+COlX07ZM9jDW4KjdOijsz4dyBNQBg==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "0.81.2", + "@zag-js/core": "0.81.2", + "@zag-js/dom-query": "0.81.2", + "@zag-js/types": "0.81.2", + "@zag-js/utils": "0.81.2" + } + }, + "node_modules/@zag-js/collapsible": { + "version": "0.81.2", + "resolved": "https://registry.npmjs.org/@zag-js/collapsible/-/collapsible-0.81.2.tgz", + "integrity": "sha512-JauqCO4gdPibc4nViPps2rVrovNTaiiMNVy/QMUa6PEtu2zW+l/OR56eQWneIrF11ahq6uUt0HPf0vYhM96A/Q==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "0.81.2", + "@zag-js/core": "0.81.2", + "@zag-js/dom-query": "0.81.2", + "@zag-js/types": "0.81.2", + "@zag-js/utils": "0.81.2" + } + }, + "node_modules/@zag-js/collection": { + "version": "0.81.2", + "resolved": "https://registry.npmjs.org/@zag-js/collection/-/collection-0.81.2.tgz", + "integrity": "sha512-FEqd77voD550yp3O3ZuGsV/g7KUvjOX30hBN2O4qGeXkSGvSJSDuy6eL07M+Fm/vWLDz8moMKnwZ7R9QUWLFEg==", + "license": "MIT", + "dependencies": { + "@zag-js/utils": "0.81.2" + } + }, + "node_modules/@zag-js/color-picker": { + "version": "0.81.2", + "resolved": "https://registry.npmjs.org/@zag-js/color-picker/-/color-picker-0.81.2.tgz", + "integrity": "sha512-NliCZhgWBhPb338BkL7GLEqGxkkcitqVMGq82284Fh6qg+e1kXS1lrC1X6p32WU/3dwoSc12YEfbolRkIWAcTQ==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "0.81.2", + "@zag-js/color-utils": "0.81.2", + "@zag-js/core": "0.81.2", + "@zag-js/dismissable": "0.81.2", + "@zag-js/dom-query": "0.81.2", + "@zag-js/popper": "0.81.2", + "@zag-js/types": "0.81.2", + "@zag-js/utils": "0.81.2" + } + }, + "node_modules/@zag-js/color-utils": { + "version": "0.81.2", + "resolved": "https://registry.npmjs.org/@zag-js/color-utils/-/color-utils-0.81.2.tgz", + "integrity": "sha512-mvnagJ0eZkSRIfRcqdZUB6Pv8GaGtHWqDU1rCQoYSmV/Dp468ERoOQbl8/95qeTYRGGL4ba/n89oEDCcVRcUoA==", + "license": "MIT", + "dependencies": { + "@zag-js/utils": "0.81.2" + } + }, + "node_modules/@zag-js/combobox": { + "version": "0.81.2", + "resolved": "https://registry.npmjs.org/@zag-js/combobox/-/combobox-0.81.2.tgz", + "integrity": "sha512-EygGIhg4w+f8BmsLFffxHnxsG/V31iHScOVojK/jK6uJi8Q705ZBzvv4sC6ARVxgB9rt+HE+f2sQUZtbSSpxvA==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "0.81.2", + "@zag-js/aria-hidden": "0.81.2", + "@zag-js/collection": "0.81.2", + "@zag-js/core": "0.81.2", + "@zag-js/dismissable": "0.81.2", + "@zag-js/dom-query": "0.81.2", + "@zag-js/popper": "0.81.2", + "@zag-js/types": "0.81.2", + "@zag-js/utils": "0.81.2" + } + }, + "node_modules/@zag-js/core": { + "version": "0.81.2", + "resolved": "https://registry.npmjs.org/@zag-js/core/-/core-0.81.2.tgz", + "integrity": "sha512-dyOSdvxIUaZivEgszAZAsEXzDbz30K7R5cnav42ey6q2DysyA0ir61KuSLqik7pBpkMocLOslB1yjY3XVT7Hfg==", + "license": "MIT", + "dependencies": { + "@zag-js/store": "0.81.2", + "@zag-js/utils": "0.81.2" + } + }, + "node_modules/@zag-js/date-picker": { + "version": "0.81.2", + "resolved": "https://registry.npmjs.org/@zag-js/date-picker/-/date-picker-0.81.2.tgz", + "integrity": "sha512-o1eH8c4FnTf5ncq9eVFwz2mwwWFuZ7YwXXCXCA3dXoIjOhJc/IjxbW7Ji4m7nRAPkd0TCq06VSJnpwGObdfa6A==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "0.81.2", + "@zag-js/core": "0.81.2", + "@zag-js/date-utils": "0.81.2", + "@zag-js/dismissable": "0.81.2", + "@zag-js/dom-query": "0.81.2", + "@zag-js/live-region": "0.81.2", + "@zag-js/popper": "0.81.2", + "@zag-js/types": "0.81.2", + "@zag-js/utils": "0.81.2" + }, + "peerDependencies": { + "@internationalized/date": ">=3.0.0" + } + }, + "node_modules/@zag-js/date-utils": { + "version": "0.81.2", + "resolved": "https://registry.npmjs.org/@zag-js/date-utils/-/date-utils-0.81.2.tgz", + "integrity": "sha512-dWh2t3wiaRBM8wjWVd9pYlUu/T3L0DTXGquTqq+1TtsU89uLNQMKR9kYgK9iqRwITIUPojsTOy40CJIjBRLP5w==", + "license": "MIT", + "peerDependencies": { + "@internationalized/date": ">=3.0.0" + } + }, + "node_modules/@zag-js/dialog": { + "version": "0.81.2", + "resolved": "https://registry.npmjs.org/@zag-js/dialog/-/dialog-0.81.2.tgz", + "integrity": "sha512-IN3GdKoRPr2mLiLHhrnrxAjvNMg3gjogtlXApsFA2Quxi0J2X68CS/5EU66hiVxzp3YfmulC7F5amSiN8Xn3ew==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "0.81.2", + "@zag-js/aria-hidden": "0.81.2", + "@zag-js/core": "0.81.2", + "@zag-js/dismissable": "0.81.2", + "@zag-js/dom-query": "0.81.2", + "@zag-js/focus-trap": "0.81.2", + "@zag-js/remove-scroll": "0.81.2", + "@zag-js/types": "0.81.2", + "@zag-js/utils": "0.81.2" + } + }, + "node_modules/@zag-js/dismissable": { + "version": "0.81.2", + "resolved": "https://registry.npmjs.org/@zag-js/dismissable/-/dismissable-0.81.2.tgz", + "integrity": "sha512-LEK01BSl22PHSoYGWVQ9LH5FRI5G6leOO6ZabCMysBmHf7+NkieUSo07wVrAcCDYvdRCkmGTQ6B/u/z2STJ5lQ==", + "license": "MIT", + "dependencies": { + "@zag-js/dom-query": "0.81.2", + "@zag-js/interact-outside": "0.81.2", + "@zag-js/utils": "0.81.2" + } + }, + "node_modules/@zag-js/dom-query": { + "version": "0.81.2", + "resolved": "https://registry.npmjs.org/@zag-js/dom-query/-/dom-query-0.81.2.tgz", + "integrity": "sha512-Iqi84Ac+5G8PUSETdJFG4eQ+g+Ami/IKxpTmYBdpPZWzgg82hD/+DQ5dDFndQc5HLfo1uhJVZy8O7z8gTrr0Sg==", + "license": "MIT", + "dependencies": { + "@zag-js/types": "0.81.2" + } + }, + "node_modules/@zag-js/editable": { + "version": "0.81.2", + "resolved": "https://registry.npmjs.org/@zag-js/editable/-/editable-0.81.2.tgz", + "integrity": "sha512-Mn6rj0N61eNZ/b/tuyXlZAdtDmx0aIvHqW30Cqy/a/wO63GCDBx+HNFa+nYM+rvgy5V0KDrrqAm01XV/5e03fg==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "0.81.2", + "@zag-js/core": "0.81.2", + "@zag-js/dom-query": "0.81.2", + "@zag-js/interact-outside": "0.81.2", + "@zag-js/types": "0.81.2", + "@zag-js/utils": "0.81.2" + } + }, + "node_modules/@zag-js/element-rect": { + "version": "0.81.2", + "resolved": "https://registry.npmjs.org/@zag-js/element-rect/-/element-rect-0.81.2.tgz", + "integrity": "sha512-s2skZTYiauP1gcZhoD8TzBY3tm6DGG0rL2ZCNaP0dtvXv+VMY+/uziwMem32BIQhsSNeA0U5RLaUdzGNuQV6ZA==", + "license": "MIT" + }, + "node_modules/@zag-js/element-size": { + "version": "0.81.2", + "resolved": "https://registry.npmjs.org/@zag-js/element-size/-/element-size-0.81.2.tgz", + "integrity": "sha512-73MoNe2u5oTZlPj2T4dbHDdEN6aPXunth9vx1abWiTKif7VG1BqVQb9a6LKyFOztdSG9FaQif2p0VcmLsiO4zw==", + "license": "MIT" + }, + "node_modules/@zag-js/file-upload": { + "version": "0.81.2", + "resolved": "https://registry.npmjs.org/@zag-js/file-upload/-/file-upload-0.81.2.tgz", + "integrity": "sha512-SK4iCV+4b5aAGH4Fotscuuw0a+P2WTOc1n1IXVLzbcIcAWxOAui5Id+yqimRKUGlqa2D9U6I6vpVFa4UKvAGZg==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "0.81.2", + "@zag-js/core": "0.81.2", + "@zag-js/dom-query": "0.81.2", + "@zag-js/file-utils": "0.81.2", + "@zag-js/i18n-utils": "0.81.2", + "@zag-js/types": "0.81.2", + "@zag-js/utils": "0.81.2" + } + }, + "node_modules/@zag-js/file-utils": { + "version": "0.81.2", + "resolved": "https://registry.npmjs.org/@zag-js/file-utils/-/file-utils-0.81.2.tgz", + "integrity": "sha512-wKMgJX8xUXzrKTMHm0JqeD4ljaAGhnNd1EPN2xQOl81zd0Hmr6A2293/2bwXtsSSAhS2h2w+mEJkf3phnz5IEg==", + "license": "MIT", + "dependencies": { + "@zag-js/i18n-utils": "0.81.2" + } + }, + "node_modules/@zag-js/focus-trap": { + "version": "0.81.2", + "resolved": "https://registry.npmjs.org/@zag-js/focus-trap/-/focus-trap-0.81.2.tgz", + "integrity": "sha512-jvMBiUHMb71PDPJOKwGMLSVyv+xYtdW3me+zB5eYBXol8EsAv83m6bjT0SZpJzSeph/9pBg2c+qHhNNQGaZyiA==", + "license": "MIT", + "dependencies": { + "@zag-js/dom-query": "0.81.2" + } + }, + "node_modules/@zag-js/focus-visible": { + "version": "0.81.2", + "resolved": "https://registry.npmjs.org/@zag-js/focus-visible/-/focus-visible-0.81.2.tgz", + "integrity": "sha512-zQF/VK5KN81HkxhRXccP2ai2j7QRhq0J5x9rYIOX/m99S3JvA4l4zKNuENd4vMtS7LZbyIZ9dArMvqLXl5Q+dw==", + "license": "MIT", + "dependencies": { + "@zag-js/dom-query": "0.81.2" + } + }, + "node_modules/@zag-js/highlight-word": { + "version": "0.81.2", + "resolved": "https://registry.npmjs.org/@zag-js/highlight-word/-/highlight-word-0.81.2.tgz", + "integrity": "sha512-YLl8nmvEOtwVFbeZnmL+pZPuRBZiPK0N094hWdKn+ouVxC4lIx+CabDLbKcG2rRm/75Wtyvc/8W4JBkKOQhLfg==", + "license": "MIT" + }, + "node_modules/@zag-js/hover-card": { + "version": "0.81.2", + "resolved": "https://registry.npmjs.org/@zag-js/hover-card/-/hover-card-0.81.2.tgz", + "integrity": "sha512-MuS2T8ZeQtCt8H+MfebLOhpCDN/OCoP0OXyVmzaEvC/S2g1wCUl0itPNvz1O028ekLQwqlxwxEI4c4PXTDDvwA==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "0.81.2", + "@zag-js/core": "0.81.2", + "@zag-js/dismissable": "0.81.2", + "@zag-js/dom-query": "0.81.2", + "@zag-js/popper": "0.81.2", + "@zag-js/types": "0.81.2", + "@zag-js/utils": "0.81.2" + } + }, + "node_modules/@zag-js/i18n-utils": { + "version": "0.81.2", + "resolved": "https://registry.npmjs.org/@zag-js/i18n-utils/-/i18n-utils-0.81.2.tgz", + "integrity": "sha512-OBFV+MTy1Ypz8nEwgHrcEGS70dAC1qN2tADWE78VMdjcky5T5VcwoxXlVGgaSOUUdBqC+BfR14m9g3BOREqqdQ==", + "license": "MIT", + "dependencies": { + "@zag-js/dom-query": "0.81.2" + } + }, + "node_modules/@zag-js/interact-outside": { + "version": "0.81.2", + "resolved": "https://registry.npmjs.org/@zag-js/interact-outside/-/interact-outside-0.81.2.tgz", + "integrity": "sha512-PqEQMiSWJtDUVd0qAsbu0PUo/f5scmbZgX5aaxqKhv0EG+ikitoDem4Y173RSCrbah90/IYOQO+OuVrB1awS9A==", + "license": "MIT", + "dependencies": { + "@zag-js/dom-query": "0.81.2", + "@zag-js/utils": "0.81.2" + } + }, + "node_modules/@zag-js/live-region": { + "version": "0.81.2", + "resolved": "https://registry.npmjs.org/@zag-js/live-region/-/live-region-0.81.2.tgz", + "integrity": "sha512-PFrOXUXYipHXsygh43LDankinS1fp00rXTWX7Tr8Ao2UiFA/3ooxNqhupq0wvVT2lNgxSDsMSS2XpenZRNLI/g==", + "license": "MIT" + }, + "node_modules/@zag-js/menu": { + "version": "0.81.2", + "resolved": "https://registry.npmjs.org/@zag-js/menu/-/menu-0.81.2.tgz", + "integrity": "sha512-DXCTAo+DwJKD/8n3az1fqyq/xDOWw7MvRcRubbSz/aJPTdLCrnul/kDAKCr1zZ6JRdMX5xzBSJRlwA69/uPMHw==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "0.81.2", + "@zag-js/core": "0.81.2", + "@zag-js/dismissable": "0.81.2", + "@zag-js/dom-query": "0.81.2", + "@zag-js/popper": "0.81.2", + "@zag-js/rect-utils": "0.81.2", + "@zag-js/types": "0.81.2", + "@zag-js/utils": "0.81.2" + } + }, + "node_modules/@zag-js/number-input": { + "version": "0.81.2", + "resolved": "https://registry.npmjs.org/@zag-js/number-input/-/number-input-0.81.2.tgz", + "integrity": "sha512-17LjDRJ4Jtb7PEQjcXzgn+hJ0XKQTttMZsEQmGJwHYtQLYXxYqWxihlK1wdpInlxy3a8zwp9ob2gwegbeB1DWA==", + "license": "MIT", + "dependencies": { + "@internationalized/number": "3.6.0", + "@zag-js/anatomy": "0.81.2", + "@zag-js/core": "0.81.2", + "@zag-js/dom-query": "0.81.2", + "@zag-js/types": "0.81.2", + "@zag-js/utils": "0.81.2" + } + }, + "node_modules/@zag-js/pagination": { + "version": "0.81.2", + "resolved": "https://registry.npmjs.org/@zag-js/pagination/-/pagination-0.81.2.tgz", + "integrity": "sha512-79Z9ELA+xM5LSCtUuztyUnIBFUHOIfnm1xkBIctEs9PMulx9W0Z8KkzfiV44Ze4Qmk/50LByaveg4vQ0sAY9VQ==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "0.81.2", + "@zag-js/core": "0.81.2", + "@zag-js/dom-query": "0.81.2", + "@zag-js/types": "0.81.2", + "@zag-js/utils": "0.81.2" + } + }, + "node_modules/@zag-js/pin-input": { + "version": "0.81.2", + "resolved": "https://registry.npmjs.org/@zag-js/pin-input/-/pin-input-0.81.2.tgz", + "integrity": "sha512-EnNP4bbiPZPt6kQC5XLTYxjq1WrlxXJdWjloe1voZSlL/ZDo7l9Wztx/+7sSwys11F17r9RTm7ACYH4ixs0ujQ==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "0.81.2", + "@zag-js/core": "0.81.2", + "@zag-js/dom-query": "0.81.2", + "@zag-js/types": "0.81.2", + "@zag-js/utils": "0.81.2" + } + }, + "node_modules/@zag-js/popover": { + "version": "0.81.2", + "resolved": "https://registry.npmjs.org/@zag-js/popover/-/popover-0.81.2.tgz", + "integrity": "sha512-7Meukjyw+yBFJfR3LiFISG28+rb6J5+dwmcQscFswjq7yS602gqr3LCHhrl8AdfIt/fOcSBRc8BY+lf3uXGqlQ==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "0.81.2", + "@zag-js/aria-hidden": "0.81.2", + "@zag-js/core": "0.81.2", + "@zag-js/dismissable": "0.81.2", + "@zag-js/dom-query": "0.81.2", + "@zag-js/focus-trap": "0.81.2", + "@zag-js/popper": "0.81.2", + "@zag-js/remove-scroll": "0.81.2", + "@zag-js/types": "0.81.2", + "@zag-js/utils": "0.81.2" + } + }, + "node_modules/@zag-js/popper": { + "version": "0.81.2", + "resolved": "https://registry.npmjs.org/@zag-js/popper/-/popper-0.81.2.tgz", + "integrity": "sha512-9WzvtgadumsrEyKzcx4eoNE7H++k4eC44sVbIYNWXfaOQhzrQchSRhLjRfj06FQ7Pj2qj9ep7LjzJ2X2yWBkAg==", + "license": "MIT", + "dependencies": { + "@floating-ui/dom": "1.6.12", + "@zag-js/dom-query": "0.81.2", + "@zag-js/utils": "0.81.2" + } + }, + "node_modules/@zag-js/popper/node_modules/@floating-ui/dom": { + "version": "1.6.12", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.12.tgz", + "integrity": "sha512-NP83c0HjokcGVEMeoStg317VD9W7eDlGK7457dMBANbKA6GJZdc7rjujdgqzTaz93jkGgc5P/jeWbaCHnMNc+w==", + "license": "MIT", + "dependencies": { + "@floating-ui/core": "^1.6.0", + "@floating-ui/utils": "^0.2.8" + } + }, + "node_modules/@zag-js/presence": { + "version": "0.81.2", + "resolved": "https://registry.npmjs.org/@zag-js/presence/-/presence-0.81.2.tgz", + "integrity": "sha512-S4iMDxWko+km2QgadJ8W8HuRIW6p04sCxvZrsgT/xGQrJJ5/nmDPcmyyKPeMWtultzi4k1G6SIGQoSzEZvgFZg==", + "license": "MIT", + "dependencies": { + "@zag-js/core": "0.81.2", + "@zag-js/types": "0.81.2" + } + }, + "node_modules/@zag-js/progress": { + "version": "0.81.2", + "resolved": "https://registry.npmjs.org/@zag-js/progress/-/progress-0.81.2.tgz", + "integrity": "sha512-LRpDNI9lap0fOr1DiB1WLuY4j5lEVW0v5TBBT61vNhbc0b07Lq3bR6PoSUW7RWjC26mFrbS9/3MuwHrfSR4BeQ==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "0.81.2", + "@zag-js/core": "0.81.2", + "@zag-js/dom-query": "0.81.2", + "@zag-js/types": "0.81.2", + "@zag-js/utils": "0.81.2" + } + }, + "node_modules/@zag-js/qr-code": { + "version": "0.81.2", + "resolved": "https://registry.npmjs.org/@zag-js/qr-code/-/qr-code-0.81.2.tgz", + "integrity": "sha512-TtHoJC78iBsK8PrRkZz5l8LZdVWUZQiaRx7locjYmhjsWSHxgxyoZ7GZG8mfblFO0vVsGlyupfApYV9QENkjBw==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "0.81.2", + "@zag-js/core": "0.81.2", + "@zag-js/dom-query": "0.81.2", + "@zag-js/types": "0.81.2", + "@zag-js/utils": "0.81.2", + "proxy-memoize": "3.0.1", + "uqr": "0.1.2" + } + }, + "node_modules/@zag-js/radio-group": { + "version": "0.81.2", + "resolved": "https://registry.npmjs.org/@zag-js/radio-group/-/radio-group-0.81.2.tgz", + "integrity": "sha512-rRjCZVyAxUvEFNnpyhCCLH3dPGIF/XkUn9L/A770oPrel9Z33ULIZMEef96X0W74btdi88OC/BSZMOrA9OrLTw==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "0.81.2", + "@zag-js/core": "0.81.2", + "@zag-js/dom-query": "0.81.2", + "@zag-js/element-rect": "0.81.2", + "@zag-js/focus-visible": "0.81.2", + "@zag-js/types": "0.81.2", + "@zag-js/utils": "0.81.2" + } + }, + "node_modules/@zag-js/rating-group": { + "version": "0.81.2", + "resolved": "https://registry.npmjs.org/@zag-js/rating-group/-/rating-group-0.81.2.tgz", + "integrity": "sha512-Ktm7Bh9GZb7s+fOIpdvg0zBS8EbY+ITOtNd9MZyCNa4CSm0whw7X5AYk5z9cvaXA1z9jB9JprGk9zgO9bxqEzg==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "0.81.2", + "@zag-js/core": "0.81.2", + "@zag-js/dom-query": "0.81.2", + "@zag-js/types": "0.81.2", + "@zag-js/utils": "0.81.2" + } + }, + "node_modules/@zag-js/react": { + "version": "0.81.2", + "resolved": "https://registry.npmjs.org/@zag-js/react/-/react-0.81.2.tgz", + "integrity": "sha512-hm3Ws+CBECRslQX0d1VDv6RlMrbh2GM9uGhRWE7MIrO5UuOS5qGPUj8lPDJNoHW1aWYJAl8Fl5CfJ1lPdwAI5A==", + "license": "MIT", + "dependencies": { + "@zag-js/core": "0.81.2", + "@zag-js/store": "0.81.2", + "@zag-js/types": "0.81.2", + "proxy-compare": "3.0.1" + }, + "peerDependencies": { + "react": ">=18.0.0", + "react-dom": ">=18.0.0" + } + }, + "node_modules/@zag-js/rect-utils": { + "version": "0.81.2", + "resolved": "https://registry.npmjs.org/@zag-js/rect-utils/-/rect-utils-0.81.2.tgz", + "integrity": "sha512-Hv+vs2FHn+iHn7FJF33KV83SZm8Zs8ogW0dVPsPshF8dIuoCbu/JSyaORrrTlXKlsN/E72SiKsXtn7javefWLw==", + "license": "MIT" + }, + "node_modules/@zag-js/remove-scroll": { + "version": "0.81.2", + "resolved": "https://registry.npmjs.org/@zag-js/remove-scroll/-/remove-scroll-0.81.2.tgz", + "integrity": "sha512-bcyEWuHgVYd3YdGJ99z460QwiFXeL+iNhzSNWltr6ZDvdOCQdK2Q8iAO+SgK0E1KfsnFnqLcSuBHBhJwLD6/6g==", + "license": "MIT", + "dependencies": { + "@zag-js/dom-query": "0.81.2" + } + }, + "node_modules/@zag-js/scroll-snap": { + "version": "0.81.2", + "resolved": "https://registry.npmjs.org/@zag-js/scroll-snap/-/scroll-snap-0.81.2.tgz", + "integrity": "sha512-JNJ/qfbtSwqGVIIlg16FPkMWXudn7rrDmnSC7jrlMMTnMKxLTRTyC7hDGPvjEL4MDDWMSbnxDa0peGDXMNNSJQ==", + "license": "MIT", + "dependencies": { + "@zag-js/dom-query": "0.81.2" + } + }, + "node_modules/@zag-js/select": { + "version": "0.81.2", + "resolved": "https://registry.npmjs.org/@zag-js/select/-/select-0.81.2.tgz", + "integrity": "sha512-bQYxuhf6JC9nKzlLAAcG0GxjhpVsNoI5AhCNqq+4yoMUbR/yqZwCiHFAPxZMneciS/LsWuDZMvZyVt4pY4j9Sw==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "0.81.2", + "@zag-js/collection": "0.81.2", + "@zag-js/core": "0.81.2", + "@zag-js/dismissable": "0.81.2", + "@zag-js/dom-query": "0.81.2", + "@zag-js/popper": "0.81.2", + "@zag-js/types": "0.81.2", + "@zag-js/utils": "0.81.2" + } + }, + "node_modules/@zag-js/signature-pad": { + "version": "0.81.2", + "resolved": "https://registry.npmjs.org/@zag-js/signature-pad/-/signature-pad-0.81.2.tgz", + "integrity": "sha512-TC/DKJtJsv0L3nGDAZsMxLZ2FsDwLSIqaAoK3s/kYga+//zBwHOh46NEy21fNEZBwCWh/r6Tj2p+WuutFRFc0g==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "0.81.2", + "@zag-js/core": "0.81.2", + "@zag-js/dom-query": "0.81.2", + "@zag-js/types": "0.81.2", + "@zag-js/utils": "0.81.2", + "perfect-freehand": "^1.2.2" + } + }, + "node_modules/@zag-js/slider": { + "version": "0.81.2", + "resolved": "https://registry.npmjs.org/@zag-js/slider/-/slider-0.81.2.tgz", + "integrity": "sha512-yD8FgHh7g5CVoG0itscJyq3+kPtD5EQgYH+yPpc87fQ1o7SHbzq3U9WE3KXDY555OYQYD5dAkWCIeQRfmQKnJg==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "0.81.2", + "@zag-js/core": "0.81.2", + "@zag-js/dom-query": "0.81.2", + "@zag-js/element-size": "0.81.2", + "@zag-js/types": "0.81.2", + "@zag-js/utils": "0.81.2" + } + }, + "node_modules/@zag-js/splitter": { + "version": "0.81.2", + "resolved": "https://registry.npmjs.org/@zag-js/splitter/-/splitter-0.81.2.tgz", + "integrity": "sha512-+ZCzb+XCtnFsKi55pZHCDxJ090eFUecVHohSyZH45JePp0i+QO2vK495yjYH/NHSwwS9QSwrprRZGa2QfaeKKg==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "0.81.2", + "@zag-js/core": "0.81.2", + "@zag-js/dom-query": "0.81.2", + "@zag-js/types": "0.81.2", + "@zag-js/utils": "0.81.2" + } + }, + "node_modules/@zag-js/steps": { + "version": "0.81.2", + "resolved": "https://registry.npmjs.org/@zag-js/steps/-/steps-0.81.2.tgz", + "integrity": "sha512-w2/QwDVOX0RW7igAHcYr6yZM9/A/tcm9Nb4ZWbkM253vkGDMm6ruvDpO58R9qjce2rtExXgU437WTHZe7y1TyA==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "0.81.2", + "@zag-js/core": "0.81.2", + "@zag-js/dom-query": "0.81.2", + "@zag-js/types": "0.81.2", + "@zag-js/utils": "0.81.2" + } + }, + "node_modules/@zag-js/store": { + "version": "0.81.2", + "resolved": "https://registry.npmjs.org/@zag-js/store/-/store-0.81.2.tgz", + "integrity": "sha512-D4jqyKokVwpNXL0lq3nn9iQekyntNbPkAetDZs3vy1gPAq0hvFWKF8iNTCthC1e3hRZqJBE8l6gbL9fi1nU/XA==", + "license": "MIT", + "dependencies": { + "proxy-compare": "3.0.1" + } + }, + "node_modules/@zag-js/switch": { + "version": "0.81.2", + "resolved": "https://registry.npmjs.org/@zag-js/switch/-/switch-0.81.2.tgz", + "integrity": "sha512-Ts1O8dmhkQKnWwjtnmK/yH5QMAAIAjuwVaUPcRuFuiBqU7Meo3Kapo7wAu3mxXXpNmarMUzntdv+uxmXFtAjVQ==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "0.81.2", + "@zag-js/core": "0.81.2", + "@zag-js/dom-query": "0.81.2", + "@zag-js/focus-visible": "0.81.2", + "@zag-js/types": "0.81.2", + "@zag-js/utils": "0.81.2" + } + }, + "node_modules/@zag-js/tabs": { + "version": "0.81.2", + "resolved": "https://registry.npmjs.org/@zag-js/tabs/-/tabs-0.81.2.tgz", + "integrity": "sha512-UK4J/o6Iuos/i9RG4KOT+TYBuHHeYUDer9XIQPMEX4wppgqZaisZMvsHGkA4s7kIezvuupR/uZxjzZocQFYsqQ==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "0.81.2", + "@zag-js/core": "0.81.2", + "@zag-js/dom-query": "0.81.2", + "@zag-js/element-rect": "0.81.2", + "@zag-js/types": "0.81.2", + "@zag-js/utils": "0.81.2" + } + }, + "node_modules/@zag-js/tags-input": { + "version": "0.81.2", + "resolved": "https://registry.npmjs.org/@zag-js/tags-input/-/tags-input-0.81.2.tgz", + "integrity": "sha512-zCqzluQsW7SAhZ2BkNTaTPdYkdSoMsrekEowRFHe+snRmX2UnUJ7B8skd0tw114ipJxEiC+Pjq/c5aReP+UvMw==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "0.81.2", + "@zag-js/auto-resize": "0.81.2", + "@zag-js/core": "0.81.2", + "@zag-js/dom-query": "0.81.2", + "@zag-js/interact-outside": "0.81.2", + "@zag-js/live-region": "0.81.2", + "@zag-js/types": "0.81.2", + "@zag-js/utils": "0.81.2" + } + }, + "node_modules/@zag-js/time-picker": { + "version": "0.81.2", + "resolved": "https://registry.npmjs.org/@zag-js/time-picker/-/time-picker-0.81.2.tgz", + "integrity": "sha512-/+cvKNp3g4mZ16IVWf8qutTtE9yQCS4lVtfCF0TMGryL1dGjFHZtbDBhVF0yUl2IlvBZKZIX2Zz8bd8KZbJ0VA==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "0.81.2", + "@zag-js/core": "0.81.2", + "@zag-js/dismissable": "0.81.2", + "@zag-js/dom-query": "0.81.2", + "@zag-js/popper": "0.81.2", + "@zag-js/types": "0.81.2", + "@zag-js/utils": "0.81.2" + }, + "peerDependencies": { + "@internationalized/date": ">=3.0.0" } }, - "node_modules/@typescript-eslint/types": { - "version": "8.20.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.20.0.tgz", - "integrity": "sha512-cqaMiY72CkP+2xZRrFt3ExRBu0WmVitN/rYPZErA80mHjHx/Svgp8yfbzkJmDoQ/whcytOPO9/IZXnOc+wigRA==", - "dev": true, + "node_modules/@zag-js/timer": { + "version": "0.81.2", + "resolved": "https://registry.npmjs.org/@zag-js/timer/-/timer-0.81.2.tgz", + "integrity": "sha512-eWF00NMAhCl7cNeNeqT5y7mtXPeuJm2bH9V+sXO8uvYXpKKgykX8nvEDeMJj4gAw3gpG/ov6rZpDBcaqPdXq+Q==", "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "dependencies": { + "@zag-js/anatomy": "0.81.2", + "@zag-js/core": "0.81.2", + "@zag-js/dom-query": "0.81.2", + "@zag-js/types": "0.81.2", + "@zag-js/utils": "0.81.2" } }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.20.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.20.0.tgz", - "integrity": "sha512-Y7ncuy78bJqHI35NwzWol8E0X7XkRVS4K4P4TCyzWkOJih5NDvtoRDW4Ba9YJJoB2igm9yXDdYI/+fkiiAxPzA==", - "dev": true, + "node_modules/@zag-js/toast": { + "version": "0.81.2", + "resolved": "https://registry.npmjs.org/@zag-js/toast/-/toast-0.81.2.tgz", + "integrity": "sha512-9MAFg5qAGOpCtcp8vp0MPDxzaLyn/dNjs8mscNfV93DRUA2TOCz3SXllk/qNnUjdU+Ux2WV04OwbElz43sBjwg==", "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.20.0", - "@typescript-eslint/visitor-keys": "8.20.0", - "debug": "^4.3.4", - "fast-glob": "^3.3.2", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^2.0.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <5.8.0" + "@zag-js/anatomy": "0.81.2", + "@zag-js/core": "0.81.2", + "@zag-js/dismissable": "0.81.2", + "@zag-js/dom-query": "0.81.2", + "@zag-js/types": "0.81.2", + "@zag-js/utils": "0.81.2" } }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" + "node_modules/@zag-js/toggle-group": { + "version": "0.81.2", + "resolved": "https://registry.npmjs.org/@zag-js/toggle-group/-/toggle-group-0.81.2.tgz", + "integrity": "sha512-y6BbbOCvsNYUhUfQuswNZO/LpYhmwuO2vDE88GnWAO1g41epAG3ASrkYCtpApQKVbmIHh6gNa9taGhIhzo/13A==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "0.81.2", + "@zag-js/core": "0.81.2", + "@zag-js/dom-query": "0.81.2", + "@zag-js/types": "0.81.2", + "@zag-js/utils": "0.81.2" } }, - "node_modules/@typescript-eslint/utils": { - "version": "8.20.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.20.0.tgz", - "integrity": "sha512-dq70RUw6UK9ei7vxc4KQtBRk7qkHZv447OUZ6RPQMQl71I3NZxQJX/f32Smr+iqWrB02pHKn2yAdHBb0KNrRMA==", - "dev": true, + "node_modules/@zag-js/tooltip": { + "version": "0.81.2", + "resolved": "https://registry.npmjs.org/@zag-js/tooltip/-/tooltip-0.81.2.tgz", + "integrity": "sha512-qhpUUJwUf5DrlbKh533OJYU0kYo0Nuv6RoF7qs+XSqCx4btqyCNPseJf9/BX2UTqwo7J6cZwr0iqRwJgxx2k/Q==", "license": "MIT", "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "8.20.0", - "@typescript-eslint/types": "8.20.0", - "@typescript-eslint/typescript-estree": "8.20.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.8.0" + "@zag-js/anatomy": "0.81.2", + "@zag-js/core": "0.81.2", + "@zag-js/dom-query": "0.81.2", + "@zag-js/focus-visible": "0.81.2", + "@zag-js/popper": "0.81.2", + "@zag-js/types": "0.81.2", + "@zag-js/utils": "0.81.2" } }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.20.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.20.0.tgz", - "integrity": "sha512-v/BpkeeYAsPkKCkR8BDwcno0llhzWVqPOamQrAEMdpZav2Y9OVjd9dwJyBLJWwf335B5DmlifECIkZRJCaGaHA==", - "dev": true, + "node_modules/@zag-js/tour": { + "version": "0.81.2", + "resolved": "https://registry.npmjs.org/@zag-js/tour/-/tour-0.81.2.tgz", + "integrity": "sha512-RD9eEw9EN4Qa8awT3mS/pM9bCMR0aljt1UyTL8siR0jH/tMwZ7Vntuxb3bQGdyUSLQykyh1miczMS8zha84BKg==", "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.20.0", - "eslint-visitor-keys": "^4.2.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "@zag-js/anatomy": "0.81.2", + "@zag-js/core": "0.81.2", + "@zag-js/dismissable": "0.81.2", + "@zag-js/dom-query": "0.81.2", + "@zag-js/focus-trap": "0.81.2", + "@zag-js/interact-outside": "0.81.2", + "@zag-js/popper": "0.81.2", + "@zag-js/types": "0.81.2", + "@zag-js/utils": "0.81.2" } }, - "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", - "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "node_modules/@zag-js/tree-view": { + "version": "0.81.2", + "resolved": "https://registry.npmjs.org/@zag-js/tree-view/-/tree-view-0.81.2.tgz", + "integrity": "sha512-G782cRXUnACceINnpQTLEeg33n6nzProOCC38dguwqKNd1pUDloVnDyo87XHDxEA2WCi0CslGlxW8YuL5iOd9w==", + "license": "MIT", + "dependencies": { + "@zag-js/anatomy": "0.81.2", + "@zag-js/collection": "0.81.2", + "@zag-js/core": "0.81.2", + "@zag-js/dom-query": "0.81.2", + "@zag-js/types": "0.81.2", + "@zag-js/utils": "0.81.2" } }, - "node_modules/@vitejs/plugin-react": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.3.4.tgz", - "integrity": "sha512-SCCPBJtYLdE8PX/7ZQAs1QAZ8Jqwih+0VBLum1EGqmCCQal+MIUqLCzj3ZUy8ufbC0cAM4LRlSTm7IQJwWT4ug==", - "dev": true, + "node_modules/@zag-js/types": { + "version": "0.81.2", + "resolved": "https://registry.npmjs.org/@zag-js/types/-/types-0.81.2.tgz", + "integrity": "sha512-RmEN7+TrpJiS1NLqTvURmxhYyCrsuLKblbdR/MSJ2L0M0sdncyClSNhcXkjSd0wRuEaNPF97H5lvAhQ+nEMynQ==", "license": "MIT", "dependencies": { - "@babel/core": "^7.26.0", - "@babel/plugin-transform-react-jsx-self": "^7.25.9", - "@babel/plugin-transform-react-jsx-source": "^7.25.9", - "@types/babel__core": "^7.20.5", - "react-refresh": "^0.14.2" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "peerDependencies": { - "vite": "^4.2.0 || ^5.0.0 || ^6.0.0" + "csstype": "3.1.3" } }, + "node_modules/@zag-js/utils": { + "version": "0.81.2", + "resolved": "https://registry.npmjs.org/@zag-js/utils/-/utils-0.81.2.tgz", + "integrity": "sha512-lE3aCkA+e9tCiU10FS73CyiAa43folvKCDr5HMJ8se2MgYUyVfB5vjRKBvH3eAi4tcniwYjYY73pH5V7Gf2wnA==", + "license": "MIT" + }, "node_modules/abab": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", @@ -4095,24 +5507,24 @@ } }, "node_modules/algoliasearch": { - "version": "5.19.0", - "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.19.0.tgz", - "integrity": "sha512-zrLtGhC63z3sVLDDKGW+SlCRN9eJHFTgdEmoAOpsVh6wgGL1GgTTDou7tpCBjevzgIvi3AIyDAQO3Xjbg5eqZg==", - "license": "MIT", - "dependencies": { - "@algolia/client-abtesting": "5.19.0", - "@algolia/client-analytics": "5.19.0", - "@algolia/client-common": "5.19.0", - "@algolia/client-insights": "5.19.0", - "@algolia/client-personalization": "5.19.0", - "@algolia/client-query-suggestions": "5.19.0", - "@algolia/client-search": "5.19.0", - "@algolia/ingestion": "1.19.0", - "@algolia/monitoring": "1.19.0", - "@algolia/recommend": "5.19.0", - "@algolia/requester-browser-xhr": "5.19.0", - "@algolia/requester-fetch": "5.19.0", - "@algolia/requester-node-http": "5.19.0" + "version": "5.20.0", + "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.20.0.tgz", + "integrity": "sha512-groO71Fvi5SWpxjI9Ia+chy0QBwT61mg6yxJV27f5YFf+Mw+STT75K6SHySpP8Co5LsCrtsbCH5dJZSRtkSKaQ==", + "license": "MIT", + "dependencies": { + "@algolia/client-abtesting": "5.20.0", + "@algolia/client-analytics": "5.20.0", + "@algolia/client-common": "5.20.0", + "@algolia/client-insights": "5.20.0", + "@algolia/client-personalization": "5.20.0", + "@algolia/client-query-suggestions": "5.20.0", + "@algolia/client-search": "5.20.0", + "@algolia/ingestion": "1.20.0", + "@algolia/monitoring": "1.20.0", + "@algolia/recommend": "5.20.0", + "@algolia/requester-browser-xhr": "5.20.0", + "@algolia/requester-fetch": "5.20.0", + "@algolia/requester-node-http": "5.20.0" }, "engines": { "node": ">= 14.0.0" @@ -4189,6 +5601,18 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "license": "Python-2.0" }, + "node_modules/aria-hidden": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.4.tgz", + "integrity": "sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/aria-query": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", @@ -4505,6 +5929,21 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/babel-plugin-macros": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", + "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + } + }, "node_modules/babel-plugin-transform-import-meta": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/babel-plugin-transform-import-meta/-/babel-plugin-transform-import-meta-2.3.2.tgz", @@ -4735,7 +6174,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -4987,6 +6425,31 @@ "node": ">=18" } }, + "node_modules/cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "license": "MIT", + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/cosmiconfig/node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "license": "ISC", + "engines": { + "node": ">= 6" + } + }, "node_modules/create-jest": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", @@ -5080,7 +6543,6 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "devOptional": true, "license": "MIT" }, "node_modules/data-urls": { @@ -5162,7 +6624,6 @@ "version": "4.4.0", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", - "dev": true, "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -5322,6 +6783,12 @@ "node": ">=8" } }, + "node_modules/detect-node-es": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", + "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==", + "license": "MIT" + }, "node_modules/didyoumean": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", @@ -5488,7 +6955,6 @@ "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, "license": "MIT", "dependencies": { "is-arrayish": "^0.2.1" @@ -5719,7 +7185,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -6440,6 +7905,12 @@ "node": ">=8" } }, + "node_modules/find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", + "license": "MIT" + }, "node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -6669,6 +8140,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-nonce": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", + "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/get-package-type": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", @@ -7052,7 +8532,6 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, "license": "MIT", "dependencies": { "parent-module": "^1.0.0", @@ -7178,7 +8657,6 @@ "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true, "license": "MIT" }, "node_modules/is-async-function": { @@ -8828,7 +10306,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", - "dev": true, "license": "MIT", "bin": { "jsesc": "bin/jsesc" @@ -8848,7 +10325,6 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true, "license": "MIT" }, "node_modules/json-schema-traverse": { @@ -9254,7 +10730,6 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, "license": "MIT" }, "node_modules/mz": { @@ -9609,7 +11084,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, "license": "MIT", "dependencies": { "callsites": "^3.0.0" @@ -9622,7 +11096,6 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.0.0", @@ -9707,6 +11180,21 @@ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", "license": "ISC" }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/perfect-freehand": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/perfect-freehand/-/perfect-freehand-1.2.2.tgz", + "integrity": "sha512-eh31l019WICQ03pkF3FSzHxB8n07ItqIQ++G5UV8JX0zVOXzgTGCqnRR0jJ2h9U8/2uW4W4mtGJELt9kEV0CFQ==", + "license": "MIT" + }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -10153,12 +11641,27 @@ "react-is": "^16.13.1" } }, + "node_modules/proxy-compare": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/proxy-compare/-/proxy-compare-3.0.1.tgz", + "integrity": "sha512-V9plBAt3qjMlS1+nC8771KNf6oJ12gExvaxnNzN/9yVRLdTv/lc+oJlnSzrdYDAvBfTStPCoiaCOTmTs0adv7Q==", + "license": "MIT" + }, "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", "license": "MIT" }, + "node_modules/proxy-memoize": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/proxy-memoize/-/proxy-memoize-3.0.1.tgz", + "integrity": "sha512-VDdG/VYtOgdGkWJx7y0o7p+zArSf2383Isci8C+BP3YXgMYDoPd3cCBjw0JdWb6YBb9sFiOPbAADDVTPJnh+9g==", + "license": "MIT", + "dependencies": { + "proxy-compare": "^3.0.0" + } + }, "node_modules/psl": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz", @@ -10301,6 +11804,53 @@ "node": ">=0.10.0" } }, + "node_modules/react-remove-scroll": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.6.2.tgz", + "integrity": "sha512-KmONPx5fnlXYJQqC62Q+lwIeAk64ws/cUw6omIumRzMRPqgnYqhSSti99nbj0Ry13bv7dF+BKn7NB+OqkdZGTw==", + "license": "MIT", + "dependencies": { + "react-remove-scroll-bar": "^2.3.7", + "react-style-singleton": "^2.2.1", + "tslib": "^2.1.0", + "use-callback-ref": "^1.3.3", + "use-sidecar": "^1.1.2" + }, + "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 + } + } + }, + "node_modules/react-remove-scroll-bar": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.8.tgz", + "integrity": "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==", + "license": "MIT", + "dependencies": { + "react-style-singleton": "^2.2.2", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/react-router": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.1.3.tgz", @@ -10341,6 +11891,28 @@ "react-dom": ">=18" } }, + "node_modules/react-style-singleton": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.3.tgz", + "integrity": "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==", + "license": "MIT", + "dependencies": { + "get-nonce": "^1.0.0", + "tslib": "^2.0.0" + }, + "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 + } + } + }, "node_modules/react-tooltip": { "version": "5.28.0", "resolved": "https://registry.npmjs.org/react-tooltip/-/react-tooltip-5.28.0.tgz", @@ -10503,7 +12075,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, "license": "MIT", "engines": { "node": ">=4" @@ -11150,6 +12721,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/stylis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==", + "license": "MIT" + }, "node_modules/sucrase": { "version": "3.35.0", "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", @@ -11576,7 +13153,6 @@ "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "dev": true, "license": "0BSD" }, "node_modules/turbo-stream": { @@ -11714,15 +13290,15 @@ } }, "node_modules/typescript-eslint": { - "version": "8.20.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.20.0.tgz", - "integrity": "sha512-Kxz2QRFsgbWj6Xcftlw3Dd154b3cEPFqQC+qMZrMypSijPd4UanKKvoKDrJ4o8AIfZFKAF+7sMaEIR8mTElozA==", + "version": "8.21.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.21.0.tgz", + "integrity": "sha512-txEKYY4XMKwPXxNkN8+AxAdX6iIJAPiJbHE/FpQccs/sxw8Lf26kqwC3cn0xkHlW8kEbLhkhCsjWuMveaY9Rxw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/eslint-plugin": "8.20.0", - "@typescript-eslint/parser": "8.20.0", - "@typescript-eslint/utils": "8.20.0" + "@typescript-eslint/eslint-plugin": "8.21.0", + "@typescript-eslint/parser": "8.21.0", + "@typescript-eslint/utils": "8.21.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -11809,6 +13385,12 @@ "browserslist": ">= 4.21.0" } }, + "node_modules/uqr": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/uqr/-/uqr-0.1.2.tgz", + "integrity": "sha512-MJu7ypHq6QasgF5YRTjqscSzQp/W11zoUk6kvmlH+fmWEs63Y0Eib13hYFwAzagRJcVY8WVnlV+eBDUGMJ5IbA==", + "license": "MIT" + }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -11830,6 +13412,49 @@ "requires-port": "^1.0.0" } }, + "node_modules/use-callback-ref": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.3.tgz", + "integrity": "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.0" + }, + "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 + } + } + }, + "node_modules/use-sidecar": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.3.tgz", + "integrity": "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==", + "license": "MIT", + "dependencies": { + "detect-node-es": "^1.1.0", + "tslib": "^2.0.0" + }, + "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 + } + } + }, "node_modules/util": { "version": "0.12.5", "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", @@ -11873,10 +13498,11 @@ } }, "node_modules/vite": { - "version": "6.0.8", - "resolved": "https://registry.npmjs.org/vite/-/vite-6.0.8.tgz", - "integrity": "sha512-rJmB+6m3Qmo5nssFmm6hbSvaCS+5tH/iuTJYeHEOHMwqu/DPrjjBs1rlecCo4D0qy5xq506hMpkKx6pKaudUxA==", + "version": "6.0.11", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.0.11.tgz", + "integrity": "sha512-4VL9mQPKoHy4+FE0NnRE/kbY51TOfaknxAjt3fJbGJxhIpBZiqVzlZDEesWWsuREXHwNdAoOFZ9MkPEVXczHwg==", "dev": true, + "license": "MIT", "dependencies": { "esbuild": "^0.24.2", "postcss": "^8.4.49", diff --git a/frontend/package.json b/frontend/package.json index a9e694ad0..6a166372d 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -21,19 +21,24 @@ "@algolia/autocomplete-js": "^1.17.9", "@algolia/autocomplete-plugin-query-suggestions": "^1.17.9", "@algolia/autocomplete-theme-classic": "^1.17.9", + "@chakra-ui/react": "^3.4.0", + "@emotion/react": "^11.14.0", + "@emotion/styled": "^11.14.0", "@fortawesome/fontawesome-svg-core": "^6.7.0", "@fortawesome/free-brands-svg-icons": "^6.7.0", "@fortawesome/free-regular-svg-icons": "^6.7.0", "@fortawesome/free-solid-svg-icons": "^6.7.0", "@fortawesome/react-fontawesome": "^0.2.2", + "@radix-ui/react-dropdown-menu": "^2.1.4", + "@radix-ui/react-select": "^2.1.4", "@radix-ui/react-slot": "^1.1.1", "@radix-ui/react-toast": "^1.2.4", "@sentry/browser": "^8.46.0", - "@sentry/react": "^8.48.0", + "@sentry/react": "^8.51.0", "@sentry/tracing": "^7.120.3", - "@testing-library/user-event": "^14.6.0", + "@testing-library/user-event": "^14.6.1", "@types/lodash": "^4.17.14", - "algoliasearch": "^5.19.0", + "algoliasearch": "^5.20.0", "axios": "^1.7.9", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", @@ -57,18 +62,18 @@ }, "devDependencies": { "@eslint/js": "^9.15.0", - "@swc/core": "^1.10.7", + "@swc/core": "^1.10.9", "@swc/jest": "^0.2.37", "@testing-library/jest-dom": "^6.6.3", "@testing-library/react": "^16.2.0", "@types/jest": "^29.5.14", "@types/mocha": "^10.0.10", - "@types/node": "^22.10.7", + "@types/node": "^22.10.8", "@types/react": "^19.0.6", "@types/react-dom": "^19.0.3", "@types/react-gtm-module": "^2.0.4", - "@typescript-eslint/eslint-plugin": "^8.18.0", - "@typescript-eslint/parser": "^8.20.0", + "@typescript-eslint/eslint-plugin": "^8.21.0", + "@typescript-eslint/parser": "^8.21.0", "@vitejs/plugin-react": "^4.3.4", "autoprefixer": "^10.4.20", "babel-plugin-transform-import-meta": "^2.3.2", @@ -93,9 +98,9 @@ "ts-jest": "^29.2.5", "ts-node": "^10.9.2", "typescript": "~5.7.3", - "typescript-eslint": "^8.19.1", + "typescript-eslint": "^8.21.0", "util": "^0.12.5", - "vite": "^6.0.8", + "vite": "^6.0.11", "vite-plugin-environment": "^1.1.3" }, "engines": { diff --git a/frontend/src/api/fetchAlgoliaData.ts b/frontend/src/api/fetchAlgoliaData.ts index 6b018fa2a..d3bfcdadb 100644 --- a/frontend/src/api/fetchAlgoliaData.ts +++ b/frontend/src/api/fetchAlgoliaData.ts @@ -18,7 +18,7 @@ export const fetchAlgoliaData = async ( throw new AppError(500, 'Search client not initialized') } try { - const params = getParamsForIndexName(indexName) + const params = getParamsForIndexName(indexName.split('_')[0]) const request: AlgoliaRequestType = { attributesToHighlight: [], hitsPerPage: hitsPerPage, diff --git a/frontend/src/components/Header.tsx b/frontend/src/components/Header.tsx index d407afd89..55b91ab4e 100644 --- a/frontend/src/components/Header.tsx +++ b/frontend/src/components/Header.tsx @@ -1,4 +1,8 @@ +import { faHeart as faRegularHeart } from '@fortawesome/free-regular-svg-icons' // Outline Heart +import { faStar as faRegularStar } from '@fortawesome/free-regular-svg-icons' import { faBars, faTimes } from '@fortawesome/free-solid-svg-icons' +import { faHeart as faSolidHeart } from '@fortawesome/free-solid-svg-icons' +import { faStar as faSolidStar } from '@fortawesome/free-solid-svg-icons' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { useEffect, useState } from 'react' import { NavLink, useLocation } from 'react-router-dom' @@ -6,7 +10,7 @@ import { desktopViewMinWidth, headerLinks } from 'utils/constants' import { cn } from 'utils/utility' import ModeToggle from './ModeToggle' -import SponsorButton from './SponsorButton' +import NavButton from './NavButton' export default function Header() { const [mobileMenuOpen, setMobileMenuOpen] = useState(false) @@ -64,7 +68,24 @@ export default function Header() {
- + + +
+ + + {options.map((option) => ( + onSortChange(option.value)} + className="justify-between" + > + {option.label} + {option.value === selectedOption && } + + ))} + + + ) +} + +export default SortBy diff --git a/frontend/src/components/SponsorButton.tsx b/frontend/src/components/SponsorButton.tsx deleted file mode 100644 index 7075d8432..000000000 --- a/frontend/src/components/SponsorButton.tsx +++ /dev/null @@ -1,28 +0,0 @@ -// import { faHeart } from '@fortawesome/free-regular-svg-icons' -import { faHeart as faRegularHeart } from '@fortawesome/free-regular-svg-icons' // Outline Heart -import { faHeart as faSolidHeart } from '@fortawesome/free-solid-svg-icons' -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' -import { useState } from 'react' - -const SponsorButton = () => { - const [isHovered, setIsHovered] = useState(false) - return ( - setIsHovered(true)} - onMouseLeave={() => setIsHovered(false)} - > - - Sponsor - - ) -} - -export default SponsorButton diff --git a/frontend/src/components/ui/dropdownMenu.tsx b/frontend/src/components/ui/dropdownMenu.tsx new file mode 100644 index 000000000..a52b7955a --- /dev/null +++ b/frontend/src/components/ui/dropdownMenu.tsx @@ -0,0 +1,184 @@ +import { faCheck, faChevronRight, faDotCircle } from '@fortawesome/free-solid-svg-icons' +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' +import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu' +import * as React from 'react' +import { cn } from 'utils/utility' + +const DropdownMenu = DropdownMenuPrimitive.Root + +const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger + +const DropdownMenuGroup = DropdownMenuPrimitive.Group + +const DropdownMenuPortal = DropdownMenuPrimitive.Portal + +const DropdownMenuSub = DropdownMenuPrimitive.Sub + +const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup + +const DropdownMenuSubTrigger = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & { + inset?: boolean + } +>(({ className, inset, children, ...props }, ref) => ( + + {children} + + +)) +DropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName + +const DropdownMenuSubContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +DropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName + +const DropdownMenuContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, sideOffset = 4, ...props }, ref) => ( + + + +)) +DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName + +const DropdownMenuItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & { + inset?: boolean + } +>(({ className, inset, ...props }, ref) => ( + svg]:size-4 [&>svg]:shrink-0', + inset && 'pl-8', + className + )} + {...props} + /> +)) +DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName + +const DropdownMenuCheckboxItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, checked, ...props }, ref) => ( + + + + + + + {children} + +)) +DropdownMenuCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName + +const DropdownMenuRadioItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + + + + + + {children} + +)) +DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName + +const DropdownMenuLabel = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & { + inset?: boolean + } +>(({ className, inset, ...props }, ref) => ( + +)) +DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName + +const DropdownMenuSeparator = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName + +const DropdownMenuShortcut = ({ className, ...props }: React.HTMLAttributes) => { + return +} +DropdownMenuShortcut.displayName = 'DropdownMenuShortcut' + +export { + DropdownMenu, + DropdownMenuTrigger, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuCheckboxItem, + DropdownMenuRadioItem, + DropdownMenuLabel, + DropdownMenuSeparator, + DropdownMenuShortcut, + DropdownMenuGroup, + DropdownMenuPortal, + DropdownMenuSub, + DropdownMenuSubContent, + DropdownMenuSubTrigger, + DropdownMenuRadioGroup, +} diff --git a/frontend/src/hooks/useSearchPage.ts b/frontend/src/hooks/useSearchPage.ts index 879b30535..0348f292c 100644 --- a/frontend/src/hooks/useSearchPage.ts +++ b/frontend/src/hooks/useSearchPage.ts @@ -7,6 +7,7 @@ import { handleAppError } from 'wrappers/ErrorWrapper' interface UseSearchPageOptions { indexName: string pageTitle: string + defaultSortBy?: string } interface UseSearchPageReturn { @@ -15,21 +16,23 @@ interface UseSearchPageReturn { currentPage: number totalPages: number searchQuery: string - + sortBy: string handleSearch: (query: string) => void - handlePageChange: (page: number) => void + handleSortChange: (sort: string) => void } export function useSearchPage({ indexName, pageTitle, + defaultSortBy = '', }: UseSearchPageOptions): UseSearchPageReturn { const navigate = useNavigate() const [searchParams, setSearchParams] = useSearchParams() const [items, setItems] = useState([]) const [currentPage, setCurrentPage] = useState(parseInt(searchParams.get('page') || '1')) const [searchQuery, setSearchQuery] = useState(searchParams.get('q') || '') + const [sortBy, setSortBy] = useState(searchParams.get('sortBy') || defaultSortBy) const [totalPages, setTotalPages] = useState(0) const [isLoaded, setIsLoaded] = useState(false) @@ -37,8 +40,9 @@ export function useSearchPage({ const params = new URLSearchParams() if (searchQuery) params.set('q', searchQuery) if (currentPage > 1) params.set('page', currentPage.toString()) + if (sortBy && sortBy !== 'projects') params.set('sortBy', sortBy) setSearchParams(params) - }, [searchQuery, currentPage, setSearchParams]) + }, [searchQuery, currentPage, sortBy, setSearchParams]) useEffect(() => { document.title = pageTitle @@ -47,7 +51,7 @@ export function useSearchPage({ const fetchData = async () => { try { const data: AlgoliaResponseType = await fetchAlgoliaData( - indexName, + sortBy ? `${indexName}_${sortBy}` : indexName, searchQuery, currentPage ) @@ -60,7 +64,7 @@ export function useSearchPage({ } fetchData() - }, [currentPage, searchQuery, indexName, pageTitle, navigate]) + }, [currentPage, searchQuery, sortBy, indexName, pageTitle, navigate]) const handleSearch = (query: string) => { setSearchQuery(query) @@ -75,13 +79,20 @@ export function useSearchPage({ }) } + const handleSortChange = (sort: string) => { + setSortBy(sort) + setCurrentPage(1) + } + return { items, isLoaded, currentPage, totalPages, searchQuery, + sortBy, handleSearch, handlePageChange, + handleSortChange, } } diff --git a/frontend/src/main.tsx b/frontend/src/main.tsx index 12b369f78..3c8a70c86 100644 --- a/frontend/src/main.tsx +++ b/frontend/src/main.tsx @@ -1,3 +1,4 @@ +import { ChakraProvider, defaultSystem } from '@chakra-ui/react' import { StrictMode } from 'react' import { createRoot } from 'react-dom/client' import './index.css' @@ -20,7 +21,9 @@ createRoot(document.getElementById('root')!).render( - + + + diff --git a/frontend/src/pages/ChapterDetails.tsx b/frontend/src/pages/ChapterDetails.tsx index ea8aa8794..555aeb54e 100644 --- a/frontend/src/pages/ChapterDetails.tsx +++ b/frontend/src/pages/ChapterDetails.tsx @@ -33,7 +33,7 @@ const ChapterDetailsPage = () => {
) - if (!chapter) + if (!chapter || !chapter.is_active) return ( { topContributors={chapter.top_contributors} button={SubmitButton} social={formattedUrls} + isActive={chapter.is_active} />
diff --git a/frontend/src/pages/Chapters.tsx b/frontend/src/pages/Chapters.tsx index a8629669b..d5525b631 100644 --- a/frontend/src/pages/Chapters.tsx +++ b/frontend/src/pages/Chapters.tsx @@ -5,7 +5,6 @@ import { useNavigate } from 'react-router-dom' import { AlgoliaResponseType } from 'types/algolia' import { ChapterType } from 'types/chapter' import { getFilteredIcons, handleSocialUrls } from 'utils/utility' -import { AppError } from 'wrappers/ErrorWrapper' import FontAwesomeIconWrapper from 'wrappers/FontAwesomeIconWrapper' import Card from 'components/Card' import ChapterMap from 'components/ChapterMap' @@ -28,33 +27,27 @@ const ChaptersPage = () => { useEffect(() => { const fetchData = async () => { - try { - const searchParams = { - indexName: 'chapters', - query: '', - currentPage: 1, - filterKey: '', - hitsPerPage: 1000, - } - const data: AlgoliaResponseType = await fetchAlgoliaData( - searchParams.indexName, - searchParams.query, - searchParams.currentPage, - searchParams.filterKey, - searchParams.hitsPerPage - ) - setGeoLocData(data.hits) - } catch (error) { - if (error instanceof AppError) { - throw error - } + const searchParams = { + indexName: 'chapters', + query: '', + currentPage: 1, + filterKey: '', + hitsPerPage: 1000, } + const data: AlgoliaResponseType = await fetchAlgoliaData( + searchParams.indexName, + searchParams.query, + searchParams.currentPage, + searchParams.filterKey, + searchParams.hitsPerPage + ) + setGeoLocData(data.hits) } fetchData() }, []) const navigate = useNavigate() - const renderChapterCard = (chapter: ChapterType, index: number) => { + const renderChapterCard = (chapter: ChapterType) => { const params: string[] = ['updated_at'] const filteredIcons = getFilteredIcons(chapter, params) const formattedUrls = handleSocialUrls(chapter.related_urls) @@ -71,7 +64,7 @@ const ChaptersPage = () => { return ( { pageTitle: 'OWASP Committees', }) const navigate = useNavigate() - const renderCommitteeCard = (committee: CommitteeType, index: number) => { + const renderCommitteeCard = (committee: CommitteeType) => { const params: string[] = ['updated_at'] const filteredIcons = getFilteredIcons(committee, params) const formattedUrls = handleSocialUrls(committee.related_urls) @@ -36,7 +36,7 @@ const CommitteesPage = () => { return ( { } return ( - + { fetchProjectData() }, [projectKey]) + const navigate = useNavigate() + if (isLoading) return (
@@ -70,6 +72,9 @@ const ProjectDetailsPage = () => {

{project.name}

+ {!project.is_active && ( + Inactive + )}

{project.description}

Summary

@@ -198,9 +203,15 @@ const ProjectDetailsPage = () => {
{(showAllContributors ? project.top_contributors - : project.top_contributors.slice(0, 5) + : project.top_contributors.slice(0, 6) ).map((contributor, index) => ( -
+
{ + navigate(`/community/users/${contributor.login}`) + }} + > {contributor.name { const { @@ -14,14 +16,18 @@ const ProjectsPage = () => { currentPage, totalPages, searchQuery, + sortBy, handleSearch, handlePageChange, + handleSortChange, } = useSearchPage({ indexName: 'projects', pageTitle: 'OWASP Projects', + defaultSortBy: '', }) + const navigate = useNavigate() - const renderProjectCard = (project: project, index: number) => { + const renderProjectCard = (project: project) => { const params: string[] = ['updated_at', 'forks_count', 'stars_count', 'contributors_count'] const filteredIcons = getFilteredIcons(project, params) @@ -37,7 +43,7 @@ const ProjectsPage = () => { return ( { onPageChange={handlePageChange} empty="No projects found" searchPlaceholder="Search for OWASP projects..." + sortChildren={ + + } > - {projects && projects.map(renderProjectCard)} + {projects && projects.filter((project) => project.is_active).map(renderProjectCard)} ) } diff --git a/frontend/src/types/button.ts b/frontend/src/types/button.ts index 4dd79fd7f..6e8e521b8 100644 --- a/frontend/src/types/button.ts +++ b/frontend/src/types/button.ts @@ -1,3 +1,4 @@ +import { IconDefinition } from '@fortawesome/free-solid-svg-icons' import { JSX } from 'react' export type ButtonType = { @@ -6,3 +7,13 @@ export type ButtonType = { onclick?: () => void url?: string } + +export interface NavButtonProps { + href: string + defaultIcon: IconDefinition + hoverIcon: IconDefinition + defaultIconColor?: string + hoverIconColor?: string + text: string + className?: string +} diff --git a/frontend/src/types/card.ts b/frontend/src/types/card.ts index 3d21b12bb..add8a44cd 100644 --- a/frontend/src/types/card.ts +++ b/frontend/src/types/card.ts @@ -22,4 +22,5 @@ export interface CardProps { projectLink?: string social?: { title: string; icon: string; url: string }[] tooltipLabel?: string + isActive?: boolean } diff --git a/frontend/src/types/chapter.ts b/frontend/src/types/chapter.ts index 255a39792..45c16b945 100644 --- a/frontend/src/types/chapter.ts +++ b/frontend/src/types/chapter.ts @@ -1,5 +1,6 @@ export interface ChapterType { created_at: number + is_active: boolean key: string leaders: string[] name: string diff --git a/frontend/src/types/project.ts b/frontend/src/types/project.ts index 955839aa0..eec79e5a1 100644 --- a/frontend/src/types/project.ts +++ b/frontend/src/types/project.ts @@ -7,6 +7,7 @@ export type project = { }[] contributors_count: number forks_count: number + is_active: boolean leaders: string[] level: string name: string diff --git a/frontend/src/utils/paramsMapping.ts b/frontend/src/utils/paramsMapping.ts index 5331b7a78..3fb427ccb 100644 --- a/frontend/src/utils/paramsMapping.ts +++ b/frontend/src/utils/paramsMapping.ts @@ -22,6 +22,7 @@ export const getParamsForIndexName = (indexName: string, distinct = false) => { return { attributesToRetrieve: [ 'idx_created_at', + 'idx_is_active', 'idx_key', 'idx_leaders', 'idx_name', @@ -44,6 +45,7 @@ export const getParamsForIndexName = (indexName: string, distinct = false) => { 'idx_forks_count', 'idx_issues', 'idx_issues_count', + 'idx_is_active', 'idx_key', 'idx_languages', 'idx_leaders', diff --git a/frontend/src/utils/sortingOptions.ts b/frontend/src/utils/sortingOptions.ts new file mode 100644 index 000000000..15f63b0e9 --- /dev/null +++ b/frontend/src/utils/sortingOptions.ts @@ -0,0 +1,11 @@ +export const sortOptionsProject = [ + { label: 'Default', value: '' }, + { label: 'Name (A-Z)', value: 'name_asc' }, + { label: 'Name (Z-A)', value: 'name_desc' }, + { label: 'Stars (Low to High)', value: 'stars_count_asc' }, + { label: 'Stars (High to Low)', value: 'stars_count_desc' }, + { label: 'Contributors (Low to High)', value: 'contributors_count_asc' }, + { label: 'Contributors (High to Low)', value: 'contributors_count_desc' }, + { label: 'Forks (Low to High)', value: 'forks_count_asc' }, + { label: 'Forks (High to Low)', value: 'forks_count_desc' }, +]