- {% block content %}{% endblock %} + +
+ {% block content %} +
+

Try a Sample Request

+

Use the form below to test an API POST request.

+
+ + +
+
+
+ {% endblock %}
- - - - - + + + + + {% block script %}{% endblock %} diff --git a/backend/server/users/views.py b/backend/server/users/views.py index d5a5a4133..5fb7d2a23 100644 --- a/backend/server/users/views.py +++ b/backend/server/users/views.py @@ -11,8 +11,8 @@ from django.contrib.auth import get_user_model from .serializers import CustomUserDetailsSerializer as PublicUserSerializer from allauth.socialaccount.models import SocialApp -from adventures.serializers import AdventureSerializer, CollectionSerializer -from adventures.models import Adventure, Collection +from adventures.serializers import LocationSerializer, CollectionSerializer +from adventures.models import Location, Collection from allauth.socialaccount.models import SocialAccount User = get_user_model() @@ -99,9 +99,9 @@ def get(self, request, username): user.email = None # Get the users adventures and collections to include in the response - adventures = Adventure.objects.filter(user_id=user, is_public=True) - collections = Collection.objects.filter(user_id=user, is_public=True) - adventure_serializer = AdventureSerializer(adventures, many=True) + adventures = Location.objects.filter(user=user, is_public=True) + collections = Collection.objects.filter(user=user, is_public=True) + adventure_serializer = LocationSerializer(adventures, many=True) collection_serializer = CollectionSerializer(collections, many=True) return Response({ diff --git a/backend/server/worldtravel/management/commands/bulk-adventure-geocode.py b/backend/server/worldtravel/management/commands/bulk-adventure-geocode.py index 1a5d7a542..fff255eca 100644 --- a/backend/server/worldtravel/management/commands/bulk-adventure-geocode.py +++ b/backend/server/worldtravel/management/commands/bulk-adventure-geocode.py @@ -1,12 +1,12 @@ from django.core.management.base import BaseCommand -from adventures.models import Adventure +from adventures.models import Location import time class Command(BaseCommand): help = 'Bulk geocode all adventures by triggering save on each one' def handle(self, *args, **options): - adventures = Adventure.objects.all() + adventures = Location.objects.all() total = adventures.count() self.stdout.write(self.style.SUCCESS(f'Starting bulk geocoding of {total} adventures')) diff --git a/backend/server/worldtravel/migrations/0017_rename_user_id_visitedregion_user.py b/backend/server/worldtravel/migrations/0017_rename_user_id_visitedregion_user.py new file mode 100644 index 000000000..6614c77ec --- /dev/null +++ b/backend/server/worldtravel/migrations/0017_rename_user_id_visitedregion_user.py @@ -0,0 +1,18 @@ +# Generated by Django 5.2.1 on 2025-06-19 20:24 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('worldtravel', '0016_remove_city_insert_id_remove_country_insert_id_and_more'), + ] + + operations = [ + migrations.RenameField( + model_name='visitedregion', + old_name='user_id', + new_name='user', + ), + ] diff --git a/backend/server/worldtravel/migrations/0018_rename_user_id_visitedcity_user.py b/backend/server/worldtravel/migrations/0018_rename_user_id_visitedcity_user.py new file mode 100644 index 000000000..43cac9db1 --- /dev/null +++ b/backend/server/worldtravel/migrations/0018_rename_user_id_visitedcity_user.py @@ -0,0 +1,18 @@ +# Generated by Django 5.2.1 on 2025-06-19 20:24 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('worldtravel', '0017_rename_user_id_visitedregion_user'), + ] + + operations = [ + migrations.RenameField( + model_name='visitedcity', + old_name='user_id', + new_name='user', + ), + ] diff --git a/backend/server/worldtravel/models.py b/backend/server/worldtravel/models.py index 9e83f591e..e4f69e6d0 100644 --- a/backend/server/worldtravel/models.py +++ b/backend/server/worldtravel/models.py @@ -6,7 +6,7 @@ User = get_user_model() -default_user_id = 1 # Replace with an actual user ID +default_user = 1 # Replace with an actual user ID class Country(models.Model): @@ -50,29 +50,29 @@ def __str__(self): class VisitedRegion(models.Model): id = models.AutoField(primary_key=True) - user_id = models.ForeignKey( - User, on_delete=models.CASCADE, default=default_user_id) + user = models.ForeignKey( + User, on_delete=models.CASCADE, default=default_user) region = models.ForeignKey(Region, on_delete=models.CASCADE) def __str__(self): - return f'{self.region.name} ({self.region.country.country_code}) visited by: {self.user_id.username}' + return f'{self.region.name} ({self.region.country.country_code}) visited by: {self.user.username}' def save(self, *args, **kwargs): - if VisitedRegion.objects.filter(user_id=self.user_id, region=self.region).exists(): + if VisitedRegion.objects.filter(user=self.user, region=self.region).exists(): raise ValidationError("Region already visited by user.") super().save(*args, **kwargs) class VisitedCity(models.Model): id = models.AutoField(primary_key=True) - user_id = models.ForeignKey( - User, on_delete=models.CASCADE, default=default_user_id) + user = models.ForeignKey( + User, on_delete=models.CASCADE, default=default_user) city = models.ForeignKey(City, on_delete=models.CASCADE) def __str__(self): - return f'{self.city.name} ({self.city.region.name}) visited by: {self.user_id.username}' + return f'{self.city.name} ({self.city.region.name}) visited by: {self.user.username}' def save(self, *args, **kwargs): - if VisitedCity.objects.filter(user_id=self.user_id, city=self.city).exists(): + if VisitedCity.objects.filter(user=self.user, city=self.city).exists(): raise ValidationError("City already visited by user.") super().save(*args, **kwargs) diff --git a/backend/server/worldtravel/serializers.py b/backend/server/worldtravel/serializers.py index 962914bf7..a325abde2 100644 --- a/backend/server/worldtravel/serializers.py +++ b/backend/server/worldtravel/serializers.py @@ -25,7 +25,7 @@ def get_num_visits(self, obj): user = getattr(request, 'user', None) if user and user.is_authenticated: - return VisitedRegion.objects.filter(region__country=obj, user_id=user).count() + return VisitedRegion.objects.filter(region__country=obj, user=user).count() return 0 @@ -62,8 +62,8 @@ class VisitedRegionSerializer(CustomModelSerializer): class Meta: model = VisitedRegion - fields = ['id', 'user_id', 'region', 'longitude', 'latitude', 'name'] - read_only_fields = ['user_id', 'id', 'longitude', 'latitude', 'name'] + fields = ['id', 'user', 'region', 'longitude', 'latitude', 'name'] + read_only_fields = ['user', 'id', 'longitude', 'latitude', 'name'] class VisitedCitySerializer(CustomModelSerializer): longitude = serializers.DecimalField(source='city.longitude', max_digits=9, decimal_places=6, read_only=True) @@ -72,5 +72,5 @@ class VisitedCitySerializer(CustomModelSerializer): class Meta: model = VisitedCity - fields = ['id', 'user_id', 'city', 'longitude', 'latitude', 'name'] - read_only_fields = ['user_id', 'id', 'longitude', 'latitude', 'name'] \ No newline at end of file + fields = ['id', 'user', 'city', 'longitude', 'latitude', 'name'] + read_only_fields = ['user', 'id', 'longitude', 'latitude', 'name'] \ No newline at end of file diff --git a/backend/server/worldtravel/views.py b/backend/server/worldtravel/views.py index c77309d25..c418bf34e 100644 --- a/backend/server/worldtravel/views.py +++ b/backend/server/worldtravel/views.py @@ -13,7 +13,7 @@ from django.conf import settings from rest_framework.decorators import action from django.contrib.staticfiles import finders -from adventures.models import Adventure +from adventures.models import Location @api_view(['GET']) @permission_classes([IsAuthenticated]) @@ -28,7 +28,7 @@ def regions_by_country(request, country_code): @permission_classes([IsAuthenticated]) def visits_by_country(request, country_code): country = get_object_or_404(Country, country_code=country_code) - visits = VisitedRegion.objects.filter(region__country=country, user_id=request.user.id) + visits = VisitedRegion.objects.filter(region__country=country, user=request.user.id) serializer = VisitedRegionSerializer(visits, many=True) return Response(serializer.data) @@ -45,7 +45,7 @@ def cities_by_region(request, region_id): @permission_classes([IsAuthenticated]) def visits_by_region(request, region_id): region = get_object_or_404(Region, id=region_id) - visits = VisitedCity.objects.filter(city__region=region, user_id=request.user.id) + visits = VisitedCity.objects.filter(city__region=region, user=request.user.id) serializer = VisitedCitySerializer(visits, many=True) return Response(serializer.data) @@ -71,7 +71,7 @@ def check_point_in_region(self, request): # make a post action that will get all of the users adventures and check if the point is in any of the regions if so make a visited region object for that user if it does not already exist @action(detail=False, methods=['post']) def region_check_all_adventures(self, request): - adventures = Adventure.objects.filter(user_id=request.user.id, type='visited') + adventures = Location.objects.filter(user=request.user.id, type='visited') count = 0 for adventure in adventures: if adventure.latitude is not None and adventure.longitude is not None: @@ -79,8 +79,8 @@ def region_check_all_adventures(self, request): point = Point(float(adventure.longitude), float(adventure.latitude), srid=4326) region = Region.objects.filter(geometry__contains=point).first() if region: - if not VisitedRegion.objects.filter(user_id=request.user.id, region=region).exists(): - VisitedRegion.objects.create(user_id=request.user, region=region) + if not VisitedRegion.objects.filter(user=request.user.id, region=region).exists(): + VisitedRegion.objects.create(user=request.user, region=region) count += 1 except Exception as e: print(f"Error processing adventure {adventure.id}: {e}") @@ -97,14 +97,14 @@ class VisitedRegionViewSet(viewsets.ModelViewSet): permission_classes = [IsAuthenticated] def get_queryset(self): - return VisitedRegion.objects.filter(user_id=self.request.user.id) + return VisitedRegion.objects.filter(user=self.request.user.id) def perform_create(self, serializer): - serializer.save(user_id=self.request.user) + serializer.save(user=self.request.user) def create(self, request, *args, **kwargs): - request.data['user_id'] = request.user - if VisitedRegion.objects.filter(user_id=request.user.id, region=request.data['region']).exists(): + request.data['user'] = request.user + if VisitedRegion.objects.filter(user=request.user.id, region=request.data['region']).exists(): return Response({"error": "Region already visited by user."}, status=400) serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) @@ -115,7 +115,7 @@ def create(self, request, *args, **kwargs): def destroy(self, request, **kwargs): # delete by region id region = get_object_or_404(Region, id=kwargs['pk']) - visited_region = VisitedRegion.objects.filter(user_id=request.user.id, region=region) + visited_region = VisitedRegion.objects.filter(user=request.user.id, region=region) if visited_region.exists(): visited_region.delete() return Response(status=status.HTTP_204_NO_CONTENT) @@ -127,27 +127,27 @@ class VisitedCityViewSet(viewsets.ModelViewSet): permission_classes = [IsAuthenticated] def get_queryset(self): - return VisitedCity.objects.filter(user_id=self.request.user.id) + return VisitedCity.objects.filter(user=self.request.user.id) def perform_create(self, serializer): - serializer.save(user_id=self.request.user) + serializer.save(user=self.request.user) def create(self, request, *args, **kwargs): - request.data['user_id'] = request.user + request.data['user'] = request.user serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) self.perform_create(serializer) # if the region is not visited, visit it region = serializer.validated_data['city'].region - if not VisitedRegion.objects.filter(user_id=request.user.id, region=region).exists(): - VisitedRegion.objects.create(user_id=request.user, region=region) + if not VisitedRegion.objects.filter(user=request.user.id, region=region).exists(): + VisitedRegion.objects.create(user=request.user, region=region) headers = self.get_success_headers(serializer.data) return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers) def destroy(self, request, **kwargs): # delete by city id city = get_object_or_404(City, id=kwargs['pk']) - visited_city = VisitedCity.objects.filter(user_id=request.user.id, city=city) + visited_city = VisitedCity.objects.filter(user=request.user.id, city=city) if visited_city.exists(): visited_city.delete() return Response(status=status.HTTP_204_NO_CONTENT) diff --git a/brand/banner.png b/brand/banner.png index a0dd0ae75..f71e3c014 100644 Binary files a/brand/banner.png and b/brand/banner.png differ diff --git a/brand/screenshots/adventures.png b/brand/screenshots/adventures.png index 96204dfe1..9082dd78e 100644 Binary files a/brand/screenshots/adventures.png and b/brand/screenshots/adventures.png differ diff --git a/brand/screenshots/countries.png b/brand/screenshots/countries.png index 6eecc5946..e7f5e1e05 100644 Binary files a/brand/screenshots/countries.png and b/brand/screenshots/countries.png differ diff --git a/brand/screenshots/dashboard.png b/brand/screenshots/dashboard.png index 05ca98256..e885f6f03 100644 Binary files a/brand/screenshots/dashboard.png and b/brand/screenshots/dashboard.png differ diff --git a/brand/screenshots/details.png b/brand/screenshots/details.png index 47c99faac..051c5c4f4 100644 Binary files a/brand/screenshots/details.png and b/brand/screenshots/details.png differ diff --git a/brand/screenshots/edit.png b/brand/screenshots/edit.png index 1fce199d4..04480ce44 100644 Binary files a/brand/screenshots/edit.png and b/brand/screenshots/edit.png differ diff --git a/brand/screenshots/itinerary.png b/brand/screenshots/itinerary.png index c11cf4e4e..06d44f42e 100644 Binary files a/brand/screenshots/itinerary.png and b/brand/screenshots/itinerary.png differ diff --git a/brand/screenshots/map.png b/brand/screenshots/map.png index 081cb793c..4ca76e197 100644 Binary files a/brand/screenshots/map.png and b/brand/screenshots/map.png differ diff --git a/brand/screenshots/regions.png b/brand/screenshots/regions.png index 4aea537de..e6ae02cbc 100644 Binary files a/brand/screenshots/regions.png and b/brand/screenshots/regions.png differ diff --git a/documentation/.vitepress/config.mts b/documentation/.vitepress/config.mts index 212eedb68..a4a60f45a 100644 --- a/documentation/.vitepress/config.mts +++ b/documentation/.vitepress/config.mts @@ -149,6 +149,7 @@ export default defineConfig({ }, { text: "Traefik", link: "/docs/install/traefik" }, { text: "Caddy", link: "/docs/install/caddy" }, + { text: "HAProxy", link: "/docs/install/haproxy" }, ], }, ], diff --git a/documentation/docs/install/getting_started.md b/documentation/docs/install/getting_started.md index ff8d4b5f9..05e427e8c 100644 --- a/documentation/docs/install/getting_started.md +++ b/documentation/docs/install/getting_started.md @@ -24,3 +24,4 @@ Perfect for Docker beginners. - [Nginx Proxy Manager](nginx_proxy_manager.md) — Easy reverse proxy config - [Traefik](traefik.md) — Dynamic reverse proxy with automation - [Caddy](caddy.md) — Automatic HTTPS with a clean config +- [HAProxy](haproxy.md) — High-performance reverse proxy with advanced control diff --git a/documentation/docs/install/haproxy.md b/documentation/docs/install/haproxy.md new file mode 100644 index 000000000..1d33c05e0 --- /dev/null +++ b/documentation/docs/install/haproxy.md @@ -0,0 +1,31 @@ +# Installation with Haproxy + +HAProxy is a free and open source software that provides a high availability load balancer and Proxy for TCP and HTTP-based applications. + +You need to make the frontend and the backend available in order to have your AdventureLog working properly. +To do this, you will need to add 2 ACLs and 2 corresponding HAProxy backends in your haproxy configuration : +- One for your regular Adventurelog domain that will direct the requests to the frontend. +- One for the URLs that need to access the backend. + +Example : + +``` +listen http-s + bind :80 + + timeout connect 5s + timeout client 60s + + mode http + + acl is_adventurelog hdr_sub(Host) -i adventurelog + acl is_adventurelog_backend path_beg /media/ or /admin/ + + use_backend adventurelog_media if is_adventurelog is_adventurelog_backend + use_backend adventurelog if is_adventurelog + +backend adventurelog + server adventurelog 192.168.1.100:3000 check +backend adventurelog_backend + server adventurelog_media 192.168.1.100:8000 check +``` diff --git a/documentation/docs/intro/adventurelog_overview.md b/documentation/docs/intro/adventurelog_overview.md index 80cf63df2..d9e022c83 100644 --- a/documentation/docs/intro/adventurelog_overview.md +++ b/documentation/docs/intro/adventurelog_overview.md @@ -1,6 +1,6 @@ # About AdventureLog -Starting from a simple idea of tracking travel locations (called adventures), AdventureLog has grown into a full-fledged travel companion. With AdventureLog, you can log your adventures, keep track of where you've been on the world map, plan your next trip collaboratively, and share your experiences with friends and family. **AdventureLog is the ultimate travel companion for the modern-day explorer**. +Starting from a simple idea of tracking travel locations, AdventureLog has grown into a full-fledged travel companion. With AdventureLog, you can log your adventures, keep track of where you've been on the world map, plan your next trip collaboratively, and share your experiences with friends and family. **AdventureLog is the ultimate travel companion for the modern-day explorer**. ## Features diff --git a/documentation/docs/usage/usage.md b/documentation/docs/usage/usage.md index aa27cf328..c85a0f797 100644 --- a/documentation/docs/usage/usage.md +++ b/documentation/docs/usage/usage.md @@ -4,18 +4,23 @@ Welcome to AdventureLog! This guide will help you get started with AdventureLog ## Key Terms -#### Adventures +#### Locations -- **Adventure**: think of an adventure as a point on a map, a location you want to visit, or a place you want to explore. An adventure can be anything you want it to be, from a local park to a famous landmark. -- **Visit**: a visit is added to an adventure. It contains a date and notes about when the adventure was visited. If an adventure is visited multiple times, multiple visits can be added. If there are no visits on an adventure or the date of all visits is in the future, the adventure is considered planned. If the date of the visit is in the past, the adventure is considered completed. -- **Category**: a category is a way to group adventures together. For example, you could have a category for parks, a category for museums, and a category for restaurants. -- **Tag**: a tag is a way to add additional information to an adventure. For example, you could have a tag for the type of cuisine at a restaurant or the type of art at a museum. Multiple tags can be added to an adventure. -- **Image**: an image is a photo that is added to an adventure. Images can be added to an adventure to provide a visual representation of the location or to capture a memory of the visit. These can be uploaded from your device or with a service like [Immich](/docs/configuration/immich_integration) if the integration is enabled. -- **Attachment**: an attachment is a file that is added to an adventure. Attachments can be added to an adventure to provide additional information, such as a map of the location or a brochure from the visit. +::: tip Terminology Update +**Location has replaced Adventure:** +The term "Location" is now used instead of "Adventure" - the usage remains the same, just the name has changed to better reflect the purpose of the feature. +::: + +- **Location**: think of a location as a point on a map, a place you want to visit, have visited, or a place you want to explore. A location can be anything you want it to be, from a local park to a famous landmark. These are the building blocks of AdventureLog and are the fundamental unit of information in the app. +- **Visit**: a visit is added to an location. It contains a date and notes about when the location was visited. If a location is visited multiple times, multiple visits can be added. If there are no visits on a location or the date of all visits is in the future, the location is considered planned. If the date of the visit is in the past, the location is considered completed. +- **Category**: a category is a way to group locations together. For example, you could have a category for parks, a category for museums, and a category for restaurants. +- **Tag**: a tag is a way to add additional information to a location. For example, you could have a tag for the type of cuisine at a restaurant or the type of art at a museum. Multiple tags can be added to a location. +- **Image**: an image is a photo that is added to a location. Images can be added to a location to provide a visual representation or to capture a memory of the visit. These can be uploaded from your device or with a service like [Immich](/docs/configuration/immich_integration) if the integration is enabled. +- **Attachment**: an attachment is a file that is added to a location. Attachments can be added to a location to provide additional information, such as a map of the location or a brochure from the visit. #### Collections -- **Collection**: a collection is a way to group adventures together. Collections are flexible and can be used in many ways. When no start or end date is added to a collection, it acts like a folder to group adventures together. When a start and end date is added to a collection, it acts like a trip to group adventures together that were visited during that time period. With start and end dates, the collection is transformed into a full itinerary with a map showing the route taken between adventures. +- **Collection**: a collection is a way to group locations together. Collections are flexible and can be used in many ways. When no start or end date is added to a collection, it acts like a folder to group locations together. When a start and end date is added to a collection, it acts like a trip to group locations together that were visited during that time period. With start and end dates, the collection is transformed into a full itinerary with a map showing the route taken between locations. For example, you could have a collection for a trip to Europe with dates so you can plan where you want to visit, a collection of local hiking trails, or a collection for a list of restaurants you want to try. - **Transportation**: a transportation is a collection exclusive feature that allows you to add transportation information to your trip. This can be used to show the route taken between locations and the mode of transportation used. It can also be used to track flight information, such as flight number and departure time. - **Lodging**: a lodging is a collection exclusive feature that allows you to add lodging information to your trip. This can be used to plan where you will stay during your trip and add notes about the lodging location. It can also be used to track reservation information, such as reservation number and check-in time. - **Note**: a note is a collection exclusive feature that allows you to add notes to your trip. This can be used to add additional information about your trip, such as a summary of the trip or a list of things to do. Notes can be assigned to a specific day of the trip to help organize the information. diff --git a/frontend/package.json b/frontend/package.json index 95ff6c923..74263466d 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -50,5 +50,13 @@ "qrcode": "^1.5.4", "svelte-i18n": "^4.0.1", "svelte-maplibre": "^0.9.8" + }, + "overrides": { + "esbuild": "^0.25.0" + }, + "pnpm": { + "overrides": { + "esbuild": "^0.25.0" + } } } diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index aa4490a83..d213b71c6 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -4,6 +4,9 @@ settings: autoInstallPeers: true excludeLinksFromLockfile: false +overrides: + esbuild: ^0.25.0 + importers: .: @@ -137,428 +140,152 @@ packages: '@antfu/utils@8.1.1': resolution: {integrity: sha512-Mex9nXf9vR6AhcXmMrlz/HVgYYZpVGJ6YlPgwl7UnaFpnshXs6EK/oa5Gpf3CzENMjkvEx2tQtntGnb7UtSTOQ==} - '@esbuild/aix-ppc64@0.19.12': - resolution: {integrity: sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [aix] - - '@esbuild/aix-ppc64@0.21.5': - resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [aix] - - '@esbuild/aix-ppc64@0.24.2': - resolution: {integrity: sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==} + '@esbuild/aix-ppc64@0.25.5': + resolution: {integrity: sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA==} engines: {node: '>=18'} cpu: [ppc64] os: [aix] - '@esbuild/android-arm64@0.19.12': - resolution: {integrity: sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [android] - - '@esbuild/android-arm64@0.21.5': - resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} - engines: {node: '>=12'} - cpu: [arm64] - os: [android] - - '@esbuild/android-arm64@0.24.2': - resolution: {integrity: sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==} + '@esbuild/android-arm64@0.25.5': + resolution: {integrity: sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg==} engines: {node: '>=18'} cpu: [arm64] os: [android] - '@esbuild/android-arm@0.19.12': - resolution: {integrity: sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==} - engines: {node: '>=12'} - cpu: [arm] - os: [android] - - '@esbuild/android-arm@0.21.5': - resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} - engines: {node: '>=12'} - cpu: [arm] - os: [android] - - '@esbuild/android-arm@0.24.2': - resolution: {integrity: sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==} + '@esbuild/android-arm@0.25.5': + resolution: {integrity: sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA==} engines: {node: '>=18'} cpu: [arm] os: [android] - '@esbuild/android-x64@0.19.12': - resolution: {integrity: sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==} - engines: {node: '>=12'} - cpu: [x64] - os: [android] - - '@esbuild/android-x64@0.21.5': - resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} - engines: {node: '>=12'} - cpu: [x64] - os: [android] - - '@esbuild/android-x64@0.24.2': - resolution: {integrity: sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==} + '@esbuild/android-x64@0.25.5': + resolution: {integrity: sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw==} engines: {node: '>=18'} cpu: [x64] os: [android] - '@esbuild/darwin-arm64@0.19.12': - resolution: {integrity: sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==} - engines: {node: '>=12'} - cpu: [arm64] - os: [darwin] - - '@esbuild/darwin-arm64@0.21.5': - resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} - engines: {node: '>=12'} - cpu: [arm64] - os: [darwin] - - '@esbuild/darwin-arm64@0.24.2': - resolution: {integrity: sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==} + '@esbuild/darwin-arm64@0.25.5': + resolution: {integrity: sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] - '@esbuild/darwin-x64@0.19.12': - resolution: {integrity: sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==} - engines: {node: '>=12'} - cpu: [x64] - os: [darwin] - - '@esbuild/darwin-x64@0.21.5': - resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} - engines: {node: '>=12'} - cpu: [x64] - os: [darwin] - - '@esbuild/darwin-x64@0.24.2': - resolution: {integrity: sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==} + '@esbuild/darwin-x64@0.25.5': + resolution: {integrity: sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ==} engines: {node: '>=18'} cpu: [x64] os: [darwin] - '@esbuild/freebsd-arm64@0.19.12': - resolution: {integrity: sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [freebsd] - - '@esbuild/freebsd-arm64@0.21.5': - resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} - engines: {node: '>=12'} - cpu: [arm64] - os: [freebsd] - - '@esbuild/freebsd-arm64@0.24.2': - resolution: {integrity: sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==} + '@esbuild/freebsd-arm64@0.25.5': + resolution: {integrity: sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-x64@0.19.12': - resolution: {integrity: sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==} - engines: {node: '>=12'} - cpu: [x64] - os: [freebsd] - - '@esbuild/freebsd-x64@0.21.5': - resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [freebsd] - - '@esbuild/freebsd-x64@0.24.2': - resolution: {integrity: sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==} + '@esbuild/freebsd-x64@0.25.5': + resolution: {integrity: sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] - '@esbuild/linux-arm64@0.19.12': - resolution: {integrity: sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [linux] - - '@esbuild/linux-arm64@0.21.5': - resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} - engines: {node: '>=12'} - cpu: [arm64] - os: [linux] - - '@esbuild/linux-arm64@0.24.2': - resolution: {integrity: sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==} + '@esbuild/linux-arm64@0.25.5': + resolution: {integrity: sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg==} engines: {node: '>=18'} cpu: [arm64] os: [linux] - '@esbuild/linux-arm@0.19.12': - resolution: {integrity: sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==} - engines: {node: '>=12'} - cpu: [arm] - os: [linux] - - '@esbuild/linux-arm@0.21.5': - resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} - engines: {node: '>=12'} - cpu: [arm] - os: [linux] - - '@esbuild/linux-arm@0.24.2': - resolution: {integrity: sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==} + '@esbuild/linux-arm@0.25.5': + resolution: {integrity: sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw==} engines: {node: '>=18'} cpu: [arm] os: [linux] - '@esbuild/linux-ia32@0.19.12': - resolution: {integrity: sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==} - engines: {node: '>=12'} - cpu: [ia32] - os: [linux] - - '@esbuild/linux-ia32@0.21.5': - resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} - engines: {node: '>=12'} - cpu: [ia32] - os: [linux] - - '@esbuild/linux-ia32@0.24.2': - resolution: {integrity: sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==} + '@esbuild/linux-ia32@0.25.5': + resolution: {integrity: sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA==} engines: {node: '>=18'} cpu: [ia32] os: [linux] - '@esbuild/linux-loong64@0.19.12': - resolution: {integrity: sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==} - engines: {node: '>=12'} - cpu: [loong64] - os: [linux] - - '@esbuild/linux-loong64@0.21.5': - resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} - engines: {node: '>=12'} - cpu: [loong64] - os: [linux] - - '@esbuild/linux-loong64@0.24.2': - resolution: {integrity: sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==} + '@esbuild/linux-loong64@0.25.5': + resolution: {integrity: sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg==} engines: {node: '>=18'} cpu: [loong64] os: [linux] - '@esbuild/linux-mips64el@0.19.12': - resolution: {integrity: sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==} - engines: {node: '>=12'} - cpu: [mips64el] - os: [linux] - - '@esbuild/linux-mips64el@0.21.5': - resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} - engines: {node: '>=12'} - cpu: [mips64el] - os: [linux] - - '@esbuild/linux-mips64el@0.24.2': - resolution: {integrity: sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==} + '@esbuild/linux-mips64el@0.25.5': + resolution: {integrity: sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] - '@esbuild/linux-ppc64@0.19.12': - resolution: {integrity: sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [linux] - - '@esbuild/linux-ppc64@0.21.5': - resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [linux] - - '@esbuild/linux-ppc64@0.24.2': - resolution: {integrity: sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==} + '@esbuild/linux-ppc64@0.25.5': + resolution: {integrity: sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] - '@esbuild/linux-riscv64@0.19.12': - resolution: {integrity: sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==} - engines: {node: '>=12'} - cpu: [riscv64] - os: [linux] - - '@esbuild/linux-riscv64@0.21.5': - resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} - engines: {node: '>=12'} - cpu: [riscv64] - os: [linux] - - '@esbuild/linux-riscv64@0.24.2': - resolution: {integrity: sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==} + '@esbuild/linux-riscv64@0.25.5': + resolution: {integrity: sha512-kTxwu4mLyeOlsVIFPfQo+fQJAV9mh24xL+y+Bm6ej067sYANjyEw1dNHmvoqxJUCMnkBdKpvOn0Ahql6+4VyeA==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] - '@esbuild/linux-s390x@0.19.12': - resolution: {integrity: sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==} - engines: {node: '>=12'} - cpu: [s390x] - os: [linux] - - '@esbuild/linux-s390x@0.21.5': - resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} - engines: {node: '>=12'} - cpu: [s390x] - os: [linux] - - '@esbuild/linux-s390x@0.24.2': - resolution: {integrity: sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==} + '@esbuild/linux-s390x@0.25.5': + resolution: {integrity: sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ==} engines: {node: '>=18'} cpu: [s390x] os: [linux] - '@esbuild/linux-x64@0.19.12': - resolution: {integrity: sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==} - engines: {node: '>=12'} - cpu: [x64] - os: [linux] - - '@esbuild/linux-x64@0.21.5': - resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [linux] - - '@esbuild/linux-x64@0.24.2': - resolution: {integrity: sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==} + '@esbuild/linux-x64@0.25.5': + resolution: {integrity: sha512-uhj8N2obKTE6pSZ+aMUbqq+1nXxNjZIIjCjGLfsWvVpy7gKCOL6rsY1MhRh9zLtUtAI7vpgLMK6DxjO8Qm9lJw==} engines: {node: '>=18'} cpu: [x64] os: [linux] - '@esbuild/netbsd-arm64@0.24.2': - resolution: {integrity: sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==} + '@esbuild/netbsd-arm64@0.25.5': + resolution: {integrity: sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] - '@esbuild/netbsd-x64@0.19.12': - resolution: {integrity: sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==} - engines: {node: '>=12'} - cpu: [x64] - os: [netbsd] - - '@esbuild/netbsd-x64@0.21.5': - resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} - engines: {node: '>=12'} - cpu: [x64] - os: [netbsd] - - '@esbuild/netbsd-x64@0.24.2': - resolution: {integrity: sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==} + '@esbuild/netbsd-x64@0.25.5': + resolution: {integrity: sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] - '@esbuild/openbsd-arm64@0.24.2': - resolution: {integrity: sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==} + '@esbuild/openbsd-arm64@0.25.5': + resolution: {integrity: sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] - '@esbuild/openbsd-x64@0.19.12': - resolution: {integrity: sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==} - engines: {node: '>=12'} - cpu: [x64] - os: [openbsd] - - '@esbuild/openbsd-x64@0.21.5': - resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} - engines: {node: '>=12'} - cpu: [x64] - os: [openbsd] - - '@esbuild/openbsd-x64@0.24.2': - resolution: {integrity: sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==} + '@esbuild/openbsd-x64@0.25.5': + resolution: {integrity: sha512-G4hE405ErTWraiZ8UiSoesH8DaCsMm0Cay4fsFWOOUcz8b8rC6uCvnagr+gnioEjWn0wC+o1/TAHt+It+MpIMg==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] - '@esbuild/sunos-x64@0.19.12': - resolution: {integrity: sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==} - engines: {node: '>=12'} - cpu: [x64] - os: [sunos] - - '@esbuild/sunos-x64@0.21.5': - resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} - engines: {node: '>=12'} - cpu: [x64] - os: [sunos] - - '@esbuild/sunos-x64@0.24.2': - resolution: {integrity: sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==} + '@esbuild/sunos-x64@0.25.5': + resolution: {integrity: sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA==} engines: {node: '>=18'} cpu: [x64] os: [sunos] - '@esbuild/win32-arm64@0.19.12': - resolution: {integrity: sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==} - engines: {node: '>=12'} - cpu: [arm64] - os: [win32] - - '@esbuild/win32-arm64@0.21.5': - resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} - engines: {node: '>=12'} - cpu: [arm64] - os: [win32] - - '@esbuild/win32-arm64@0.24.2': - resolution: {integrity: sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==} + '@esbuild/win32-arm64@0.25.5': + resolution: {integrity: sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw==} engines: {node: '>=18'} cpu: [arm64] os: [win32] - '@esbuild/win32-ia32@0.19.12': - resolution: {integrity: sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==} - engines: {node: '>=12'} - cpu: [ia32] - os: [win32] - - '@esbuild/win32-ia32@0.21.5': - resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} - engines: {node: '>=12'} - cpu: [ia32] - os: [win32] - - '@esbuild/win32-ia32@0.24.2': - resolution: {integrity: sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==} + '@esbuild/win32-ia32@0.25.5': + resolution: {integrity: sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ==} engines: {node: '>=18'} cpu: [ia32] os: [win32] - '@esbuild/win32-x64@0.19.12': - resolution: {integrity: sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==} - engines: {node: '>=12'} - cpu: [x64] - os: [win32] - - '@esbuild/win32-x64@0.21.5': - resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} - engines: {node: '>=12'} - cpu: [x64] - os: [win32] - - '@esbuild/win32-x64@0.24.2': - resolution: {integrity: sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==} + '@esbuild/win32-x64@0.25.5': + resolution: {integrity: sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g==} engines: {node: '>=18'} cpu: [x64] os: [win32] @@ -1188,18 +915,8 @@ packages: es6-weak-map@2.0.3: resolution: {integrity: sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==} - esbuild@0.19.12: - resolution: {integrity: sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==} - engines: {node: '>=12'} - hasBin: true - - esbuild@0.21.5: - resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} - engines: {node: '>=12'} - hasBin: true - - esbuild@0.24.2: - resolution: {integrity: sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==} + esbuild@0.25.5: + resolution: {integrity: sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ==} engines: {node: '>=18'} hasBin: true @@ -2189,217 +1906,79 @@ snapshots: '@antfu/utils@8.1.1': {} - '@esbuild/aix-ppc64@0.19.12': - optional: true - - '@esbuild/aix-ppc64@0.21.5': - optional: true - - '@esbuild/aix-ppc64@0.24.2': - optional: true - - '@esbuild/android-arm64@0.19.12': - optional: true - - '@esbuild/android-arm64@0.21.5': - optional: true - - '@esbuild/android-arm64@0.24.2': - optional: true - - '@esbuild/android-arm@0.19.12': - optional: true - - '@esbuild/android-arm@0.21.5': - optional: true - - '@esbuild/android-arm@0.24.2': - optional: true - - '@esbuild/android-x64@0.19.12': - optional: true - - '@esbuild/android-x64@0.21.5': - optional: true - - '@esbuild/android-x64@0.24.2': - optional: true - - '@esbuild/darwin-arm64@0.19.12': - optional: true - - '@esbuild/darwin-arm64@0.21.5': - optional: true - - '@esbuild/darwin-arm64@0.24.2': - optional: true - - '@esbuild/darwin-x64@0.19.12': - optional: true - - '@esbuild/darwin-x64@0.21.5': - optional: true - - '@esbuild/darwin-x64@0.24.2': - optional: true - - '@esbuild/freebsd-arm64@0.19.12': - optional: true - - '@esbuild/freebsd-arm64@0.21.5': - optional: true - - '@esbuild/freebsd-arm64@0.24.2': - optional: true - - '@esbuild/freebsd-x64@0.19.12': - optional: true - - '@esbuild/freebsd-x64@0.21.5': - optional: true - - '@esbuild/freebsd-x64@0.24.2': - optional: true - - '@esbuild/linux-arm64@0.19.12': - optional: true - - '@esbuild/linux-arm64@0.21.5': + '@esbuild/aix-ppc64@0.25.5': optional: true - '@esbuild/linux-arm64@0.24.2': + '@esbuild/android-arm64@0.25.5': optional: true - '@esbuild/linux-arm@0.19.12': + '@esbuild/android-arm@0.25.5': optional: true - '@esbuild/linux-arm@0.21.5': + '@esbuild/android-x64@0.25.5': optional: true - '@esbuild/linux-arm@0.24.2': + '@esbuild/darwin-arm64@0.25.5': optional: true - '@esbuild/linux-ia32@0.19.12': + '@esbuild/darwin-x64@0.25.5': optional: true - '@esbuild/linux-ia32@0.21.5': + '@esbuild/freebsd-arm64@0.25.5': optional: true - '@esbuild/linux-ia32@0.24.2': + '@esbuild/freebsd-x64@0.25.5': optional: true - '@esbuild/linux-loong64@0.19.12': + '@esbuild/linux-arm64@0.25.5': optional: true - '@esbuild/linux-loong64@0.21.5': + '@esbuild/linux-arm@0.25.5': optional: true - '@esbuild/linux-loong64@0.24.2': + '@esbuild/linux-ia32@0.25.5': optional: true - '@esbuild/linux-mips64el@0.19.12': + '@esbuild/linux-loong64@0.25.5': optional: true - '@esbuild/linux-mips64el@0.21.5': + '@esbuild/linux-mips64el@0.25.5': optional: true - '@esbuild/linux-mips64el@0.24.2': + '@esbuild/linux-ppc64@0.25.5': optional: true - '@esbuild/linux-ppc64@0.19.12': + '@esbuild/linux-riscv64@0.25.5': optional: true - '@esbuild/linux-ppc64@0.21.5': + '@esbuild/linux-s390x@0.25.5': optional: true - '@esbuild/linux-ppc64@0.24.2': + '@esbuild/linux-x64@0.25.5': optional: true - '@esbuild/linux-riscv64@0.19.12': + '@esbuild/netbsd-arm64@0.25.5': optional: true - '@esbuild/linux-riscv64@0.21.5': + '@esbuild/netbsd-x64@0.25.5': optional: true - '@esbuild/linux-riscv64@0.24.2': + '@esbuild/openbsd-arm64@0.25.5': optional: true - '@esbuild/linux-s390x@0.19.12': + '@esbuild/openbsd-x64@0.25.5': optional: true - '@esbuild/linux-s390x@0.21.5': + '@esbuild/sunos-x64@0.25.5': optional: true - '@esbuild/linux-s390x@0.24.2': + '@esbuild/win32-arm64@0.25.5': optional: true - '@esbuild/linux-x64@0.19.12': + '@esbuild/win32-ia32@0.25.5': optional: true - '@esbuild/linux-x64@0.21.5': - optional: true - - '@esbuild/linux-x64@0.24.2': - optional: true - - '@esbuild/netbsd-arm64@0.24.2': - optional: true - - '@esbuild/netbsd-x64@0.19.12': - optional: true - - '@esbuild/netbsd-x64@0.21.5': - optional: true - - '@esbuild/netbsd-x64@0.24.2': - optional: true - - '@esbuild/openbsd-arm64@0.24.2': - optional: true - - '@esbuild/openbsd-x64@0.19.12': - optional: true - - '@esbuild/openbsd-x64@0.21.5': - optional: true - - '@esbuild/openbsd-x64@0.24.2': - optional: true - - '@esbuild/sunos-x64@0.19.12': - optional: true - - '@esbuild/sunos-x64@0.21.5': - optional: true - - '@esbuild/sunos-x64@0.24.2': - optional: true - - '@esbuild/win32-arm64@0.19.12': - optional: true - - '@esbuild/win32-arm64@0.21.5': - optional: true - - '@esbuild/win32-arm64@0.24.2': - optional: true - - '@esbuild/win32-ia32@0.19.12': - optional: true - - '@esbuild/win32-ia32@0.21.5': - optional: true - - '@esbuild/win32-ia32@0.24.2': - optional: true - - '@esbuild/win32-x64@0.19.12': - optional: true - - '@esbuild/win32-x64@0.21.5': - optional: true - - '@esbuild/win32-x64@0.24.2': + '@esbuild/win32-x64@0.25.5': optional: true '@event-calendar/core@3.12.0': @@ -2673,7 +2252,7 @@ snapshots: dependencies: '@sveltejs/kit': 2.20.7(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.19(@types/node@22.15.2)))(svelte@4.2.19)(vite@5.4.19(@types/node@22.15.2)) '@vercel/nft': 0.29.2(rollup@4.40.2) - esbuild: 0.24.2 + esbuild: 0.25.5 transitivePeerDependencies: - encoding - rollup @@ -3046,85 +2625,33 @@ snapshots: es6-iterator: 2.0.3 es6-symbol: 3.1.4 - esbuild@0.19.12: - optionalDependencies: - '@esbuild/aix-ppc64': 0.19.12 - '@esbuild/android-arm': 0.19.12 - '@esbuild/android-arm64': 0.19.12 - '@esbuild/android-x64': 0.19.12 - '@esbuild/darwin-arm64': 0.19.12 - '@esbuild/darwin-x64': 0.19.12 - '@esbuild/freebsd-arm64': 0.19.12 - '@esbuild/freebsd-x64': 0.19.12 - '@esbuild/linux-arm': 0.19.12 - '@esbuild/linux-arm64': 0.19.12 - '@esbuild/linux-ia32': 0.19.12 - '@esbuild/linux-loong64': 0.19.12 - '@esbuild/linux-mips64el': 0.19.12 - '@esbuild/linux-ppc64': 0.19.12 - '@esbuild/linux-riscv64': 0.19.12 - '@esbuild/linux-s390x': 0.19.12 - '@esbuild/linux-x64': 0.19.12 - '@esbuild/netbsd-x64': 0.19.12 - '@esbuild/openbsd-x64': 0.19.12 - '@esbuild/sunos-x64': 0.19.12 - '@esbuild/win32-arm64': 0.19.12 - '@esbuild/win32-ia32': 0.19.12 - '@esbuild/win32-x64': 0.19.12 - - esbuild@0.21.5: - optionalDependencies: - '@esbuild/aix-ppc64': 0.21.5 - '@esbuild/android-arm': 0.21.5 - '@esbuild/android-arm64': 0.21.5 - '@esbuild/android-x64': 0.21.5 - '@esbuild/darwin-arm64': 0.21.5 - '@esbuild/darwin-x64': 0.21.5 - '@esbuild/freebsd-arm64': 0.21.5 - '@esbuild/freebsd-x64': 0.21.5 - '@esbuild/linux-arm': 0.21.5 - '@esbuild/linux-arm64': 0.21.5 - '@esbuild/linux-ia32': 0.21.5 - '@esbuild/linux-loong64': 0.21.5 - '@esbuild/linux-mips64el': 0.21.5 - '@esbuild/linux-ppc64': 0.21.5 - '@esbuild/linux-riscv64': 0.21.5 - '@esbuild/linux-s390x': 0.21.5 - '@esbuild/linux-x64': 0.21.5 - '@esbuild/netbsd-x64': 0.21.5 - '@esbuild/openbsd-x64': 0.21.5 - '@esbuild/sunos-x64': 0.21.5 - '@esbuild/win32-arm64': 0.21.5 - '@esbuild/win32-ia32': 0.21.5 - '@esbuild/win32-x64': 0.21.5 - - esbuild@0.24.2: + esbuild@0.25.5: optionalDependencies: - '@esbuild/aix-ppc64': 0.24.2 - '@esbuild/android-arm': 0.24.2 - '@esbuild/android-arm64': 0.24.2 - '@esbuild/android-x64': 0.24.2 - '@esbuild/darwin-arm64': 0.24.2 - '@esbuild/darwin-x64': 0.24.2 - '@esbuild/freebsd-arm64': 0.24.2 - '@esbuild/freebsd-x64': 0.24.2 - '@esbuild/linux-arm': 0.24.2 - '@esbuild/linux-arm64': 0.24.2 - '@esbuild/linux-ia32': 0.24.2 - '@esbuild/linux-loong64': 0.24.2 - '@esbuild/linux-mips64el': 0.24.2 - '@esbuild/linux-ppc64': 0.24.2 - '@esbuild/linux-riscv64': 0.24.2 - '@esbuild/linux-s390x': 0.24.2 - '@esbuild/linux-x64': 0.24.2 - '@esbuild/netbsd-arm64': 0.24.2 - '@esbuild/netbsd-x64': 0.24.2 - '@esbuild/openbsd-arm64': 0.24.2 - '@esbuild/openbsd-x64': 0.24.2 - '@esbuild/sunos-x64': 0.24.2 - '@esbuild/win32-arm64': 0.24.2 - '@esbuild/win32-ia32': 0.24.2 - '@esbuild/win32-x64': 0.24.2 + '@esbuild/aix-ppc64': 0.25.5 + '@esbuild/android-arm': 0.25.5 + '@esbuild/android-arm64': 0.25.5 + '@esbuild/android-x64': 0.25.5 + '@esbuild/darwin-arm64': 0.25.5 + '@esbuild/darwin-x64': 0.25.5 + '@esbuild/freebsd-arm64': 0.25.5 + '@esbuild/freebsd-x64': 0.25.5 + '@esbuild/linux-arm': 0.25.5 + '@esbuild/linux-arm64': 0.25.5 + '@esbuild/linux-ia32': 0.25.5 + '@esbuild/linux-loong64': 0.25.5 + '@esbuild/linux-mips64el': 0.25.5 + '@esbuild/linux-ppc64': 0.25.5 + '@esbuild/linux-riscv64': 0.25.5 + '@esbuild/linux-s390x': 0.25.5 + '@esbuild/linux-x64': 0.25.5 + '@esbuild/netbsd-arm64': 0.25.5 + '@esbuild/netbsd-x64': 0.25.5 + '@esbuild/openbsd-arm64': 0.25.5 + '@esbuild/openbsd-x64': 0.25.5 + '@esbuild/sunos-x64': 0.25.5 + '@esbuild/win32-arm64': 0.25.5 + '@esbuild/win32-ia32': 0.25.5 + '@esbuild/win32-x64': 0.25.5 escalade@3.2.0: {} @@ -3827,7 +3354,7 @@ snapshots: dependencies: cli-color: 2.0.4 deepmerge: 4.3.1 - esbuild: 0.19.12 + esbuild: 0.25.5 estree-walker: 2.0.2 intl-messageformat: 10.7.16 sade: 1.8.1 @@ -3981,7 +3508,7 @@ snapshots: vite@5.4.19(@types/node@22.15.2): dependencies: - esbuild: 0.21.5 + esbuild: 0.25.5 postcss: 8.5.3 rollup: 4.40.2 optionalDependencies: diff --git a/frontend/src/lib/components/AboutModal.svelte b/frontend/src/lib/components/AboutModal.svelte index 46ad5aac3..e437bc8ad 100644 --- a/frontend/src/lib/components/AboutModal.svelte +++ b/frontend/src/lib/components/AboutModal.svelte @@ -33,146 +33,201 @@ } - + - - diff --git a/frontend/src/lib/components/Avatar.svelte b/frontend/src/lib/components/Avatar.svelte index 28cb9527a..72f23326b 100644 --- a/frontend/src/lib/components/Avatar.svelte +++ b/frontend/src/lib/components/Avatar.svelte @@ -31,9 +31,9 @@ section: 'main' }, { - path: '/adventures', + path: '/locations', icon: MapMarker, - label: 'navbar.my_adventures', + label: 'locations.my_locations', section: 'main' }, { diff --git a/frontend/src/lib/components/CardCarousel.svelte b/frontend/src/lib/components/CardCarousel.svelte index 60f9b38be..f8b947be0 100644 --- a/frontend/src/lib/components/CardCarousel.svelte +++ b/frontend/src/lib/components/CardCarousel.svelte @@ -1,12 +1,13 @@ -{#if image_url} +{#if showImageModal && adventure_images.length > 0} (image_url = null)} + images={adventure_images} + initialIndex={modalInitialIndex} + on:close={closeImageModal} /> {/if} @@ -61,14 +71,46 @@ (image_url = adventure_images[currentSlide].image)} - class="cursor-pointer" + on:click|stopPropagation={() => openImageModal(currentSlide)} + class="cursor-pointer relative group" > {adventure_images[currentSlide].adventure.name} + + + + + + {#if adventure_images.length > 1} @@ -76,8 +118,18 @@ {#if currentSlide > 0} + + + + {:else}
{/if} @@ -85,17 +137,43 @@ {#if currentSlide < adventure_images.length - 1} + + + + {:else}
{/if}