diff --git a/.env.testing.example b/.env.testing.example index ea0c4db7..0d0a03df 100644 --- a/.env.testing.example +++ b/.env.testing.example @@ -8,12 +8,12 @@ LOG_CHANNEL=stack LOG_DEPRECATIONS_CHANNEL=null LOG_LEVEL=debug -DB_CONNECTION=testing -DB_HOST=mysql -DB_PORT=3306 -DB_DATABASE=dev_he4rtbot -DB_USERNAME=root -DB_PASSWORD=root +DB_CONNECTION=pgsql +DB_HOST=127.0.0.1 +DB_PORT=5432 +DB_DATABASE=test_he4rtbot +DB_USERNAME=postgres +DB_PASSWORD=postgres BROADCAST_DRIVER=log CACHE_DRIVER=file diff --git a/.github/workflows/_pest.yml b/.github/workflows/_pest.yml index 14e09ff3..0c1b2675 100644 --- a/.github/workflows/_pest.yml +++ b/.github/workflows/_pest.yml @@ -27,6 +27,22 @@ jobs: concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}-tests cancel-in-progress: true + + services: + postgres: + image: postgres:18-alpine + env: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_DB: test_he4rtbot + ports: + - 5432/tcp + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + steps: - name: Checkout code uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -70,5 +86,6 @@ jobs: - name: Run Tests env: XDEBUG_MODE: coverage + DB_PORT: ${{ job.services.postgres.ports['5432'] }} run: | vendor/bin/pest --ci --parallel diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index 0093a212..4e280991 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -31,7 +31,7 @@ jobs: id: setup run: | echo "PHP_VERSION=8.4" >> "$GITHUB_OUTPUT" - echo "PHP_EXTENSIONS=mbstring,pdo,xml,ctype,fileinfo,json,curl,openssl,dom,zip" >> "$GITHUB_OUTPUT" + echo "PHP_EXTENSIONS=mbstring,pdo,pdo_pgsql,xml,ctype,fileinfo,json,curl,openssl,dom,zip" >> "$GITHUB_OUTPUT" echo "PHP_INI_PROPERTIES=post_max_size=256M,upload_max_filesize=256M" >> "$GITHUB_OUTPUT" echo "COMPOSER_FLAGS=--prefer-dist --optimize-autoloader" >> "$GITHUB_OUTPUT" diff --git a/Makefile b/Makefile index e26a8860..8b1c6ed4 100644 --- a/Makefile +++ b/Makefile @@ -50,18 +50,22 @@ check: test-rector test-pint test-phpstan ## Run Pint, PHPStan with Rector in dr .PHONY: test test: ## Run all tests - @$(CURDIR)/vendor/bin/pest --parallel --compact + @$(CURDIR)/vendor/bin/pest --compact .PHONY: t t: test ## Alias for test .PHONY: test-unit test-unit: ## Run unit tests - @$(CURDIR)/vendor/bin/pest --parallel --compact --group=unit + @$(CURDIR)/vendor/bin/pest --compact --group=unit .PHONY: test-feature test-feature: ## Run feature tests - @$(CURDIR)/vendor/bin/pest --parallel --compact --group=feature + @$(CURDIR)/vendor/bin/pest --compact --group=feature + +.PHONY: setup-test-db +setup-test-db: ## Create the testing database for running tests + @PGHOST=localhost PGUSER=postgres PGPASSWORD=postgres createdb test_he4rtbot 2>/dev/null || echo "Database test_he4rtbot already exists" .PHONY: migrate-fresh migrate-fresh: ## Run migrations and seed the database @@ -89,6 +93,10 @@ setup: ## Setup the project @php artisan storage:link --ansi @composer run-script ide-helper +.PHONY: import-db +import-db: ## Import a PostgreSQL dump file (usage: make import-db file=path/to/dump) + @PGHOST=localhost PGUSER=postgres PGPASSWORD=postgres pg_restore -x -O -cC -j 8 -d postgres $(file) + .PHONY: bot bot: ## Run the Discord bot @php artisan bot:boot diff --git a/README.md b/README.md index c63ac097..c61b3c07 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# He4rtBot Discord API +# he4rtdevs.com

diff --git a/app-modules/activity/src/Actions/NewMessage.php b/app-modules/activity/src/Actions/NewMessage.php index f59dbc12..ee368ea7 100644 --- a/app-modules/activity/src/Actions/NewMessage.php +++ b/app-modules/activity/src/Actions/NewMessage.php @@ -25,7 +25,7 @@ public function persist(NewMessageDTO $messageDTO): void 'tenant_id' => $messageDTO->tenantId, 'provider' => $messageDTO->provider, 'external_account_id' => $messageDTO->externalAccountId, - 'model_type' => User::class, + 'model_type' => (new User)->getMorphClass(), 'username' => $messageDTO->providerUsername, ]); diff --git a/app-modules/bot-discord/src/Events/MessageReceivedEvent.php b/app-modules/bot-discord/src/Events/MessageReceivedEvent.php index 495a95e7..40f3d9bd 100644 --- a/app-modules/bot-discord/src/Events/MessageReceivedEvent.php +++ b/app-modules/bot-discord/src/Events/MessageReceivedEvent.php @@ -32,7 +32,7 @@ public function handle(Message $message, Discord $discord): void try { $tenantProvider = ExternalIdentity::query() - ->where('model_type', Tenant::class) + ->where('model_type', (new Tenant)->getMorphClass()) ->where('external_account_id', (string) $message->guild_id) ->firstOrFail(); diff --git a/app-modules/bot-discord/src/Events/WelcomeMember.php b/app-modules/bot-discord/src/Events/WelcomeMember.php index d1f57cbb..bfaeefbf 100644 --- a/app-modules/bot-discord/src/Events/WelcomeMember.php +++ b/app-modules/bot-discord/src/Events/WelcomeMember.php @@ -25,7 +25,7 @@ public function handle(Member $member, Discord $discord): void $channelId = config('bot-discord.channels.auto-report'); $tenantProvider = ExternalIdentity::query() - ->where('model_type', Tenant::class) + ->where('model_type', (new Tenant)->getMorphClass()) ->where('external_account_id', (string) $member->guild_id) ->firstOrFail(); @@ -34,7 +34,7 @@ public function handle(Member $member, Discord $discord): void 'tenant_id' => $tenantProvider->tenant_id, 'provider' => $tenantProvider->provider, 'external_account_id' => $member->user->id, - 'model_type' => User::class, + 'model_type' => (new User)->getMorphClass(), 'username' => $member->user->username, 'avatar' => $member->user->avatar, ]); diff --git a/app-modules/bot-discord/src/SlashCommands/AbstractSlashCommand.php b/app-modules/bot-discord/src/SlashCommands/AbstractSlashCommand.php index 7b84a9ba..b76f8f1c 100644 --- a/app-modules/bot-discord/src/SlashCommands/AbstractSlashCommand.php +++ b/app-modules/bot-discord/src/SlashCommands/AbstractSlashCommand.php @@ -42,21 +42,21 @@ protected function getMemberProviderQuery(): Builder { return ExternalIdentity::query() ->where('tenant_id', $this->tenantProvider->tenant_id) - ->where('model_type', User::class) + ->where('model_type', (new User)->getMorphClass()) ->where('provider', IdentityProvider::Discord); } private function beforePipeline(Interaction $interaction): void { $this->tenantProvider = ExternalIdentity::query() - ->where('model_type', Tenant::class) + ->where('model_type', (new Tenant)->getMorphClass()) ->where('provider', IdentityProvider::Discord) ->where('external_account_id', $interaction->guild_id) ->first(); $this->memberProvider = ExternalIdentity::query() ->where('tenant_id', $this->tenantProvider->tenant_id) - ->where('model_type', User::class) + ->where('model_type', (new User)->getMorphClass()) ->where('provider', IdentityProvider::Discord) ->where('external_account_id', $interaction->user->id) ->first(); diff --git a/app-modules/bot-discord/src/SlashCommands/IntroductionCommand.php b/app-modules/bot-discord/src/SlashCommands/IntroductionCommand.php index 164af2d7..b006c9c0 100644 --- a/app-modules/bot-discord/src/SlashCommands/IntroductionCommand.php +++ b/app-modules/bot-discord/src/SlashCommands/IntroductionCommand.php @@ -115,7 +115,7 @@ public function handle(Interaction $interaction): void private function persistData(Interaction $interaction, Collection $components): void { $tenantProvider = ExternalIdentity::query() - ->where('model_type', Tenant::class) + ->where('model_type', (new Tenant)->getMorphClass()) ->where('external_account_id', (string) $interaction->guild_id) ->firstOrFail(); @@ -123,7 +123,7 @@ private function persistData(Interaction $interaction, Collection $components): 'tenant_id' => $tenantProvider->tenant_id, 'provider' => $tenantProvider->provider, 'external_account_id' => $interaction->user->id, - 'model_type' => User::class, + 'model_type' => (new User)->getMorphClass(), 'username' => $interaction->user->username, 'avatar' => $interaction->user->avatar, ]); diff --git a/app-modules/economy/database/factories/WalletFactory.php b/app-modules/economy/database/factories/WalletFactory.php index c9553e29..83f4b57b 100644 --- a/app-modules/economy/database/factories/WalletFactory.php +++ b/app-modules/economy/database/factories/WalletFactory.php @@ -17,7 +17,7 @@ final class WalletFactory extends Factory public function definition(): array { return [ - 'owner_type' => Character::class, + 'owner_type' => (new Character)->getMorphClass(), 'owner_id' => Character::factory(), 'currency' => Currency::Coin, 'balance' => 0, diff --git a/app-modules/economy/tests/Feature/EconomyFlowTest.php b/app-modules/economy/tests/Feature/EconomyFlowTest.php index 94fe4ee3..7655f6fc 100644 --- a/app-modules/economy/tests/Feature/EconomyFlowTest.php +++ b/app-modules/economy/tests/Feature/EconomyFlowTest.php @@ -17,7 +17,7 @@ expect($wallet->balance)->toBe(0) ->and($wallet->currency)->toBe(Currency::Coin) - ->and($wallet->owner_type)->toBe(Character::class) + ->and($wallet->owner_type)->toBe('character') ->and($wallet->owner_id)->toBe($character->id); resolve(Credit::class)->handle(new CreditDTO( diff --git a/app-modules/events/database/factories/EventAgendaFactory.php b/app-modules/events/database/factories/EventAgendaFactory.php index 135465f0..07024910 100644 --- a/app-modules/events/database/factories/EventAgendaFactory.php +++ b/app-modules/events/database/factories/EventAgendaFactory.php @@ -34,7 +34,7 @@ public function definition(): array public function forSegment(?EventSegment $segment = null) { return $this->state(fn () => [ - 'schedulable_type' => EventSegment::class, + 'schedulable_type' => (new EventSegment)->getMorphClass(), 'schedulable_id' => $segment ?? EventSegment::query()->inRandomOrder()->first()->getKey(), ]); } @@ -42,7 +42,7 @@ public function forSegment(?EventSegment $segment = null) public function forTalk(?EventSubmission $talk = null) { return $this->state(fn () => [ - 'schedulable_type' => EventSubmission::class, + 'schedulable_type' => (new EventSubmission)->getMorphClass(), 'schedulable_id' => $talk ?? EventSubmission::factory(), ]); } diff --git a/app-modules/events/src/Enums/SchedulableTypeEnum.php b/app-modules/events/src/Enums/SchedulableTypeEnum.php index df1ded67..19aaf1bb 100644 --- a/app-modules/events/src/Enums/SchedulableTypeEnum.php +++ b/app-modules/events/src/Enums/SchedulableTypeEnum.php @@ -7,14 +7,12 @@ use BackedEnum; use Filament\Support\Contracts\HasIcon; use Filament\Support\Icons\Heroicon; -use He4rt\Events\Models\EventSegment; -use He4rt\Events\Models\EventSubmission; enum SchedulableTypeEnum: string implements HasIcon { - case Submission = EventSubmission::class; + case Submission = 'event_submission'; - case Segment = EventSegment::class; + case Segment = 'event_segment'; public function getIcon(): BackedEnum { diff --git a/app-modules/events/src/Models/Sponsor.php b/app-modules/events/src/Models/Sponsor.php index 9130aae8..b91ecb5a 100644 --- a/app-modules/events/src/Models/Sponsor.php +++ b/app-modules/events/src/Models/Sponsor.php @@ -29,6 +29,8 @@ class Sponsor extends Model implements HasMedia protected $table = 'sponsors'; + protected $keyType = 'string'; + protected $fillable = [ 'name', 'logo_path', diff --git a/app-modules/events/src/Providers/EventsServiceProvider.php b/app-modules/events/src/Providers/EventsServiceProvider.php index 418b8d34..46279d25 100644 --- a/app-modules/events/src/Providers/EventsServiceProvider.php +++ b/app-modules/events/src/Providers/EventsServiceProvider.php @@ -9,6 +9,10 @@ use He4rt\Events\AdminEventPanelPlugin; use He4rt\Events\AppEventPanelPlugin; use He4rt\Events\EventPanelPlugin; +use He4rt\Events\Models\EventSegment; +use He4rt\Events\Models\EventSubmission; +use He4rt\Events\Models\Sponsor; +use Illuminate\Database\Eloquent\Relations\Relation; use Illuminate\Support\ServiceProvider; class EventsServiceProvider extends ServiceProvider @@ -29,5 +33,11 @@ public function boot(): void { $this->loadMigrationsFrom(__DIR__.'/../../database/migrations'); $this->loadViewsFrom(__DIR__.'/../../resources/views', 'events'); + + Relation::morphMap([ + 'event_submission' => EventSubmission::class, + 'event_segment' => EventSegment::class, + 'sponsor' => Sponsor::class, + ]); } } diff --git a/app-modules/events/tests/Feature/Filament/Admin/Event/CreateEventTest.php b/app-modules/events/tests/Feature/Filament/Admin/Event/CreateEventTest.php index f3e9a83f..5d6b942b 100644 --- a/app-modules/events/tests/Feature/Filament/Admin/Event/CreateEventTest.php +++ b/app-modules/events/tests/Feature/Filament/Admin/Event/CreateEventTest.php @@ -7,6 +7,7 @@ use He4rt\Events\Enums\EventTypeEnum; use He4rt\Events\Filament\Admin\Resources\Events\Pages\CreateEvent; use He4rt\Events\Models\EventModel; +use He4rt\Identity\Tenant\Models\Tenant; use Illuminate\Support\Facades\Date; use function Pest\Laravel\assertDatabaseCount; @@ -16,6 +17,7 @@ beforeEach(function (): void { Filament::setCurrentPanel(FilamentPanel::Admin->value); $this->actingAsAdmin(); + $this->tenant = Tenant::query()->first(); }); it('should render', function (): void { @@ -27,7 +29,7 @@ livewire(CreateEvent::class) ->assertOk() ->fillForm([ - 'tenant_id' => 1, + 'tenant_id' => $this->tenant->getKey(), 'title' => 'event title', 'slug' => 'event-slug', 'description' => 'event description', @@ -44,7 +46,7 @@ assertDatabaseCount(EventModel::class, 1); assertDatabaseHas(EventModel::class, [ - 'tenant_id' => 1, + 'tenant_id' => $this->tenant->getKey(), 'title' => 'event title', 'slug' => 'event-slug', 'location' => 'event location', diff --git a/app-modules/events/tests/Feature/Filament/Admin/Sponsors/CreateSponsorTest.php b/app-modules/events/tests/Feature/Filament/Admin/Sponsors/CreateSponsorTest.php index 3225697e..4bb0f05e 100644 --- a/app-modules/events/tests/Feature/Filament/Admin/Sponsors/CreateSponsorTest.php +++ b/app-modules/events/tests/Feature/Filament/Admin/Sponsors/CreateSponsorTest.php @@ -6,6 +6,7 @@ use Filament\Facades\Filament; use He4rt\Events\Filament\Resources\Sponsors\Pages\CreateSponsor; use He4rt\Events\Models\Sponsor; +use He4rt\Identity\Tenant\Models\Tenant; use Illuminate\Http\UploadedFile; use Illuminate\Support\Facades\Storage; @@ -27,10 +28,12 @@ Filament::setCurrentPanel(FilamentPanel::Admin->value); $this->actingAsAdmin(); + $tenant = Tenant::query()->first(); + livewire(CreateSponsor::class) ->assertOk() ->fillForm([ - 'tenant_id' => 1, + 'tenant_id' => $tenant->getKey(), 'name' => 'sponsor name', 'receipt' => $image, 'homepage_url' => 'https://www.google.com', @@ -41,7 +44,7 @@ assertDatabaseCount(Sponsor::class, 1); assertDatabaseHas(Sponsor::class, [ - 'tenant_id' => 1, + 'tenant_id' => $tenant->getKey(), 'name' => 'sponsor name', 'homepage_url' => 'https://www.google.com', ]); diff --git a/app-modules/events/tests/Feature/Filament/App/Events/ListEventsTest.php b/app-modules/events/tests/Feature/Filament/App/Events/ListEventsTest.php index b28c4b07..b81d7905 100644 --- a/app-modules/events/tests/Feature/Filament/App/Events/ListEventsTest.php +++ b/app-modules/events/tests/Feature/Filament/App/Events/ListEventsTest.php @@ -57,14 +57,15 @@ it('should see Register or Join Waitlist based on status', function ($status, $text, $dontSeeText): void { $this->events->each(function (EventModel $event) use ($status): void { - $attendeeIds = $event->attendees->pluck('id'); - $event->attendees()->updateExistingPivot( - $attendeeIds, - ['status' => $status] - ); + foreach ($event->attendees as $attendee) { + $event->attendees()->updateExistingPivot( + $attendee->getKey(), + ['status' => $status] + ); + } }); - $this->events->fresh(); + $this->events = $this->events->fresh(); livewire(ListEventModels::class, ['tenant' => $this->tenant->slug]) ->assertOk() ->assertSeeText($text) @@ -76,12 +77,14 @@ it('should be able to participate to an event', function (): void { $event = $this->events->first(); - $attendeeIds = $event->attendees->pluck('id'); - $event->attendees()->updateExistingPivot( - $attendeeIds, - ['status' => AttendingStatusEnum::Waitlist], - ); + foreach ($event->attendees as $attendee) { + $event->attendees()->updateExistingPivot( + $attendee->getKey(), + ['status' => AttendingStatusEnum::Waitlist], + ); + } + livewire(ListEventModels::class, ['tenant' => $this->tenant->slug]) ->assertOk() ->call('attend', $event->getKey()) @@ -92,17 +95,18 @@ ); expect($event->attendees()->count())->toBe(5) - ->and($event->attendees()->get()->last()->getKey())->toBe(auth()->user()->getKey()); + ->and($event->isParticipating(auth()->user()->getKey()))->toBeTrue(); }); it('should go to waitlist', function (): void { $event = $this->events->first(); - $attendeeIds = $event->attendees->pluck('id'); - $event->attendees()->updateExistingPivot( - $attendeeIds, - ['status' => AttendingStatusEnum::Waitlist], - ); + foreach ($event->attendees as $attendee) { + $event->attendees()->updateExistingPivot( + $attendee->getKey(), + ['status' => AttendingStatusEnum::Waitlist], + ); + } livewire(ListEventModels::class, ['tenant' => $this->tenant->slug]) ->assertOk() diff --git a/app-modules/gamification/src/Badge/Models/Badge.php b/app-modules/gamification/src/Badge/Models/Badge.php index 4a477591..389031be 100644 --- a/app-modules/gamification/src/Badge/Models/Badge.php +++ b/app-modules/gamification/src/Badge/Models/Badge.php @@ -20,6 +20,8 @@ final class Badge extends Model implements HasMedia protected $table = 'badges'; + protected $keyType = 'string'; + protected $fillable = [ 'provider', 'name', diff --git a/app-modules/gamification/src/Character/Actions/PersistClaimedBadge.php b/app-modules/gamification/src/Character/Actions/PersistClaimedBadge.php index 84420ce7..31855654 100644 --- a/app-modules/gamification/src/Character/Actions/PersistClaimedBadge.php +++ b/app-modules/gamification/src/Character/Actions/PersistClaimedBadge.php @@ -8,7 +8,7 @@ final readonly class PersistClaimedBadge { - public function handle(string $characterId, int $badgeId): void + public function handle(string $characterId, int|string $badgeId): void { $character = Character::query()->findOrFail($characterId); $character->badges() diff --git a/app-modules/gamification/src/Providers/GamificationServiceProvider.php b/app-modules/gamification/src/Providers/GamificationServiceProvider.php index 23cb8cbf..3e9a4ad6 100644 --- a/app-modules/gamification/src/Providers/GamificationServiceProvider.php +++ b/app-modules/gamification/src/Providers/GamificationServiceProvider.php @@ -7,8 +7,11 @@ use App\Enums\FilamentPanel; use Filament\Panel; use He4rt\Gamification\Badge\Filament\Resources\Badges\BadgeResource; +use He4rt\Gamification\Badge\Models\Badge; +use He4rt\Gamification\Character\Models\Character; use He4rt\Gamification\Season\Filament\Admin\Resources\Seasons\SeasonResource; use He4rt\Gamification\Season\Filament\Shared\Widgets\SeasonStatsOverview; +use Illuminate\Database\Eloquent\Relations\Relation; use Illuminate\Support\ServiceProvider; class GamificationServiceProvider extends ServiceProvider @@ -33,5 +36,10 @@ public function register(): void public function boot(): void { $this->loadMigrationsFrom(__DIR__.'/../../database/migrations'); + + Relation::morphMap([ + 'character' => Character::class, + 'badge' => Badge::class, + ]); } } diff --git a/app-modules/identity/database/factories/ExternalIdentityFactory.php b/app-modules/identity/database/factories/ExternalIdentityFactory.php index 580622c1..77c81474 100644 --- a/app-modules/identity/database/factories/ExternalIdentityFactory.php +++ b/app-modules/identity/database/factories/ExternalIdentityFactory.php @@ -26,7 +26,7 @@ public function definition(): array return [ 'id' => fake()->uuid(), 'tenant_id' => Tenant::factory(), - 'model_type' => User::class, + 'model_type' => (new User)->getMorphClass(), 'model_id' => User::factory(), 'type' => IdentityType::External, 'provider' => fake()->randomElement(IdentityProvider::cases()), @@ -49,7 +49,7 @@ public function definition(): array public function morphFor(?string $model = User::class): static { return $this->state(fn () => [ - 'model_type' => $model, + 'model_type' => (new $model)->getMorphClass(), 'model_id' => $model::factory(), ]); } diff --git a/app-modules/identity/database/factories/UserFactory.php b/app-modules/identity/database/factories/UserFactory.php index 09104451..41d491ae 100644 --- a/app-modules/identity/database/factories/UserFactory.php +++ b/app-modules/identity/database/factories/UserFactory.php @@ -19,7 +19,7 @@ public function definition(): array { return [ 'id' => fake()->uuid(), - 'username' => fake()->userName(), + 'username' => fake()->unique()->userName(), 'name' => fake()->name(), 'email' => fake()->email(), 'password' => Hash::make('password'), diff --git a/app-modules/identity/database/migrations/2025_11_02_171945_add_polymorphic_fields_to_providers_table.php b/app-modules/identity/database/migrations/2025_11_02_171945_add_polymorphic_fields_to_providers_table.php index 755f6afd..959ee5d8 100644 --- a/app-modules/identity/database/migrations/2025_11_02_171945_add_polymorphic_fields_to_providers_table.php +++ b/app-modules/identity/database/migrations/2025_11_02_171945_add_polymorphic_fields_to_providers_table.php @@ -2,7 +2,6 @@ declare(strict_types=1); -use He4rt\Identity\User\Models\User; use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; @@ -16,7 +15,7 @@ public function up(): void { Schema::table('providers', function (Blueprint $table): void { $table->string('model_type')->after('id') - ->default(User::class) + ->default('user') ->nullable(); $table->renameColumn('user_id', 'model_id'); diff --git a/app-modules/identity/database/migrations/2026_03_21_000002_fix_user_address_column_lengths.php b/app-modules/identity/database/migrations/2026_03_21_000002_fix_user_address_column_lengths.php new file mode 100644 index 00000000..47b65401 --- /dev/null +++ b/app-modules/identity/database/migrations/2026_03_21_000002_fix_user_address_column_lengths.php @@ -0,0 +1,26 @@ +string('country')->nullable()->change(); + $table->string('state')->nullable()->change(); + }); + } + + public function down(): void + { + Schema::table('user_address', function (Blueprint $table): void { + $table->string('country', 4)->nullable()->change(); + $table->string('state', 4)->nullable()->change(); + }); + } +}; diff --git a/app-modules/identity/src/ExternalIdentity/Actions/CreateAccountByExternalIdentity.php b/app-modules/identity/src/ExternalIdentity/Actions/CreateAccountByExternalIdentity.php index 2ff3596e..55abae84 100644 --- a/app-modules/identity/src/ExternalIdentity/Actions/CreateAccountByExternalIdentity.php +++ b/app-modules/identity/src/ExternalIdentity/Actions/CreateAccountByExternalIdentity.php @@ -39,7 +39,7 @@ public function handle(int $tenantId, IdentityProvider $provider, string $provid return ExternalIdentity::query()->create([ 'tenant_id' => $tenantId, - 'model_type' => User::class, + 'model_type' => (new User)->getMorphClass(), 'model_id' => $user->id, 'type' => $provider->getType(), 'provider' => $provider->value, diff --git a/app-modules/identity/src/Providers/IdentityServiceProvider.php b/app-modules/identity/src/Providers/IdentityServiceProvider.php index 50fc4783..77c8c6a8 100644 --- a/app-modules/identity/src/Providers/IdentityServiceProvider.php +++ b/app-modules/identity/src/Providers/IdentityServiceProvider.php @@ -11,6 +11,9 @@ use He4rt\Identity\Filament\Shared\Widgets\UsersStatsOverview; use He4rt\Identity\Filament\User\Pages\Dashboard; use He4rt\Identity\Filament\User\Pages\UserProfile; +use He4rt\Identity\Tenant\Models\Tenant; +use He4rt\Identity\User\Models\User; +use Illuminate\Database\Eloquent\Relations\Relation; use Illuminate\Support\ServiceProvider; class IdentityServiceProvider extends ServiceProvider @@ -41,5 +44,10 @@ public function boot(): void { $this->loadMigrationsFrom(__DIR__.'/../../database/migrations'); $this->loadViewsFrom(__DIR__.'/../../resources/views', 'identity'); + + Relation::morphMap([ + 'user' => User::class, + 'tenant' => Tenant::class, + ]); } } diff --git a/app-modules/identity/src/User/Actions/UpdateProfile.php b/app-modules/identity/src/User/Actions/UpdateProfile.php index cceaddd6..70f2e339 100644 --- a/app-modules/identity/src/User/Actions/UpdateProfile.php +++ b/app-modules/identity/src/User/Actions/UpdateProfile.php @@ -23,7 +23,7 @@ public function handle(UpdateProfileDTO $profileDTO): void 'external_account_id' => $profileDTO->externalAccountId, 'provider' => $profileDTO->provider, 'tenant_id' => $profileDTO->tenantId, - 'model_type' => User::class, + 'model_type' => (new User)->getMorphClass(), ]); $provider = $this->providerResolver->handle($providerDto); diff --git a/app-modules/identity/tests/Feature/Auth/AuthenticateActionTest.php b/app-modules/identity/tests/Feature/Auth/AuthenticateActionTest.php index 7f094f58..0bf0087c 100644 --- a/app-modules/identity/tests/Feature/Auth/AuthenticateActionTest.php +++ b/app-modules/identity/tests/Feature/Auth/AuthenticateActionTest.php @@ -89,7 +89,7 @@ function setDiscordConfig(): void $existingUser = User::factory()->create(); $existingProvider = ExternalIdentity::factory()->create([ 'tenant_id' => $tenant->getKey(), - 'model_type' => User::class, + 'model_type' => (new User)->getMorphClass(), 'model_id' => $existingUser->getKey(), 'provider' => 'discord', 'external_account_id' => '777777', diff --git a/app-modules/identity/tests/Feature/FindProfileTest.php b/app-modules/identity/tests/Feature/FindProfileTest.php index fcd1ffe1..00ae4a2e 100644 --- a/app-modules/identity/tests/Feature/FindProfileTest.php +++ b/app-modules/identity/tests/Feature/FindProfileTest.php @@ -7,6 +7,7 @@ use He4rt\Gamification\Character\Models\Character; use He4rt\Gamification\Character\Models\PastSeason; use He4rt\Identity\ExternalIdentity\Models\ExternalIdentity; +use He4rt\Identity\Tenant\Models\Tenant; use He4rt\Identity\User\Models\Address; use He4rt\Identity\User\Models\Information; use He4rt\Identity\User\Models\User; @@ -63,7 +64,8 @@ $badge = Badge::factory()->create(); $character = $user->character; - $character->badges()->attach($badge->id, ['claimed_at' => now(), 'tenant_id' => 1]); + $tenant = Tenant::factory()->create(); + $character->badges()->attach($badge->id, ['claimed_at' => now(), 'tenant_id' => $tenant->getKey()]); $this ->actingAsAdmin() diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 260f5b30..4421ebbe 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -9,6 +9,7 @@ use App\Providers\Tools\TelescopeServiceProvider; use App\Support\Paginator; use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\Relations\Relation; use Illuminate\Support\Facades\URL; use Illuminate\Support\Facades\Vite; use Illuminate\Support\ServiceProvider; @@ -43,6 +44,7 @@ public function boot(): void private function configureDatabase(): void { Model::automaticallyEagerLoadRelationships(); + Relation::requireMorphMap(); } /** diff --git a/composer.json b/composer.json index 3bbe0ae8..3e28b4ec 100644 --- a/composer.json +++ b/composer.json @@ -12,8 +12,8 @@ "ext-pdo": "*", "calebporzio/sushi": "^2.5.4", "dedoc/scramble": "^0.13.16", - "filament/filament": "^5.4.0", - "filament/spatie-laravel-media-library-plugin": "^5.4.0", + "filament/filament": "^5.4.1", + "filament/spatie-laravel-media-library-plugin": "^5.4.1", "guzzlehttp/guzzle": "^7.10.0", "he4rt/activity": ">=1", "he4rt/bot-discord": ">=1", @@ -29,17 +29,17 @@ "he4rt/portal": ">=1", "internachi/modular": "dev-main#ad95fe9", "laracord/framework": "dev-next", - "laravel/framework": "^12.55.0", - "laravel/nightwatch": "^1.24.3", + "laravel/framework": "^12.55.1", + "laravel/nightwatch": "^1.24.4", "laravel/sanctum": "^4.3.1", "laravel/telescope": "^5.18.0", "laravel/tinker": "^2.11.1", "livewire/flux": "^2.13.0", "marvinlabs/laravel-discord-logger": "^1.4.3", "monicahq/laravel-cloudflare": "^4.0", - "owenvoke/blade-fontawesome": "^3.2", + "owenvoke/blade-fontawesome": "^3.2.2", "predis/predis": "^3.4.2", - "ryangjchandler/commonmark-blade-block": "^1.1", + "ryangjchandler/commonmark-blade-block": "^1.1.1", "spatie/laravel-medialibrary": "^11.21.0", "symfony/browser-kit": "v7.0.8", "torchlight/torchlight-commonmark": "^0.6.0", @@ -48,7 +48,7 @@ "require-dev": { "fruitcake/laravel-debugbar": "^4.1.3", "barryvdh/laravel-ide-helper": "^3.7.0", - "driftingly/rector-laravel": "^2.1.12", + "driftingly/rector-laravel": "^2.2.0", "fakerphp/faker": "^1.24.1", "larastan/larastan": "^3.9.3", "laravel/boost": "^2.3.4", @@ -57,7 +57,7 @@ "laravel/sail": "^1.54.0", "mockery/mockery": "^1.6.12", "nunomaduro/collision": "^8.9.1", - "pestphp/pest": "^4.4.2", + "pestphp/pest": "^4.4.3", "pestphp/pest-plugin-drift": "^4.1.0", "pestphp/pest-plugin-faker": "^4.0.0", "pestphp/pest-plugin-laravel": "^4.1.0", @@ -122,9 +122,9 @@ "test:rector": "vendor/bin/rector --dry-run", "phpstan": "vendor/bin/phpstan analyse --ansi", "test:phpstan": "vendor/bin/phpstan analyse --ansi", - "test:unit": "vendor/bin/pest --parallel --compact --group=unit", - "test:feature": "vendor/bin/pest --parallel --compact --group=feature", - "test:cov": "vendor/bin/pest --parallel --compact --coverage", + "test:unit": "vendor/bin/pest --compact --group=unit", + "test:feature": "vendor/bin/pest --compact --group=feature", + "test:cov": "vendor/bin/pest --compact --coverage", "check": [ "@test:rector", "@test:pint", @@ -132,7 +132,7 @@ ], "test": [ "@php artisan config:clear --ansi", - "vendor/bin/pest --parallel --compact" + "vendor/bin/pest --compact" ] }, "extra": { diff --git a/composer.lock b/composer.lock index d9217728..20ffce7f 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "936b4cc314a0d419109f258378ab4155", + "content-hash": "f3be323ab4f835734901b5f89dc34c61", "packages": [ { "name": "blade-ui-kit/blade-heroicons", @@ -434,16 +434,16 @@ }, { "name": "chillerlan/php-settings-container", - "version": "3.2.1", + "version": "3.3.0", "source": { "type": "git", "url": "https://github.com/chillerlan/php-settings-container.git", - "reference": "95ed3e9676a1d47cab2e3174d19b43f5dbf52681" + "reference": "a0a487cbf5344f721eb504bf0f59bada40c381b7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/chillerlan/php-settings-container/zipball/95ed3e9676a1d47cab2e3174d19b43f5dbf52681", - "reference": "95ed3e9676a1d47cab2e3174d19b43f5dbf52681", + "url": "https://api.github.com/repos/chillerlan/php-settings-container/zipball/a0a487cbf5344f721eb504bf0f59bada40c381b7", + "reference": "a0a487cbf5344f721eb504bf0f59bada40c381b7", "shasum": "" }, "require": { @@ -451,11 +451,13 @@ "php": "^8.1" }, "require-dev": { + "phan/phan": "^5.5.2", "phpmd/phpmd": "^2.15", - "phpstan/phpstan": "^1.11", - "phpstan/phpstan-deprecation-rules": "^1.2", + "phpstan/phpstan": "^2.1.31", + "phpstan/phpstan-deprecation-rules": "^2.0.3", "phpunit/phpunit": "^10.5", - "squizlabs/php_codesniffer": "^3.10" + "slevomat/coding-standard": "^8.22", + "squizlabs/php_codesniffer": "^4.0" }, "type": "library", "autoload": { @@ -480,7 +482,8 @@ "Settings", "configuration", "container", - "helper" + "helper", + "property hook" ], "support": { "issues": "https://github.com/chillerlan/php-settings-container/issues", @@ -496,7 +499,7 @@ "type": "ko_fi" } ], - "time": "2024-07-16T11:13:48+00:00" + "time": "2026-03-20T21:10:52+00:00" }, { "name": "composer/ca-bundle", @@ -2004,7 +2007,7 @@ }, { "name": "filament/actions", - "version": "v5.4.0", + "version": "v5.4.1", "source": { "type": "git", "url": "https://github.com/filamentphp/actions.git", @@ -2052,7 +2055,7 @@ }, { "name": "filament/filament", - "version": "v5.4.0", + "version": "v5.4.1", "source": { "type": "git", "url": "https://github.com/filamentphp/panels.git", @@ -2109,16 +2112,16 @@ }, { "name": "filament/forms", - "version": "v5.4.0", + "version": "v5.4.1", "source": { "type": "git", "url": "https://github.com/filamentphp/forms.git", - "reference": "dd6648637e4a7232c0c84e07157a65ea4024b84e" + "reference": "b20b76425cbdc72890ccda948d15e49affaa135f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filamentphp/forms/zipball/dd6648637e4a7232c0c84e07157a65ea4024b84e", - "reference": "dd6648637e4a7232c0c84e07157a65ea4024b84e", + "url": "https://api.github.com/repos/filamentphp/forms/zipball/b20b76425cbdc72890ccda948d15e49affaa135f", + "reference": "b20b76425cbdc72890ccda948d15e49affaa135f", "shasum": "" }, "require": { @@ -2155,11 +2158,11 @@ "issues": "https://github.com/filamentphp/filament/issues", "source": "https://github.com/filamentphp/filament" }, - "time": "2026-03-17T20:03:40+00:00" + "time": "2026-03-19T13:52:01+00:00" }, { "name": "filament/infolists", - "version": "v5.4.0", + "version": "v5.4.1", "source": { "type": "git", "url": "https://github.com/filamentphp/infolists.git", @@ -2204,7 +2207,7 @@ }, { "name": "filament/notifications", - "version": "v5.4.0", + "version": "v5.4.1", "source": { "type": "git", "url": "https://github.com/filamentphp/notifications.git", @@ -2251,16 +2254,16 @@ }, { "name": "filament/query-builder", - "version": "v5.4.0", + "version": "v5.4.1", "source": { "type": "git", "url": "https://github.com/filamentphp/query-builder.git", - "reference": "015381ecb38fc41f68ca60a9f7cb8f46987b9f9b" + "reference": "a56c1fa60040484ffce0be74a8e00ed7a30c1f0d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filamentphp/query-builder/zipball/015381ecb38fc41f68ca60a9f7cb8f46987b9f9b", - "reference": "015381ecb38fc41f68ca60a9f7cb8f46987b9f9b", + "url": "https://api.github.com/repos/filamentphp/query-builder/zipball/a56c1fa60040484ffce0be74a8e00ed7a30c1f0d", + "reference": "a56c1fa60040484ffce0be74a8e00ed7a30c1f0d", "shasum": "" }, "require": { @@ -2293,11 +2296,11 @@ "issues": "https://github.com/filamentphp/filament/issues", "source": "https://github.com/filamentphp/filament" }, - "time": "2026-03-14T07:55:43+00:00" + "time": "2026-03-19T13:47:21+00:00" }, { "name": "filament/schemas", - "version": "v5.4.0", + "version": "v5.4.1", "source": { "type": "git", "url": "https://github.com/filamentphp/schemas.git", @@ -2342,7 +2345,7 @@ }, { "name": "filament/spatie-laravel-media-library-plugin", - "version": "v5.4.0", + "version": "v5.4.1", "source": { "type": "git", "url": "https://github.com/filamentphp/spatie-laravel-media-library-plugin.git", @@ -2379,16 +2382,16 @@ }, { "name": "filament/support", - "version": "v5.4.0", + "version": "v5.4.1", "source": { "type": "git", "url": "https://github.com/filamentphp/support.git", - "reference": "03b8e1f498787a2ab76413e58814daed1051ddc3" + "reference": "2bc2afc80eaf71fd8248d7b3e71d010d2b14aa7e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filamentphp/support/zipball/03b8e1f498787a2ab76413e58814daed1051ddc3", - "reference": "03b8e1f498787a2ab76413e58814daed1051ddc3", + "url": "https://api.github.com/repos/filamentphp/support/zipball/2bc2afc80eaf71fd8248d7b3e71d010d2b14aa7e", + "reference": "2bc2afc80eaf71fd8248d7b3e71d010d2b14aa7e", "shasum": "" }, "require": { @@ -2432,20 +2435,20 @@ "issues": "https://github.com/filamentphp/filament/issues", "source": "https://github.com/filamentphp/filament" }, - "time": "2026-03-17T20:03:15+00:00" + "time": "2026-03-19T13:55:19+00:00" }, { "name": "filament/tables", - "version": "v5.4.0", + "version": "v5.4.1", "source": { "type": "git", "url": "https://github.com/filamentphp/tables.git", - "reference": "81cba776a14842aa7d513e7a7c267d013cd2e4ed" + "reference": "eb5324bbd3c92a1e56476894fa9e7098bf7bbe95" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filamentphp/tables/zipball/81cba776a14842aa7d513e7a7c267d013cd2e4ed", - "reference": "81cba776a14842aa7d513e7a7c267d013cd2e4ed", + "url": "https://api.github.com/repos/filamentphp/tables/zipball/eb5324bbd3c92a1e56476894fa9e7098bf7bbe95", + "reference": "eb5324bbd3c92a1e56476894fa9e7098bf7bbe95", "shasum": "" }, "require": { @@ -2478,11 +2481,11 @@ "issues": "https://github.com/filamentphp/filament/issues", "source": "https://github.com/filamentphp/filament" }, - "time": "2026-03-17T20:06:54+00:00" + "time": "2026-03-19T13:48:36+00:00" }, { "name": "filament/widgets", - "version": "v5.4.0", + "version": "v5.4.1", "source": { "type": "git", "url": "https://github.com/filamentphp/widgets.git", @@ -3812,16 +3815,16 @@ }, { "name": "laravel/framework", - "version": "v12.55.0", + "version": "v12.55.1", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "6917962a55ac91598e8c5e2ebd25e27aed121b5e" + "reference": "6d9185a248d101b07eecaf8fd60b18129545fd33" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/6917962a55ac91598e8c5e2ebd25e27aed121b5e", - "reference": "6917962a55ac91598e8c5e2ebd25e27aed121b5e", + "url": "https://api.github.com/repos/laravel/framework/zipball/6d9185a248d101b07eecaf8fd60b18129545fd33", + "reference": "6d9185a248d101b07eecaf8fd60b18129545fd33", "shasum": "" }, "require": { @@ -4030,20 +4033,20 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2026-03-17T14:19:00+00:00" + "time": "2026-03-18T14:28:59+00:00" }, { "name": "laravel/nightwatch", - "version": "v1.24.3", + "version": "v1.24.4", "source": { "type": "git", "url": "https://github.com/laravel/nightwatch.git", - "reference": "627e58096f6b4b88e658b7a9cff595089036ae84" + "reference": "127e9bb9928f0fcf69b52b244053b393c90347c8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/nightwatch/zipball/627e58096f6b4b88e658b7a9cff595089036ae84", - "reference": "627e58096f6b4b88e658b7a9cff595089036ae84", + "url": "https://api.github.com/repos/laravel/nightwatch/zipball/127e9bb9928f0fcf69b52b244053b393c90347c8", + "reference": "127e9bb9928f0fcf69b52b244053b393c90347c8", "shasum": "" }, "require": { @@ -4056,8 +4059,8 @@ "psr/http-message": "^1.0|^2.0", "psr/log": "^1.0|^2.0|^3.0", "ramsey/uuid": "^4.0", - "symfony/console": "^6.0|^7.0", - "symfony/http-foundation": "^6.0|^7.0", + "symfony/console": "^6.0|^7.0|^8.0", + "symfony/http-foundation": "^6.0|^7.0|^8.0", "symfony/polyfill-php84": "^1.29" }, "require-dev": { @@ -4079,9 +4082,9 @@ "phpunit/phpunit": "^10.0|^11.0|^12.0", "singlestoredb/singlestoredb-laravel": "^1.0|^2.0", "spatie/laravel-ignition": "^2.0", - "symfony/mailer": "^6.0|^7.0", - "symfony/mime": "^6.0|^7.0", - "symfony/var-dumper": "^6.0|^7.0" + "symfony/mailer": "^6.0|^7.0|^8.0", + "symfony/mime": "^6.0|^7.0|^8.0", + "symfony/var-dumper": "^6.0|^7.0|^8.0" }, "type": "library", "extra": { @@ -4124,7 +4127,7 @@ "issues": "https://github.com/laravel/nightwatch/issues", "source": "https://github.com/laravel/nightwatch" }, - "time": "2026-03-12T04:01:23+00:00" + "time": "2026-03-18T23:25:05+00:00" }, { "name": "laravel/prompts", @@ -4505,16 +4508,16 @@ }, { "name": "league/commonmark", - "version": "2.8.1", + "version": "2.8.2", "source": { "type": "git", "url": "https://github.com/thephpleague/commonmark.git", - "reference": "84b1ca48347efdbe775426f108622a42735a6579" + "reference": "59fb075d2101740c337c7216e3f32b36c204218b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/84b1ca48347efdbe775426f108622a42735a6579", - "reference": "84b1ca48347efdbe775426f108622a42735a6579", + "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/59fb075d2101740c337c7216e3f32b36c204218b", + "reference": "59fb075d2101740c337c7216e3f32b36c204218b", "shasum": "" }, "require": { @@ -4608,7 +4611,7 @@ "type": "tidelift" } ], - "time": "2026-03-05T21:37:03+00:00" + "time": "2026-03-19T13:16:38+00:00" }, { "name": "league/config", @@ -6494,22 +6497,22 @@ }, { "name": "owenvoke/blade-fontawesome", - "version": "v3.2.0", + "version": "v3.2.2", "source": { "type": "git", "url": "https://github.com/owenvoke/blade-fontawesome.git", - "reference": "d75e6de9f689aaeab89d3208244f4abebadeeba4" + "reference": "5a199630dd70c5133d58c158a974e12bcd8b3a71" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/owenvoke/blade-fontawesome/zipball/d75e6de9f689aaeab89d3208244f4abebadeeba4", - "reference": "d75e6de9f689aaeab89d3208244f4abebadeeba4", + "url": "https://api.github.com/repos/owenvoke/blade-fontawesome/zipball/5a199630dd70c5133d58c158a974e12bcd8b3a71", + "reference": "5a199630dd70c5133d58c158a974e12bcd8b3a71", "shasum": "" }, "require": { "blade-ui-kit/blade-icons": "^1.8", "illuminate/support": "^12.0|^13.0", - "php": "^8.4" + "php": "^8.3" }, "require-dev": { "laravel/pint": "^1.25", @@ -6538,7 +6541,7 @@ "description": "A package to easily make use of Font Awesome in your Laravel Blade views", "support": { "issues": "https://github.com/owenvoke/blade-fontawesome/issues", - "source": "https://github.com/owenvoke/blade-fontawesome/tree/v3.2.0" + "source": "https://github.com/owenvoke/blade-fontawesome/tree/v3.2.2" }, "funding": [ { @@ -6550,7 +6553,7 @@ "type": "github" } ], - "time": "2026-02-23T09:42:08+00:00" + "time": "2026-03-20T08:37:22+00:00" }, { "name": "paragonie/constant_time_encoding", @@ -8644,20 +8647,20 @@ }, { "name": "ryangjchandler/commonmark-blade-block", - "version": "v1.1.0", + "version": "v1.1.1", "source": { "type": "git", "url": "https://github.com/ryangjchandler/commonmark-blade-block.git", - "reference": "00bc02e2f466efcf02fc9d05a8f9566352c1f5f5" + "reference": "b72a9bfb7c70862d162f8779cf94b3c792cee8e7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ryangjchandler/commonmark-blade-block/zipball/00bc02e2f466efcf02fc9d05a8f9566352c1f5f5", - "reference": "00bc02e2f466efcf02fc9d05a8f9566352c1f5f5", + "url": "https://api.github.com/repos/ryangjchandler/commonmark-blade-block/zipball/b72a9bfb7c70862d162f8779cf94b3c792cee8e7", + "reference": "b72a9bfb7c70862d162f8779cf94b3c792cee8e7", "shasum": "" }, "require": { - "illuminate/contracts": "^12.0", + "illuminate/contracts": "^12.0 | ^13.0", "league/commonmark": "^2.7", "php": "^8.2", "spatie/laravel-package-tools": "^1.92.4" @@ -8666,10 +8669,10 @@ "larastan/larastan": "^3.0", "laravel/pint": "^1.22.1", "nunomaduro/collision": "^8.0", - "orchestra/testbench": "^10.0.0", - "pestphp/pest": "^3.0", - "pestphp/pest-plugin-arch": "^3.0", - "pestphp/pest-plugin-laravel": "^3.0", + "orchestra/testbench": "^10.0.0 | ^11.0", + "pestphp/pest": "^4.0", + "pestphp/pest-plugin-arch": "^4.0", + "pestphp/pest-plugin-laravel": "^4.0", "phpstan/extension-installer": "^1.4.3", "phpstan/phpstan-deprecation-rules": "^2.0", "phpstan/phpstan-phpunit": "^2.0", @@ -8712,7 +8715,7 @@ ], "support": { "issues": "https://github.com/ryangjchandler/commonmark-blade-block/issues", - "source": "https://github.com/ryangjchandler/commonmark-blade-block/tree/v1.1.0" + "source": "https://github.com/ryangjchandler/commonmark-blade-block/tree/v1.1.1" }, "funding": [ { @@ -8720,7 +8723,7 @@ "type": "github" } ], - "time": "2025-05-09T18:29:02+00:00" + "time": "2026-03-19T10:05:33+00:00" }, { "name": "scrivo/highlight.php", @@ -12628,16 +12631,16 @@ }, { "name": "team-reflex/discord-php", - "version": "v10.46.2", + "version": "v10.46.3", "source": { "type": "git", "url": "https://github.com/discord-php/DiscordPHP.git", - "reference": "4ca30165e6e514e06555ca70a19a4dddc5c1829d" + "reference": "1eb311cabfb7c8a8c861579a48d2c235b765a1c2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/discord-php/DiscordPHP/zipball/4ca30165e6e514e06555ca70a19a4dddc5c1829d", - "reference": "4ca30165e6e514e06555ca70a19a4dddc5c1829d", + "url": "https://api.github.com/repos/discord-php/DiscordPHP/zipball/1eb311cabfb7c8a8c861579a48d2c235b765a1c2", + "reference": "1eb311cabfb7c8a8c861579a48d2c235b765a1c2", "shasum": "" }, "require": { @@ -12707,7 +12710,7 @@ "chat": "https://discord.gg/dphp", "docs": "https://discord-php.github.io/DiscordPHP/", "issues": "https://github.com/discord-php/DiscordPHP/issues", - "source": "https://github.com/discord-php/DiscordPHP/tree/v10.46.2", + "source": "https://github.com/discord-php/DiscordPHP/tree/v10.46.3", "wiki": "https://github.com/discord-php/DiscordPHP/wiki" }, "funding": [ @@ -12728,7 +12731,7 @@ "type": "patreon" } ], - "time": "2026-03-10T12:49:07+00:00" + "time": "2026-03-20T13:35:19+00:00" }, { "name": "tijsverkoyen/css-to-inline-styles", @@ -13331,16 +13334,16 @@ }, { "name": "brianium/paratest", - "version": "v7.19.0", + "version": "v7.19.2", "source": { "type": "git", "url": "https://github.com/paratestphp/paratest.git", - "reference": "7c6c29af7c4b406b49ce0c6b0a3a81d3684474e6" + "reference": "66e4f7910cecf67736bccf2b8bd53a2e3eb98bd9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/paratestphp/paratest/zipball/7c6c29af7c4b406b49ce0c6b0a3a81d3684474e6", - "reference": "7c6c29af7c4b406b49ce0c6b0a3a81d3684474e6", + "url": "https://api.github.com/repos/paratestphp/paratest/zipball/66e4f7910cecf67736bccf2b8bd53a2e3eb98bd9", + "reference": "66e4f7910cecf67736bccf2b8bd53a2e3eb98bd9", "shasum": "" }, "require": { @@ -13354,9 +13357,9 @@ "phpunit/php-code-coverage": "^12.5.3 || ^13.0.1", "phpunit/php-file-iterator": "^6.0.1 || ^7", "phpunit/php-timer": "^8 || ^9", - "phpunit/phpunit": "^12.5.9 || ^13", + "phpunit/phpunit": "^12.5.14 || ^13.0.5", "sebastian/environment": "^8.0.3 || ^9", - "symfony/console": "^7.4.4 || ^8.0.4", + "symfony/console": "^7.4.7 || ^8.0.7", "symfony/process": "^7.4.5 || ^8.0.5" }, "require-dev": { @@ -13364,11 +13367,11 @@ "ext-pcntl": "*", "ext-pcov": "*", "ext-posix": "*", - "phpstan/phpstan": "^2.1.38", - "phpstan/phpstan-deprecation-rules": "^2.0.3", - "phpstan/phpstan-phpunit": "^2.0.12", - "phpstan/phpstan-strict-rules": "^2.0.8", - "symfony/filesystem": "^7.4.0 || ^8.0.1" + "phpstan/phpstan": "^2.1.40", + "phpstan/phpstan-deprecation-rules": "^2.0.4", + "phpstan/phpstan-phpunit": "^2.0.16", + "phpstan/phpstan-strict-rules": "^2.0.10", + "symfony/filesystem": "^7.4.6 || ^8.0.6" }, "bin": [ "bin/paratest", @@ -13408,7 +13411,7 @@ ], "support": { "issues": "https://github.com/paratestphp/paratest/issues", - "source": "https://github.com/paratestphp/paratest/tree/v7.19.0" + "source": "https://github.com/paratestphp/paratest/tree/v7.19.2" }, "funding": [ { @@ -13420,7 +13423,7 @@ "type": "paypal" } ], - "time": "2026-02-06T10:53:26+00:00" + "time": "2026-03-09T14:33:17+00:00" }, { "name": "doctrine/deprecations", @@ -13472,22 +13475,22 @@ }, { "name": "driftingly/rector-laravel", - "version": "2.1.12", + "version": "2.2.0", "source": { "type": "git", "url": "https://github.com/driftingly/rector-laravel.git", - "reference": "2a2175eefabca6d15c247d55de17c75dc2f787a9" + "reference": "807840ceb09de6764cbfcce0719108d044a459a9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/driftingly/rector-laravel/zipball/2a2175eefabca6d15c247d55de17c75dc2f787a9", - "reference": "2a2175eefabca6d15c247d55de17c75dc2f787a9", + "url": "https://api.github.com/repos/driftingly/rector-laravel/zipball/807840ceb09de6764cbfcce0719108d044a459a9", + "reference": "807840ceb09de6764cbfcce0719108d044a459a9", "shasum": "" }, "require": { "php": "^7.4 || ^8.0", "rector/rector": "^2.2.7", - "webmozart/assert": "^1.11" + "webmozart/assert": "^1.11 || ^2.0" }, "type": "rector-extension", "autoload": { @@ -13502,9 +13505,9 @@ "description": "Rector upgrades rules for Laravel Framework", "support": { "issues": "https://github.com/driftingly/rector-laravel/issues", - "source": "https://github.com/driftingly/rector-laravel/tree/2.1.12" + "source": "https://github.com/driftingly/rector-laravel/tree/2.2.0" }, - "time": "2026-03-06T19:59:21+00:00" + "time": "2026-03-19T17:24:38+00:00" }, { "name": "fakerphp/faker", @@ -14637,20 +14640,20 @@ }, { "name": "pestphp/pest", - "version": "v4.4.2", + "version": "v4.4.3", "source": { "type": "git", "url": "https://github.com/pestphp/pest.git", - "reference": "5d42e8fe3ae1d9fdf7c9f73ee88138fd30265701" + "reference": "e6ab897594312728ef2e32d586cb4f6780b1b495" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pestphp/pest/zipball/5d42e8fe3ae1d9fdf7c9f73ee88138fd30265701", - "reference": "5d42e8fe3ae1d9fdf7c9f73ee88138fd30265701", + "url": "https://api.github.com/repos/pestphp/pest/zipball/e6ab897594312728ef2e32d586cb4f6780b1b495", + "reference": "e6ab897594312728ef2e32d586cb4f6780b1b495", "shasum": "" }, "require": { - "brianium/paratest": "^7.19.0", + "brianium/paratest": "^7.19.2", "nunomaduro/collision": "^8.9.1", "nunomaduro/termwind": "^2.4.0", "pestphp/pest-plugin": "^4.0.0", @@ -14658,12 +14661,12 @@ "pestphp/pest-plugin-mutate": "^4.0.1", "pestphp/pest-plugin-profanity": "^4.2.1", "php": "^8.3.0", - "phpunit/phpunit": "^12.5.12", + "phpunit/phpunit": "^12.5.14", "symfony/process": "^7.4.5|^8.0.5" }, "conflict": { "filp/whoops": "<2.18.3", - "phpunit/phpunit": ">12.5.12", + "phpunit/phpunit": ">12.5.14", "sebastian/exporter": "<7.0.0", "webmozart/assert": "<1.11.0" }, @@ -14737,7 +14740,7 @@ ], "support": { "issues": "https://github.com/pestphp/pest/issues", - "source": "https://github.com/pestphp/pest/tree/v4.4.2" + "source": "https://github.com/pestphp/pest/tree/v4.4.3" }, "funding": [ { @@ -14749,7 +14752,7 @@ "type": "github" } ], - "time": "2026-03-10T21:09:12+00:00" + "time": "2026-03-21T13:14:39+00:00" }, { "name": "pestphp/pest-plugin", @@ -15638,16 +15641,16 @@ }, { "name": "phpdocumentor/reflection-docblock", - "version": "6.0.2", + "version": "6.0.3", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "897b5986ece6b4f9d8413fea345c7d49c757d6bf" + "reference": "7bae67520aa9f5ecc506d646810bd40d9da54582" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/897b5986ece6b4f9d8413fea345c7d49c757d6bf", - "reference": "897b5986ece6b4f9d8413fea345c7d49c757d6bf", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/7bae67520aa9f5ecc506d646810bd40d9da54582", + "reference": "7bae67520aa9f5ecc506d646810bd40d9da54582", "shasum": "" }, "require": { @@ -15697,9 +15700,9 @@ "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", "support": { "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", - "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/6.0.2" + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/6.0.3" }, - "time": "2026-03-01T18:43:49+00:00" + "time": "2026-03-18T20:49:53+00:00" }, { "name": "phpdocumentor/type-resolver", @@ -16208,16 +16211,16 @@ }, { "name": "phpunit/phpunit", - "version": "12.5.12", + "version": "12.5.14", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "418e06b3b46b0d54bad749ff4907fc7dfb530199" + "reference": "47283cfd98d553edcb1353591f4e255dc1bb61f0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/418e06b3b46b0d54bad749ff4907fc7dfb530199", - "reference": "418e06b3b46b0d54bad749ff4907fc7dfb530199", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/47283cfd98d553edcb1353591f4e255dc1bb61f0", + "reference": "47283cfd98d553edcb1353591f4e255dc1bb61f0", "shasum": "" }, "require": { @@ -16286,7 +16289,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/12.5.12" + "source": "https://github.com/sebastianbergmann/phpunit/tree/12.5.14" }, "funding": [ { @@ -16310,7 +16313,7 @@ "type": "tidelift" } ], - "time": "2026-02-16T08:34:36+00:00" + "time": "2026-02-18T12:38:40+00:00" }, { "name": "rector/rector", @@ -17431,23 +17434,23 @@ }, { "name": "webmozart/assert", - "version": "1.12.1", + "version": "2.1.6", "source": { "type": "git", "url": "https://github.com/webmozarts/assert.git", - "reference": "9be6926d8b485f55b9229203f962b51ed377ba68" + "reference": "ff31ad6efc62e66e518fbab1cde3453d389bcdc8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozarts/assert/zipball/9be6926d8b485f55b9229203f962b51ed377ba68", - "reference": "9be6926d8b485f55b9229203f962b51ed377ba68", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/ff31ad6efc62e66e518fbab1cde3453d389bcdc8", + "reference": "ff31ad6efc62e66e518fbab1cde3453d389bcdc8", "shasum": "" }, "require": { "ext-ctype": "*", "ext-date": "*", "ext-filter": "*", - "php": "^7.2 || ^8.0" + "php": "^8.2" }, "suggest": { "ext-intl": "", @@ -17457,7 +17460,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.10-dev" + "dev-feature/2-0": "2.0-dev" } }, "autoload": { @@ -17473,6 +17476,10 @@ { "name": "Bernhard Schussek", "email": "bschussek@gmail.com" + }, + { + "name": "Woody Gilk", + "email": "woody.gilk@gmail.com" } ], "description": "Assertions to validate method input/output with nice error messages.", @@ -17483,9 +17490,9 @@ ], "support": { "issues": "https://github.com/webmozarts/assert/issues", - "source": "https://github.com/webmozarts/assert/tree/1.12.1" + "source": "https://github.com/webmozarts/assert/tree/2.1.6" }, - "time": "2025-10-29T15:56:20+00:00" + "time": "2026-02-27T10:28:38+00:00" } ], "aliases": [], diff --git a/database/migrations/2026_03_21_192332_deduplicate_external_identities.php b/database/migrations/2026_03_21_192332_deduplicate_external_identities.php new file mode 100644 index 00000000..04899913 --- /dev/null +++ b/database/migrations/2026_03_21_192332_deduplicate_external_identities.php @@ -0,0 +1,65 @@ +where('external_identity_id', $dup->old_ei_id) + ->update(['external_identity_id' => $dup->new_ei_id]); + + DB::table('voice_messages') + ->where('external_identity_id', $dup->old_ei_id) + ->update(['external_identity_id' => $dup->new_ei_id]); + + $oldXp = DB::table('characters') + ->where('user_id', $dup->old_user_id) + ->value('experience') ?? 0; + + if ($oldXp > 0) { + DB::table('characters') + ->where('user_id', $dup->new_user_id) + ->increment('experience', $oldXp); + } + + DB::table('external_identities') + ->where('id', $dup->old_ei_id) + ->update(['deleted_at' => now()]); + } + } + + public function down(): void + { + // Cannot fully reverse XP merge or message reassignment. + // Restore soft-deleted old EIs only. + DB::table('external_identities') + ->whereNotNull('deleted_at') + ->whereRaw('LENGTH(model_type) = 25') + ->update(['deleted_at' => null]); + } +}; diff --git a/database/migrations/2026_03_21_192333_convert_morph_types_to_aliases.php b/database/migrations/2026_03_21_192333_convert_morph_types_to_aliases.php new file mode 100644 index 00000000..59dc2723 --- /dev/null +++ b/database/migrations/2026_03_21_192333_convert_morph_types_to_aliases.php @@ -0,0 +1,103 @@ + [ + 'He4rt\\\\User\\\\Models\\\\User', + 'He4rt\\User\\Models\\User', + User::class, + ], + 'tenant' => [ + 'He4rt\\Tenant\\Models\\Tenant', + Tenant::class, + ], + 'character' => [ + Character::class, + 'He4rt\\Character\\Models\\Character', + ], + 'badge' => [ + Badge::class, + 'He4rt\\Badge\\Models\\Badge', + ], + 'event_submission' => [ + EventSubmission::class, + ], + 'event_segment' => [ + EventSegment::class, + ], + 'sponsor' => [ + Sponsor::class, + 'He4rt\\Sponsors\\Models\\Sponsor', + ], + ]; + + private const array TABLES = [ + 'external_identities' => 'model_type', + 'wallets' => 'owner_type', + 'transactions' => 'reference_type', + 'events_agenda' => 'schedulable_type', + 'media' => 'model_type', + 'notifications' => 'notifiable_type', + 'personal_access_tokens' => 'tokenable_type', + ]; + + public function up(): void + { + foreach (self::TABLES as $table => $column) { + if (! Schema::hasTable($table)) { + continue; + } + + foreach (self::MORPH_MAP as $alias => $fqcns) { + foreach ($fqcns as $fqcn) { + DB::table($table) + ->where($column, $fqcn) + ->update([$column => $alias]); + } + } + } + } + + public function down(): void + { + $reverseMap = [ + 'user' => User::class, + 'tenant' => Tenant::class, + 'character' => Character::class, + 'badge' => Badge::class, + 'event_submission' => EventSubmission::class, + 'event_segment' => EventSegment::class, + 'sponsor' => Sponsor::class, + ]; + + foreach (self::TABLES as $table => $column) { + if (! Schema::hasTable($table)) { + continue; + } + + foreach ($reverseMap as $alias => $fqcn) { + DB::table($table) + ->where($column, $alias) + ->update([$column => $fqcn]); + } + } + } +}; diff --git a/database/migrations/2026_03_21_200000_cleanup_orphan_users.php b/database/migrations/2026_03_21_200000_cleanup_orphan_users.php new file mode 100644 index 00000000..42cf806b --- /dev/null +++ b/database/migrations/2026_03_21_200000_cleanup_orphan_users.php @@ -0,0 +1,121 @@ +orphan_user_id] = $m->kept_user_id; + } + + // Collect ALL orphan user IDs (including 26 with no EI at all) + $orphanUserIds = DB::table('users') + ->whereNotExists(function ($query): void { + $query->select(DB::raw(1)) + ->from('external_identities') + ->whereColumn('external_identities.model_id', DB::raw('users.id::text')) + ->whereNull('external_identities.deleted_at'); + }) + ->pluck('id'); + + if ($orphanUserIds->isEmpty()) { + return; + } + + // === PHASE 1: Migrate data from orphan → kept user === + + // 1a. Merge user_information: fill empty fields on kept user from orphan + foreach ($orphanToKept as $orphanId => $keptId) { + $orphanInfo = DB::table('user_information')->where('user_id', $orphanId)->first(); + $keptInfo = DB::table('user_information')->where('user_id', $keptId)->first(); + + if (! $orphanInfo || ! $keptInfo) { + continue; + } + + $fields = ['name', 'nickname', 'github_url', 'linkedin_url', 'about', 'birthdate']; + $updates = []; + + foreach ($fields as $field) { + if (blank($keptInfo->{$field}) && filled($orphanInfo->{$field})) { + $updates[$field] = $orphanInfo->{$field}; + } + } + + if ($updates !== []) { + DB::table('user_information')->where('user_id', $keptId)->update($updates); + } + } + + // 1b. Reassign feedbacks: point sender_id/target_id from orphan → kept user + foreach ($orphanToKept as $orphanId => $keptId) { + DB::table('feedbacks') + ->where('sender_id', $orphanId) + ->update(['sender_id' => $keptId]); + + DB::table('feedbacks') + ->where('target_id', $orphanId) + ->update(['target_id' => $keptId]); + } + + // === PHASE 2: Clean up NO ACTION FK references === + + $orphanCharacterIds = DB::table('characters') + ->whereIn('user_id', $orphanUserIds) + ->pluck('id'); + + DB::table('characters_leveling_logs') + ->whereIn('character_id', $orphanCharacterIds) + ->delete(); + + DB::table('event_submission_speakers') + ->whereIn('user_id', $orphanUserIds) + ->delete(); + + // === PHASE 3: Clean up orphan records === + + DB::table('external_identities') + ->whereIn('model_id', $orphanUserIds->map(fn ($id) => (string) $id)) + ->whereNotNull('deleted_at') + ->delete(); + + DB::table('media') + ->where('model_type', 'user') + ->whereIn('model_id', $orphanUserIds->map(fn ($id) => (string) $id)) + ->delete(); + + // Delete orphan users — cascades to: + // characters (→ characters_badges, characters_wallet), + // user_information, user_address, tenant_users, + // events_attendees, events_talks, feedback_reviews, + // meetings, meeting_participants + DB::table('users') + ->whereIn('id', $orphanUserIds) + ->delete(); + } + + public function down(): void + { + // Irreversible: orphan data has been permanently deleted. + } +}; diff --git a/database/seeders/ThreeDotsSeeder.php b/database/seeders/ThreeDotsSeeder.php index 842da05c..e0cf69cd 100644 --- a/database/seeders/ThreeDotsSeeder.php +++ b/database/seeders/ThreeDotsSeeder.php @@ -169,7 +169,7 @@ private function talks(Tenant $tenant, EventModel $event): void $event->agenda()->create([ 'tenant_id' => $tenant->getKey(), - 'schedulable_type' => EventSubmission::class, + 'schedulable_type' => (new EventSubmission)->getMorphClass(), 'schedulable_id' => $eventSubmission->getKey(), 'starting_at' => Date::parse($item['start']), 'ending_at' => Date::parse($item['end']), @@ -177,7 +177,7 @@ private function talks(Tenant $tenant, EventModel $event): void } else { $event->agenda()->create([ 'tenant_id' => $tenant->getKey(), - 'schedulable_type' => EventSegment::class, + 'schedulable_type' => (new EventSegment)->getMorphClass(), 'schedulable_id' => EventSegment::query()->inRandomOrder()->first()->getKey(), 'starting_at' => Date::parse($item['start']), 'ending_at' => Date::parse($item['end']), diff --git a/package-lock.json b/package-lock.json index b5066dad..e1dd8c5a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,7 @@ "devDependencies": { "@prettier/plugin-php": "0.24.0", "@tailwindcss/typography": "0.5.19", - "@tailwindcss/vite": "4.2.1", + "@tailwindcss/vite": "4.2.2", "axios": "1.13.6", "concurrently": "9.2.1", "husky": "9.1.7", @@ -19,9 +19,9 @@ "lint-staged": "16.4.0", "npm-check-updates": "19.6.5", "prettier": "3.8.1", - "prettier-plugin-blade": "3.1.3", + "prettier-plugin-blade": "3.1.4", "prettier-plugin-tailwindcss": "0.7.2", - "tailwindcss": "4.2.1", + "tailwindcss": "4.2.2", "tw-animate-css": "1.4.0", "vite": "7.3.1" }, @@ -29,8 +29,8 @@ "node": "^24" }, "optionalDependencies": { - "@rollup/rollup-linux-x64-gnu": "4.59.0", - "@tailwindcss/oxide-linux-x64-gnu": "4.2.1", + "@rollup/rollup-linux-x64-gnu": "4.59.1", + "@tailwindcss/oxide-linux-x64-gnu": "4.2.2", "lightningcss-linux-x64-gnu": "1.32.0" } }, @@ -556,9 +556,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.0.tgz", - "integrity": "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==", + "version": "4.59.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.1.tgz", + "integrity": "sha512-xB0b51TB7IfDEzAojXahmr+gfA00uYVInJGgNNkeQG6RPnCPGr7udsylFLTubuIUSRE6FkcI1NElyRt83PP5oQ==", "cpu": [ "arm" ], @@ -570,9 +570,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.59.0.tgz", - "integrity": "sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==", + "version": "4.59.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.59.1.tgz", + "integrity": "sha512-XOjPId0qwSDKHaIsdzHJtKCxX0+nH8MhBwvrNsT7tVyKmdTx1jJ4XzN5RZXCdTzMpufLb+B8llTC0D8uCrLhcw==", "cpu": [ "arm64" ], @@ -584,9 +584,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.59.0.tgz", - "integrity": "sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==", + "version": "4.59.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.59.1.tgz", + "integrity": "sha512-vQuRd28p0gQpPrS6kppd8IrWmFo42U8Pz1XLRjSZXq5zCqyMDYFABT7/sywL11mO1EL10Qhh7MVPEwkG8GiBeg==", "cpu": [ "arm64" ], @@ -598,9 +598,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.59.0.tgz", - "integrity": "sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==", + "version": "4.59.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.59.1.tgz", + "integrity": "sha512-x6VG6U29+Ivlnajrg1IHdzXeAwSoEHBFVO+CtC9Brugx6de712CUJobRUxsIA0KYrQvCmzNrMPFTT1A4CCqNTg==", "cpu": [ "x64" ], @@ -612,9 +612,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.59.0.tgz", - "integrity": "sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==", + "version": "4.59.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.59.1.tgz", + "integrity": "sha512-Sgi0Uo6t1YCHJMNO3Y8+bm+SvOanUGkoZKn/VJPwYUe2kp31X5KnXmzKd/NjW8iA3gFcfNZ64zh14uOGrIllCQ==", "cpu": [ "arm64" ], @@ -626,9 +626,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.59.0.tgz", - "integrity": "sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==", + "version": "4.59.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.59.1.tgz", + "integrity": "sha512-AM4xnwEZwukdhk7laMWfzWu9JGSVnJd+Fowt6Fd7QW1nrf3h0Hp7Qx5881M4aqrUlKBCybOxz0jofvIIfl7C5g==", "cpu": [ "x64" ], @@ -640,9 +640,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.59.0.tgz", - "integrity": "sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==", + "version": "4.59.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.59.1.tgz", + "integrity": "sha512-KUizqxpwaR2AZdAUsMWfL/C94pUu7TKpoPd88c8yFVixJ+l9hejkrwoK5Zj3wiNh65UeyryKnJyxL1b7yNqFQA==", "cpu": [ "arm" ], @@ -654,9 +654,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.59.0.tgz", - "integrity": "sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==", + "version": "4.59.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.59.1.tgz", + "integrity": "sha512-MZoQ/am77ckJtZGFAtPucgUuJWiop3m2R3lw7tC0QCcbfl4DRhQUBUkHWCkcrT3pqy5Mzv5QQgY6Dmlba6iTWg==", "cpu": [ "arm" ], @@ -668,9 +668,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.59.0.tgz", - "integrity": "sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==", + "version": "4.59.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.59.1.tgz", + "integrity": "sha512-Sez95TP6xGjkWB1608EfhCX1gdGrO5wzyN99VqzRtC17x/1bhw5VU1V0GfKUwbW/Xr1J8mSasoFoJa6Y7aGGSA==", "cpu": [ "arm64" ], @@ -682,9 +682,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.59.0.tgz", - "integrity": "sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==", + "version": "4.59.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.59.1.tgz", + "integrity": "sha512-9Cs2Seq98LWNOJzR89EGTZoiP8EkZ9UbQhBlDgfAkM6asVna1xJ04W2CLYWDN/RpUgOjtQvcv8wQVi1t5oQazA==", "cpu": [ "arm64" ], @@ -696,9 +696,9 @@ ] }, "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.59.0.tgz", - "integrity": "sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==", + "version": "4.59.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.59.1.tgz", + "integrity": "sha512-n9yqttftgFy7IrNEnHy1bOp6B4OSe8mJDiPkT7EqlM9FnKOwUMnCK62ixW0Kd9Clw0/wgvh8+SqaDXMFvw3KqQ==", "cpu": [ "loong64" ], @@ -710,9 +710,9 @@ ] }, "node_modules/@rollup/rollup-linux-loong64-musl": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.59.0.tgz", - "integrity": "sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==", + "version": "4.59.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.59.1.tgz", + "integrity": "sha512-SfpNXDzVTqs/riak4xXcLpq5gIQWsqGWMhN1AGRQKB4qGSs4r0sEs3ervXPcE1O9RsQ5bm8Muz6zmQpQnPss1g==", "cpu": [ "loong64" ], @@ -724,9 +724,9 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.59.0.tgz", - "integrity": "sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==", + "version": "4.59.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.59.1.tgz", + "integrity": "sha512-LjaChED0wQnjKZU+tsmGbN+9nN1XhaWUkAlSbTdhpEseCS4a15f/Q8xC2BN4GDKRzhhLZpYtJBZr2NZhR0jvNw==", "cpu": [ "ppc64" ], @@ -738,9 +738,9 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-musl": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.59.0.tgz", - "integrity": "sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==", + "version": "4.59.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.59.1.tgz", + "integrity": "sha512-ojW7iTJSIs4pwB2xV6QXGwNyDctvXOivYllttuPbXguuKDX5vwpqYJsHc6D2LZzjDGHML414Tuj3LvVPe1CT1A==", "cpu": [ "ppc64" ], @@ -752,9 +752,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.59.0.tgz", - "integrity": "sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==", + "version": "4.59.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.59.1.tgz", + "integrity": "sha512-FP+Q6WTcxxvsr0wQczhSE+tOZvFPV8A/mUE6mhZYFW9/eea/y/XqAgRoLLMuE9Cz0hfX5bi7p116IWoB+P237A==", "cpu": [ "riscv64" ], @@ -766,9 +766,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.59.0.tgz", - "integrity": "sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==", + "version": "4.59.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.59.1.tgz", + "integrity": "sha512-L1uD9b/Ig8Z+rn1KttCJjwhN1FgjRMBKsPaBsDKkfUl7GfFq71pU4vWCnpOsGljycFEbkHWARZLf4lMYg3WOLw==", "cpu": [ "riscv64" ], @@ -780,9 +780,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.59.0.tgz", - "integrity": "sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==", + "version": "4.59.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.59.1.tgz", + "integrity": "sha512-EZc9NGTk/oSUzzOD4nYY4gIjteo2M3CiozX6t1IXGCOdgxJTlVu/7EdPeiqeHPSIrxkLhavqpBAUCfvC6vBOug==", "cpu": [ "s390x" ], @@ -794,9 +794,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.59.0.tgz", - "integrity": "sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==", + "version": "4.59.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.59.1.tgz", + "integrity": "sha512-NQ9KyU1Anuy59L8+HHOKM++CoUxrQWrZWXRik4BJFm+7i5NP6q/SW43xIBr80zzt+PDBJ7LeNmloQGfa0JGk0w==", "cpu": [ "x64" ], @@ -807,9 +807,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.59.0.tgz", - "integrity": "sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==", + "version": "4.59.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.59.1.tgz", + "integrity": "sha512-GZkLk2t6naywsveSFBsEb0PLU+JC9ggVjbndsbG20VPhar6D1gkMfCx4NfP9owpovBXTN+eRdqGSkDGIxPHhmQ==", "cpu": [ "x64" ], @@ -821,9 +821,9 @@ ] }, "node_modules/@rollup/rollup-openbsd-x64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.59.0.tgz", - "integrity": "sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==", + "version": "4.59.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.59.1.tgz", + "integrity": "sha512-1hjG9Jpl2KDOetr64iQd8AZAEjkDUUK5RbDkYWsViYLC1op1oNzdjMJeFiofcGhqbNTaY2kfgqowE7DILifsrA==", "cpu": [ "x64" ], @@ -835,9 +835,9 @@ ] }, "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.59.0.tgz", - "integrity": "sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==", + "version": "4.59.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.59.1.tgz", + "integrity": "sha512-ARoKfflk0SiiYm3r1fmF73K/yB+PThmOwfWCk1sr7x/k9dc3uGLWuEE9if+Pw21el8MSpp3TMnG5vLNsJ/MMGQ==", "cpu": [ "arm64" ], @@ -849,9 +849,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.59.0.tgz", - "integrity": "sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==", + "version": "4.59.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.59.1.tgz", + "integrity": "sha512-oOST61G6VM45Mz2vdzWMr1s2slI7y9LqxEV5fCoWi2MDONmMvgsJVHSXxce/I2xOSZPTZ47nDPOl1tkwKWSHcw==", "cpu": [ "arm64" ], @@ -863,9 +863,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.59.0.tgz", - "integrity": "sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==", + "version": "4.59.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.59.1.tgz", + "integrity": "sha512-x5WgLi5dWpRz7WclKBGEF15LcWTh0ewrHM6Cq4A+WUbkysUMZNeqt05bwPonOQ3ihPS/WMhAZV5zB1DfnI4Sxg==", "cpu": [ "ia32" ], @@ -877,9 +877,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.59.0.tgz", - "integrity": "sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==", + "version": "4.59.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.59.1.tgz", + "integrity": "sha512-wS+zHAJRVP5zOL0e+a3V3E/NTEwM2HEvvNKoDy5Xcfs0o8lljxn+EAFPkUsxihBdmDq1JWzXmmB9cbssCPdxxw==", "cpu": [ "x64" ], @@ -891,9 +891,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.59.0.tgz", - "integrity": "sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==", + "version": "4.59.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.59.1.tgz", + "integrity": "sha512-rhHyrMeLpErT/C7BxcEsU4COHQUzHyrPYW5tOZUeUhziNtRuYxmDWvqQqzpuUt8xpOgmbKa1btGXfnA/ANVO+g==", "cpu": [ "x64" ], @@ -905,49 +905,49 @@ ] }, "node_modules/@tailwindcss/node": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.2.1.tgz", - "integrity": "sha512-jlx6sLk4EOwO6hHe1oCGm1Q4AN/s0rSrTTPBGPM0/RQ6Uylwq17FuU8IeJJKEjtc6K6O07zsvP+gDO6MMWo7pg==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.2.2.tgz", + "integrity": "sha512-pXS+wJ2gZpVXqFaUEjojq7jzMpTGf8rU6ipJz5ovJV6PUGmlJ+jvIwGrzdHdQ80Sg+wmQxUFuoW1UAAwHNEdFA==", "dev": true, "license": "MIT", "dependencies": { "@jridgewell/remapping": "^2.3.5", "enhanced-resolve": "^5.19.0", "jiti": "^2.6.1", - "lightningcss": "1.31.1", + "lightningcss": "1.32.0", "magic-string": "^0.30.21", "source-map-js": "^1.2.1", - "tailwindcss": "4.2.1" + "tailwindcss": "4.2.2" } }, "node_modules/@tailwindcss/oxide": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.2.1.tgz", - "integrity": "sha512-yv9jeEFWnjKCI6/T3Oq50yQEOqmpmpfzG1hcZsAOaXFQPfzWprWrlHSdGPEF3WQTi8zu8ohC9Mh9J470nT5pUw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.2.2.tgz", + "integrity": "sha512-qEUA07+E5kehxYp9BVMpq9E8vnJuBHfJEC0vPC5e7iL/hw7HR61aDKoVoKzrG+QKp56vhNZe4qwkRmMC0zDLvg==", "dev": true, "license": "MIT", "engines": { "node": ">= 20" }, "optionalDependencies": { - "@tailwindcss/oxide-android-arm64": "4.2.1", - "@tailwindcss/oxide-darwin-arm64": "4.2.1", - "@tailwindcss/oxide-darwin-x64": "4.2.1", - "@tailwindcss/oxide-freebsd-x64": "4.2.1", - "@tailwindcss/oxide-linux-arm-gnueabihf": "4.2.1", - "@tailwindcss/oxide-linux-arm64-gnu": "4.2.1", - "@tailwindcss/oxide-linux-arm64-musl": "4.2.1", - "@tailwindcss/oxide-linux-x64-gnu": "4.2.1", - "@tailwindcss/oxide-linux-x64-musl": "4.2.1", - "@tailwindcss/oxide-wasm32-wasi": "4.2.1", - "@tailwindcss/oxide-win32-arm64-msvc": "4.2.1", - "@tailwindcss/oxide-win32-x64-msvc": "4.2.1" + "@tailwindcss/oxide-android-arm64": "4.2.2", + "@tailwindcss/oxide-darwin-arm64": "4.2.2", + "@tailwindcss/oxide-darwin-x64": "4.2.2", + "@tailwindcss/oxide-freebsd-x64": "4.2.2", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.2.2", + "@tailwindcss/oxide-linux-arm64-gnu": "4.2.2", + "@tailwindcss/oxide-linux-arm64-musl": "4.2.2", + "@tailwindcss/oxide-linux-x64-gnu": "4.2.2", + "@tailwindcss/oxide-linux-x64-musl": "4.2.2", + "@tailwindcss/oxide-wasm32-wasi": "4.2.2", + "@tailwindcss/oxide-win32-arm64-msvc": "4.2.2", + "@tailwindcss/oxide-win32-x64-msvc": "4.2.2" } }, "node_modules/@tailwindcss/oxide-android-arm64": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.2.1.tgz", - "integrity": "sha512-eZ7G1Zm5EC8OOKaesIKuw77jw++QJ2lL9N+dDpdQiAB/c/B2wDh0QPFHbkBVrXnwNugvrbJFk1gK2SsVjwWReg==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.2.2.tgz", + "integrity": "sha512-dXGR1n+P3B6748jZO/SvHZq7qBOqqzQ+yFrXpoOWWALWndF9MoSKAT3Q0fYgAzYzGhxNYOoysRvYlpixRBBoDg==", "cpu": [ "arm64" ], @@ -962,9 +962,9 @@ } }, "node_modules/@tailwindcss/oxide-darwin-arm64": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.2.1.tgz", - "integrity": "sha512-q/LHkOstoJ7pI1J0q6djesLzRvQSIfEto148ppAd+BVQK0JYjQIFSK3JgYZJa+Yzi0DDa52ZsQx2rqytBnf8Hw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.2.2.tgz", + "integrity": "sha512-iq9Qjr6knfMpZHj55/37ouZeykwbDqF21gPFtfnhCCKGDcPI/21FKC9XdMO/XyBM7qKORx6UIhGgg6jLl7BZlg==", "cpu": [ "arm64" ], @@ -979,9 +979,9 @@ } }, "node_modules/@tailwindcss/oxide-darwin-x64": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.2.1.tgz", - "integrity": "sha512-/f/ozlaXGY6QLbpvd/kFTro2l18f7dHKpB+ieXz+Cijl4Mt9AI2rTrpq7V+t04nK+j9XBQHnSMdeQRhbGyt6fw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.2.2.tgz", + "integrity": "sha512-BlR+2c3nzc8f2G639LpL89YY4bdcIdUmiOOkv2GQv4/4M0vJlpXEa0JXNHhCHU7VWOKWT/CjqHdTP8aUuDJkuw==", "cpu": [ "x64" ], @@ -996,9 +996,9 @@ } }, "node_modules/@tailwindcss/oxide-freebsd-x64": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.2.1.tgz", - "integrity": "sha512-5e/AkgYJT/cpbkys/OU2Ei2jdETCLlifwm7ogMC7/hksI2fC3iiq6OcXwjibcIjPung0kRtR3TxEITkqgn0TcA==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.2.2.tgz", + "integrity": "sha512-YUqUgrGMSu2CDO82hzlQ5qSb5xmx3RUrke/QgnoEx7KvmRJHQuZHZmZTLSuuHwFf0DJPybFMXMYf+WJdxHy/nQ==", "cpu": [ "x64" ], @@ -1013,9 +1013,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.2.1.tgz", - "integrity": "sha512-Uny1EcVTTmerCKt/1ZuKTkb0x8ZaiuYucg2/kImO5A5Y/kBz41/+j0gxUZl+hTF3xkWpDmHX+TaWhOtba2Fyuw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.2.2.tgz", + "integrity": "sha512-FPdhvsW6g06T9BWT0qTwiVZYE2WIFo2dY5aCSpjG/S/u1tby+wXoslXS0kl3/KXnULlLr1E3NPRRw0g7t2kgaQ==", "cpu": [ "arm" ], @@ -1030,9 +1030,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.2.1.tgz", - "integrity": "sha512-CTrwomI+c7n6aSSQlsPL0roRiNMDQ/YzMD9EjcR+H4f0I1SQ8QqIuPnsVp7QgMkC1Qi8rtkekLkOFjo7OlEFRQ==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.2.2.tgz", + "integrity": "sha512-4og1V+ftEPXGttOO7eCmW7VICmzzJWgMx+QXAJRAhjrSjumCwWqMfkDrNu1LXEQzNAwz28NCUpucgQPrR4S2yw==", "cpu": [ "arm64" ], @@ -1047,9 +1047,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-arm64-musl": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.2.1.tgz", - "integrity": "sha512-WZA0CHRL/SP1TRbA5mp9htsppSEkWuQ4KsSUumYQnyl8ZdT39ntwqmz4IUHGN6p4XdSlYfJwM4rRzZLShHsGAQ==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.2.2.tgz", + "integrity": "sha512-oCfG/mS+/+XRlwNjnsNLVwnMWYH7tn/kYPsNPh+JSOMlnt93mYNCKHYzylRhI51X+TbR+ufNhhKKzm6QkqX8ag==", "cpu": [ "arm64" ], @@ -1064,9 +1064,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-x64-gnu": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.2.1.tgz", - "integrity": "sha512-qMFzxI2YlBOLW5PhblzuSWlWfwLHaneBE0xHzLrBgNtqN6mWfs+qYbhryGSXQjFYB1Dzf5w+LN5qbUTPhW7Y5g==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.2.2.tgz", + "integrity": "sha512-rTAGAkDgqbXHNp/xW0iugLVmX62wOp2PoE39BTCGKjv3Iocf6AFbRP/wZT/kuCxC9QBh9Pu8XPkv/zCZB2mcMg==", "cpu": [ "x64" ], @@ -1080,9 +1080,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-x64-musl": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.2.1.tgz", - "integrity": "sha512-5r1X2FKnCMUPlXTWRYpHdPYUY6a1Ar/t7P24OuiEdEOmms5lyqjDRvVY1yy9Rmioh+AunQ0rWiOTPE8F9A3v5g==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.2.2.tgz", + "integrity": "sha512-XW3t3qwbIwiSyRCggeO2zxe3KWaEbM0/kW9e8+0XpBgyKU4ATYzcVSMKteZJ1iukJ3HgHBjbg9P5YPRCVUxlnQ==", "cpu": [ "x64" ], @@ -1097,9 +1097,9 @@ } }, "node_modules/@tailwindcss/oxide-wasm32-wasi": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.2.1.tgz", - "integrity": "sha512-MGFB5cVPvshR85MTJkEvqDUnuNoysrsRxd6vnk1Lf2tbiqNlXpHYZqkqOQalydienEWOHHFyyuTSYRsLfxFJ2Q==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.2.2.tgz", + "integrity": "sha512-eKSztKsmEsn1O5lJ4ZAfyn41NfG7vzCg496YiGtMDV86jz1q/irhms5O0VrY6ZwTUkFy/EKG3RfWgxSI3VbZ8Q==", "bundleDependencies": [ "@napi-rs/wasm-runtime", "@emnapi/core", @@ -1127,9 +1127,9 @@ } }, "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.2.1.tgz", - "integrity": "sha512-YlUEHRHBGnCMh4Nj4GnqQyBtsshUPdiNroZj8VPkvTZSoHsilRCwXcVKnG9kyi0ZFAS/3u+qKHBdDc81SADTRA==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.2.2.tgz", + "integrity": "sha512-qPmaQM4iKu5mxpsrWZMOZRgZv1tOZpUm+zdhhQP0VhJfyGGO3aUKdbh3gDZc/dPLQwW4eSqWGrrcWNBZWUWaXQ==", "cpu": [ "arm64" ], @@ -1144,9 +1144,9 @@ } }, "node_modules/@tailwindcss/oxide-win32-x64-msvc": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.2.1.tgz", - "integrity": "sha512-rbO34G5sMWWyrN/idLeVxAZgAKWrn5LiR3/I90Q9MkA67s6T1oB0xtTe+0heoBvHSpbU9Mk7i6uwJnpo4u21XQ==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.2.2.tgz", + "integrity": "sha512-1T/37VvI7WyH66b+vqHj/cLwnCxt7Qt3WFu5Q8hk65aOvlwAhs7rAp1VkulBJw/N4tMirXjVnylTR72uI0HGcA==", "cpu": [ "x64" ], @@ -1174,18 +1174,18 @@ } }, "node_modules/@tailwindcss/vite": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.2.1.tgz", - "integrity": "sha512-TBf2sJjYeb28jD2U/OhwdW0bbOsxkWPwQ7SrqGf9sVcoYwZj7rkXljroBO9wKBut9XnmQLXanuDUeqQK0lGg/w==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.2.2.tgz", + "integrity": "sha512-mEiF5HO1QqCLXoNEfXVA1Tzo+cYsrqV7w9Juj2wdUFyW07JRenqMG225MvPwr3ZD9N1bFQj46X7r33iHxLUW0w==", "dev": true, "license": "MIT", "dependencies": { - "@tailwindcss/node": "4.2.1", - "@tailwindcss/oxide": "4.2.1", - "tailwindcss": "4.2.1" + "@tailwindcss/node": "4.2.2", + "@tailwindcss/oxide": "4.2.2", + "tailwindcss": "4.2.2" }, "peerDependencies": { - "vite": "^5.2.0 || ^6 || ^7" + "vite": "^5.2.0 || ^6 || ^7 || ^8" } }, "node_modules/@types/estree": { @@ -1971,9 +1971,9 @@ } }, "node_modules/lightningcss": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.31.1.tgz", - "integrity": "sha512-l51N2r93WmGUye3WuFoN5k10zyvrVs0qfKBhyC5ogUQ6Ew6JUSswh78mbSO+IU3nTWsyOArqPCcShdQSadghBQ==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", + "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==", "dev": true, "license": "MPL-2.0", "dependencies": { @@ -1987,23 +1987,23 @@ "url": "https://opencollective.com/parcel" }, "optionalDependencies": { - "lightningcss-android-arm64": "1.31.1", - "lightningcss-darwin-arm64": "1.31.1", - "lightningcss-darwin-x64": "1.31.1", - "lightningcss-freebsd-x64": "1.31.1", - "lightningcss-linux-arm-gnueabihf": "1.31.1", - "lightningcss-linux-arm64-gnu": "1.31.1", - "lightningcss-linux-arm64-musl": "1.31.1", - "lightningcss-linux-x64-gnu": "1.31.1", - "lightningcss-linux-x64-musl": "1.31.1", - "lightningcss-win32-arm64-msvc": "1.31.1", - "lightningcss-win32-x64-msvc": "1.31.1" + "lightningcss-android-arm64": "1.32.0", + "lightningcss-darwin-arm64": "1.32.0", + "lightningcss-darwin-x64": "1.32.0", + "lightningcss-freebsd-x64": "1.32.0", + "lightningcss-linux-arm-gnueabihf": "1.32.0", + "lightningcss-linux-arm64-gnu": "1.32.0", + "lightningcss-linux-arm64-musl": "1.32.0", + "lightningcss-linux-x64-gnu": "1.32.0", + "lightningcss-linux-x64-musl": "1.32.0", + "lightningcss-win32-arm64-msvc": "1.32.0", + "lightningcss-win32-x64-msvc": "1.32.0" } }, "node_modules/lightningcss-android-arm64": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.31.1.tgz", - "integrity": "sha512-HXJF3x8w9nQ4jbXRiNppBCqeZPIAfUo8zE/kOEGbW5NZvGc/K7nMxbhIr+YlFlHW5mpbg/YFPdbnCh1wAXCKFg==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz", + "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==", "cpu": [ "arm64" ], @@ -2022,9 +2022,9 @@ } }, "node_modules/lightningcss-darwin-arm64": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.31.1.tgz", - "integrity": "sha512-02uTEqf3vIfNMq3h/z2cJfcOXnQ0GRwQrkmPafhueLb2h7mqEidiCzkE4gBMEH65abHRiQvhdcQ+aP0D0g67sg==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz", + "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==", "cpu": [ "arm64" ], @@ -2043,9 +2043,9 @@ } }, "node_modules/lightningcss-darwin-x64": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.31.1.tgz", - "integrity": "sha512-1ObhyoCY+tGxtsz1lSx5NXCj3nirk0Y0kB/g8B8DT+sSx4G9djitg9ejFnjb3gJNWo7qXH4DIy2SUHvpoFwfTA==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz", + "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==", "cpu": [ "x64" ], @@ -2064,9 +2064,9 @@ } }, "node_modules/lightningcss-freebsd-x64": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.31.1.tgz", - "integrity": "sha512-1RINmQKAItO6ISxYgPwszQE1BrsVU5aB45ho6O42mu96UiZBxEXsuQ7cJW4zs4CEodPUioj/QrXW1r9pLUM74A==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz", + "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==", "cpu": [ "x64" ], @@ -2085,9 +2085,9 @@ } }, "node_modules/lightningcss-linux-arm-gnueabihf": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.31.1.tgz", - "integrity": "sha512-OOCm2//MZJ87CdDK62rZIu+aw9gBv4azMJuA8/KB74wmfS3lnC4yoPHm0uXZ/dvNNHmnZnB8XLAZzObeG0nS1g==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz", + "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==", "cpu": [ "arm" ], @@ -2106,9 +2106,9 @@ } }, "node_modules/lightningcss-linux-arm64-gnu": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.31.1.tgz", - "integrity": "sha512-WKyLWztD71rTnou4xAD5kQT+982wvca7E6QoLpoawZ1gP9JM0GJj4Tp5jMUh9B3AitHbRZ2/H3W5xQmdEOUlLg==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz", + "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==", "cpu": [ "arm64" ], @@ -2127,9 +2127,9 @@ } }, "node_modules/lightningcss-linux-arm64-musl": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.31.1.tgz", - "integrity": "sha512-mVZ7Pg2zIbe3XlNbZJdjs86YViQFoJSpc41CbVmKBPiGmC4YrfeOyz65ms2qpAobVd7WQsbW4PdsSJEMymyIMg==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz", + "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==", "cpu": [ "arm64" ], @@ -2168,9 +2168,9 @@ } }, "node_modules/lightningcss-linux-x64-musl": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.31.1.tgz", - "integrity": "sha512-eowF8PrKHw9LpoZii5tdZwnBcYDxRw2rRCyvAXLi34iyeYfqCQNA9rmUM0ce62NlPhCvof1+9ivRaTY6pSKDaA==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz", + "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==", "cpu": [ "x64" ], @@ -2189,9 +2189,9 @@ } }, "node_modules/lightningcss-win32-arm64-msvc": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.31.1.tgz", - "integrity": "sha512-aJReEbSEQzx1uBlQizAOBSjcmr9dCdL3XuC/6HLXAxmtErsj2ICo5yYggg1qOODQMtnjNQv2UHb9NpOuFtYe4w==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz", + "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==", "cpu": [ "arm64" ], @@ -2210,9 +2210,9 @@ } }, "node_modules/lightningcss-win32-x64-msvc": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.31.1.tgz", - "integrity": "sha512-I9aiFrbd7oYHwlnQDqr1Roz+fTz61oDDJX7n9tYF9FJymH1cIN1DtKw3iYt6b8WZgEjoNwVSncwF4wx/ZedMhw==", + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz", + "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==", "cpu": [ "x64" ], @@ -2230,27 +2230,6 @@ "url": "https://opencollective.com/parcel" } }, - "node_modules/lightningcss/node_modules/lightningcss-linux-x64-gnu": { - "version": "1.31.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.31.1.tgz", - "integrity": "sha512-xGlFWRMl+0KvUhgySdIaReQdB4FNudfUTARn7q0hh/V67PVGCs3ADFjw+6++kG1RNd0zdGRlEKa+T13/tQjPMA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, "node_modules/linguist-languages": { "version": "8.2.0", "resolved": "https://registry.npmjs.org/linguist-languages/-/linguist-languages-8.2.0.tgz", @@ -2544,9 +2523,9 @@ } }, "node_modules/prettier-plugin-blade": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/prettier-plugin-blade/-/prettier-plugin-blade-3.1.3.tgz", - "integrity": "sha512-liFmluY37zpuUxLQ1lAy+WU7TWjn3HdQFNy3Wg21srpqwUpks9JjmJSgUV241NnVthlWCYO7AVL5wjXRCh1U5A==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/prettier-plugin-blade/-/prettier-plugin-blade-3.1.4.tgz", + "integrity": "sha512-efthq1LOBckZe18xx9fjaESAKvG6l0l4IZqLT4LvFb0DuHdcMayD9O6S7IELGa7NnjAw34LcbEjT9SQ0/W9ErA==", "dev": true, "license": "MIT", "dependencies": { @@ -2693,9 +2672,9 @@ "license": "MIT" }, "node_modules/rollup": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.59.0.tgz", - "integrity": "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==", + "version": "4.59.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.59.1.tgz", + "integrity": "sha512-iZKH8BeoCwTCBTZBZWQQMreekd4mdomwdjIQ40GC1oZm6o+8PnNMIxFOiCsGMWeS8iDJ7KZcl7KwmKk/0HOQpA==", "dev": true, "license": "MIT", "dependencies": { @@ -2709,31 +2688,31 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.59.0", - "@rollup/rollup-android-arm64": "4.59.0", - "@rollup/rollup-darwin-arm64": "4.59.0", - "@rollup/rollup-darwin-x64": "4.59.0", - "@rollup/rollup-freebsd-arm64": "4.59.0", - "@rollup/rollup-freebsd-x64": "4.59.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.59.0", - "@rollup/rollup-linux-arm-musleabihf": "4.59.0", - "@rollup/rollup-linux-arm64-gnu": "4.59.0", - "@rollup/rollup-linux-arm64-musl": "4.59.0", - "@rollup/rollup-linux-loong64-gnu": "4.59.0", - "@rollup/rollup-linux-loong64-musl": "4.59.0", - "@rollup/rollup-linux-ppc64-gnu": "4.59.0", - "@rollup/rollup-linux-ppc64-musl": "4.59.0", - "@rollup/rollup-linux-riscv64-gnu": "4.59.0", - "@rollup/rollup-linux-riscv64-musl": "4.59.0", - "@rollup/rollup-linux-s390x-gnu": "4.59.0", - "@rollup/rollup-linux-x64-gnu": "4.59.0", - "@rollup/rollup-linux-x64-musl": "4.59.0", - "@rollup/rollup-openbsd-x64": "4.59.0", - "@rollup/rollup-openharmony-arm64": "4.59.0", - "@rollup/rollup-win32-arm64-msvc": "4.59.0", - "@rollup/rollup-win32-ia32-msvc": "4.59.0", - "@rollup/rollup-win32-x64-gnu": "4.59.0", - "@rollup/rollup-win32-x64-msvc": "4.59.0", + "@rollup/rollup-android-arm-eabi": "4.59.1", + "@rollup/rollup-android-arm64": "4.59.1", + "@rollup/rollup-darwin-arm64": "4.59.1", + "@rollup/rollup-darwin-x64": "4.59.1", + "@rollup/rollup-freebsd-arm64": "4.59.1", + "@rollup/rollup-freebsd-x64": "4.59.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.59.1", + "@rollup/rollup-linux-arm-musleabihf": "4.59.1", + "@rollup/rollup-linux-arm64-gnu": "4.59.1", + "@rollup/rollup-linux-arm64-musl": "4.59.1", + "@rollup/rollup-linux-loong64-gnu": "4.59.1", + "@rollup/rollup-linux-loong64-musl": "4.59.1", + "@rollup/rollup-linux-ppc64-gnu": "4.59.1", + "@rollup/rollup-linux-ppc64-musl": "4.59.1", + "@rollup/rollup-linux-riscv64-gnu": "4.59.1", + "@rollup/rollup-linux-riscv64-musl": "4.59.1", + "@rollup/rollup-linux-s390x-gnu": "4.59.1", + "@rollup/rollup-linux-x64-gnu": "4.59.1", + "@rollup/rollup-linux-x64-musl": "4.59.1", + "@rollup/rollup-openbsd-x64": "4.59.1", + "@rollup/rollup-openharmony-arm64": "4.59.1", + "@rollup/rollup-win32-arm64-msvc": "4.59.1", + "@rollup/rollup-win32-ia32-msvc": "4.59.1", + "@rollup/rollup-win32-x64-gnu": "4.59.1", + "@rollup/rollup-win32-x64-msvc": "4.59.1", "fsevents": "~2.3.2" } }, @@ -2873,9 +2852,9 @@ } }, "node_modules/tailwindcss": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.2.1.tgz", - "integrity": "sha512-/tBrSQ36vCleJkAOsy9kbNTgaxvGbyOamC30PRePTQe/o1MFwEKHQk4Cn7BNGaPtjp+PuUrByJehM1hgxfq4sw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.2.2.tgz", + "integrity": "sha512-KWBIxs1Xb6NoLdMVqhbhgwZf2PGBpPEiwOqgI4pFIYbNTfBXiKYyWoTsXgBQ9WFg/OlhnvHaY+AEpW7wSmFo2Q==", "dev": true, "license": "MIT", "peer": true @@ -3122,9 +3101,9 @@ } }, "node_modules/yaml": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.2.tgz", - "integrity": "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==", + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.3.tgz", + "integrity": "sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg==", "dev": true, "license": "ISC", "bin": { diff --git a/package.json b/package.json index 5791507a..734d3ec9 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "devDependencies": { "@prettier/plugin-php": "0.24.0", "@tailwindcss/typography": "0.5.19", - "@tailwindcss/vite": "4.2.1", + "@tailwindcss/vite": "4.2.2", "axios": "1.13.6", "concurrently": "9.2.1", "husky": "9.1.7", @@ -26,9 +26,9 @@ "lint-staged": "16.4.0", "npm-check-updates": "19.6.5", "prettier": "3.8.1", - "prettier-plugin-blade": "3.1.3", + "prettier-plugin-blade": "3.1.4", "prettier-plugin-tailwindcss": "0.7.2", - "tailwindcss": "4.2.1", + "tailwindcss": "4.2.2", "tw-animate-css": "1.4.0", "vite": "7.3.1" }, @@ -42,8 +42,8 @@ ] }, "optionalDependencies": { - "@rollup/rollup-linux-x64-gnu": "4.59.0", - "@tailwindcss/oxide-linux-x64-gnu": "4.2.1", + "@rollup/rollup-linux-x64-gnu": "4.59.1", + "@tailwindcss/oxide-linux-x64-gnu": "4.2.2", "lightningcss-linux-x64-gnu": "1.32.0" } } diff --git a/phpunit.xml b/phpunit.xml index f22394ea..457779ff 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -19,8 +19,12 @@ - - + + + + + +