diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8211ea4..8e47e28 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -34,7 +34,8 @@ DB_PASSWORD= Lalu jalankan: ```bash php artisan migrate --seed -php artisan shield:generate --panel=admin +php artisan shield:generate --panel=admin --all -n +php artisan db:seed --class=PermissionSeeder --force php artisan shield:super-admin --user=1 php artisan serve ``` diff --git a/README.md b/README.md index b418753..d545143 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@ Sistem web production-ready untuk **Organisasi Pemuda Desa Persegi**, berlokasi di Desa Karangdadap, Kecamatan Kalibagor, Kabupaten Banyumas. +**URL Production:** https://persegi.nyawiji.net + --- ## Teknologi @@ -14,7 +16,7 @@ Sistem web production-ready untuk **Organisasi Pemuda Desa Persegi**, berlokasi | Database | MySQL / MariaDB | | Frontend Publik | Blade + Tailwind CSS | | Realtime | Livewire | -| Queue | Supervisor | +| Queue | Supervisor (database driver) | --- @@ -24,33 +26,37 @@ Sistem web production-ready untuk **Organisasi Pemuda Desa Persegi**, berlokasi app/ ├── Filament/ │ ├── Resources/ -│ │ ├── Activities/ # Manajemen kegiatan -│ │ ├── Approvals/ # Multi-approval -│ │ ├── Audits/ # Audit internal -│ │ ├── CashCategories/ # Kategori kas -│ │ ├── CashRecords/ # Transaksi kas -│ │ ├── ContactMessages/# Pesan dari publik -│ │ ├── Divisions/ # Divisi organisasi -│ │ ├── Posts/ # Konten publik -│ │ ├── Users/ # Manajemen anggota -│ │ └── Votes/ # Sistem voting +│ │ ├── Activities/ # Manajemen kegiatan +│ │ ├── Approvals/ # Multi-approval +│ │ ├── Audits/ # Audit internal +│ │ ├── CashCategories/ # Kategori kas +│ │ ├── CashRecords/ # Transaksi kas +│ │ ├── ContactMessages/ # Pesan dari publik +│ │ ├── Divisions/ # Divisi organisasi +│ │ ├── MemberDues/ # Iuran anggota +│ │ ├── MemberPoints/ # Poin anggota +│ │ ├── Posts/ # Konten publik +│ │ ├── Users/ # Manajemen anggota +│ │ └── Votes/ # Sistem voting │ └── Widgets/ │ ├── StatsOverview.php # Widget dashboard utama │ ├── CashStatsWidget.php # Widget statistik kas │ └── ActivityLogWidget.php # Widget log aktivitas ├── Models/ -│ ├── User.php, Division.php, Activity.php +│ ├── User.php, Division.php +│ ├── Activity.php, MemberStatusLog.php, ActivityLog.php +│ ├── MemberDue.php, MemberPoint.php │ ├── CashRecord.php, CashCategory.php │ ├── Vote.php, VoteItem.php │ ├── Approval.php, ApprovalItem.php │ ├── Audit.php, AuditResponse.php -│ ├── MemberStatusLog.php, ActivityLog.php -│ ├── Post.php, ContactMessage.php +│ └── Post.php, ContactMessage.php └── Observers/ - ├── CashRecordObserver.php # Log + threshold approval/voting - ├── ActivityObserver.php # Log approval & eksekusi kegiatan ├── UserObserver.php # Log perubahan status anggota - └── VoteObserver.php # Notifikasi voting baru ke semua user + ├── ActivityObserver.php # Log approval & eksekusi kegiatan + ├── CashRecordObserver.php # Log + threshold approval/voting otomatis + ├── VoteObserver.php # Notifikasi voting baru ke semua user + └── PostObserver.php # Poin +5 saat artikel dipublish ``` --- @@ -59,12 +65,12 @@ app/ | Role | Deskripsi | |---|---| -| `super_admin` | Full akses, override semua, semua aksi di-log | +| `super_admin` | Full akses via gate, semua aksi di-log | | `ketua` | Approval kegiatan, verifikasi kas, lihat semua data | -| `bendahara` | Input & kelola transaksi kas | +| `bendahara` | Input & kelola transaksi kas dan iuran | | `pengurus` | Submit kegiatan ke pending | -| `anggota` | Akses terbatas, bisa voting | -| `auditor` | Read-only + bisa buat temuan audit | +| `anggota` | Akses terbatas, bisa voting dan buat artikel | +| `auditor` | Read-only semua + bisa buat temuan audit | --- @@ -82,7 +88,11 @@ Threshold otomatis saat transaksi dibuat: - Transaksi yang belum diverifikasi tidak masuk ke total kas - Setelah `verified_at` terisi, data terkunci (tidak bisa diubah/dihapus) -- Widget statistik kas tampil di halaman transaksi: total saldo, pemasukan/pengeluaran bulan ini, saldo bulan lalu + +### Iuran Anggota + +- Satu iuran per anggota per periode (format `YYYY-MM`) +- Unique constraint `(user_id, period)` mencegah duplikasi ### Kegiatan @@ -91,6 +101,8 @@ draft → pending → approved → (executed_at diisi) → rejected ``` +- Draft hanya terlihat oleh kreator dan `super_admin` + ### Voting - Semua user bisa melihat dan memberi suara @@ -98,6 +110,15 @@ draft → pending → approved → (executed_at diisi) - Notifikasi ke semua user saat voting baru dibuat - Mayoritas >50% untuk lolos +### Sistem Poin + +| Event | Poin | +|---|---| +| Hadir kegiatan | +10 | +| Artikel dipublish | +5 | + +- Duplikasi dicegah via `firstOrCreate` dengan key `(user_id, source_type, source_id)` + ### Notifikasi - Database notifications via Filament @@ -106,7 +127,7 @@ draft → pending → approved → (executed_at diisi) ### Konten Publik -- Website publik berbasis Blade (font: Roboto + Playfair Display) +- Website publik berbasis Blade - Artikel/berita, halaman kegiatan, form kontak - Link ke website publik tersedia di sidebar admin @@ -129,7 +150,8 @@ composer install cp .env.example .env php artisan key:generate php artisan migrate --seed -php artisan shield:generate --panel=admin +php artisan shield:generate --panel=admin --all -n +php artisan db:seed --class=PermissionSeeder --force php artisan shield:super-admin --user=1 ``` @@ -156,15 +178,12 @@ sudo supervisorctl start persegi-worker ### Production ```bash +php artisan migrate +php artisan shield:generate --panel=admin --all -n +php artisan db:seed --class=PermissionSeeder --force +php artisan permission:cache-reset +php artisan filament:optimize-clear +php artisan filament:optimize php artisan config:cache php artisan route:cache -php artisan view:cache -php artisan permission:cache-reset -php artisan filament:optimize ``` - ---- - -## Kontribusi - -Lihat [CONTRIBUTING.md](CONTRIBUTING.md) untuk panduan berkontribusi. diff --git a/app/Filament/Resources/CashCategories/Schemas/CashCategoryForm.php b/app/Filament/Resources/CashCategories/Schemas/CashCategoryForm.php index 905d519..c041fa6 100644 --- a/app/Filament/Resources/CashCategories/Schemas/CashCategoryForm.php +++ b/app/Filament/Resources/CashCategories/Schemas/CashCategoryForm.php @@ -2,6 +2,7 @@ namespace App\Filament\Resources\CashCategories\Schemas; +use Filament\Forms\Components\Select; use Filament\Forms\Components\TextInput; use Filament\Schemas\Schema; @@ -11,6 +12,9 @@ class CashCategoryForm { return $schema->components([ TextInput::make('name')->label('Nama')->required(), + Select::make('type')->label('Tipe') + ->options(['pemasukan' => 'Pemasukan', 'pengeluaran' => 'Pengeluaran']) + ->required(), ]); } } diff --git a/app/Filament/Resources/CashCategories/Tables/CashCategoriesTable.php b/app/Filament/Resources/CashCategories/Tables/CashCategoriesTable.php index 9c3dc78..a0a5842 100644 --- a/app/Filament/Resources/CashCategories/Tables/CashCategoriesTable.php +++ b/app/Filament/Resources/CashCategories/Tables/CashCategoriesTable.php @@ -15,6 +15,10 @@ class CashCategoriesTable return $table ->columns([ TextColumn::make('name')->label('Nama')->searchable(), + TextColumn::make('type')->label('Tipe') + ->badge() + ->color(fn ($state) => $state === 'pemasukan' ? 'success' : 'danger') + ->formatStateUsing(fn ($state) => ucfirst($state)), TextColumn::make('records_count')->counts('records')->label('Transaksi'), ]) ->recordActions([EditAction::make()]) diff --git a/app/Filament/Resources/CashRecords/Schemas/CashRecordForm.php b/app/Filament/Resources/CashRecords/Schemas/CashRecordForm.php index 184e96c..9efdb0a 100644 --- a/app/Filament/Resources/CashRecords/Schemas/CashRecordForm.php +++ b/app/Filament/Resources/CashRecords/Schemas/CashRecordForm.php @@ -16,7 +16,11 @@ class CashRecordForm { return $schema->components([ Select::make('category_id')->label('Kategori') - ->options(CashCategory::pluck('name', 'id')) + ->options( + CashCategory::all()->mapWithKeys(fn ($c) => [ + $c->id => $c->name . ' (' . ucfirst($c->type) . ')' + ]) + ) ->required(), TextInput::make('amount')->label('Jumlah (Rp)')->numeric()->required() ->helperText('< Rp500.000: langsung | Rp500.000–2.000.000: perlu approval ketua | > Rp2.000.000: perlu voting') diff --git a/app/Filament/Resources/CashRecords/Tables/CashRecordsTable.php b/app/Filament/Resources/CashRecords/Tables/CashRecordsTable.php index e4d80b1..4500755 100644 --- a/app/Filament/Resources/CashRecords/Tables/CashRecordsTable.php +++ b/app/Filament/Resources/CashRecords/Tables/CashRecordsTable.php @@ -58,6 +58,11 @@ class CashRecordsTable ->filters([ SelectFilter::make('category_id')->label('Kategori') ->options(CashCategory::pluck('name', 'id')), + SelectFilter::make('type')->label('Tipe') + ->options(['pemasukan' => 'Pemasukan', 'pengeluaran' => 'Pengeluaran']) + ->query(fn ($query, $state) => $state['value'] + ? $query->whereHas('category', fn ($q) => $q->where('type', $state['value'])) + : $query), ]) ->recordActions([ // Ketua: approve transaksi 500rb–2jt diff --git a/app/Filament/Resources/Posts/PostResource.php b/app/Filament/Resources/Posts/PostResource.php index 149e824..c5bcc67 100644 --- a/app/Filament/Resources/Posts/PostResource.php +++ b/app/Filament/Resources/Posts/PostResource.php @@ -23,7 +23,7 @@ class PostResource extends Resource // Label dinamis sesuai role public static function getModelLabel(): string { - return auth()->user()?->can('ViewAny:Post') && auth()->user()?->can('Update:Post') + return auth()->user()?->can('Publish:Post') ? 'Artikel' : 'Artikel Saya'; } @@ -32,7 +32,7 @@ class PostResource extends Resource { $query = parent::getEloquentQuery(); - if (auth()->user()?->can('Update:Post')) { + if (auth()->user()?->can('Publish:Post')) { return $query; } diff --git a/app/Filament/Resources/Posts/Schemas/PostForm.php b/app/Filament/Resources/Posts/Schemas/PostForm.php index 07fd8fd..12421e0 100644 --- a/app/Filament/Resources/Posts/Schemas/PostForm.php +++ b/app/Filament/Resources/Posts/Schemas/PostForm.php @@ -13,7 +13,7 @@ class PostForm { public static function configure(Schema $schema): Schema { - $isAdmin = auth()->user()?->can('Update:Post'); + $canReview = auth()->user()?->can('Publish:Post'); return $schema->components([ TextInput::make('title')->label('Judul')->required() @@ -28,7 +28,7 @@ class PostForm ]) ->default('umum')->required(), DateTimePicker::make('published_at')->label('Tanggal Publikasi') - ->visible($isAdmin) + ->visible($canReview) ->helperText('Kosongkan untuk menyimpan sebagai draft'), RichEditor::make('content')->label('Konten')->required()->columnSpanFull(), ]); diff --git a/app/Filament/Resources/Posts/Tables/PostsTable.php b/app/Filament/Resources/Posts/Tables/PostsTable.php index c346a4d..674c049 100644 --- a/app/Filament/Resources/Posts/Tables/PostsTable.php +++ b/app/Filament/Resources/Posts/Tables/PostsTable.php @@ -7,6 +7,7 @@ use Filament\Actions\Action; use Filament\Actions\BulkActionGroup; use Filament\Actions\DeleteBulkAction; use Filament\Actions\EditAction; +use Filament\Forms\Components\DateTimePicker; use Filament\Forms\Components\Textarea; use Filament\Tables\Columns\TextColumn; use Filament\Tables\Filters\SelectFilter; @@ -16,7 +17,8 @@ class PostsTable { public static function configure(Table $table): Table { - $isAdmin = auth()->user()?->can('Update:Post'); + $canReview = auth()->user()?->can('Publish:Post'); + $canPublish = auth()->user()?->can('Publish:Post'); return $table ->columns([ @@ -30,68 +32,74 @@ class PostsTable TextColumn::make('status')->badge() ->color(fn ($state) => match ($state) { 'published' => 'success', + 'approved' => 'info', 'pending' => 'warning', 'rejected' => 'danger', default => 'gray', + }) + ->formatStateUsing(fn ($state) => match ($state) { + 'draft' => 'Draft', + 'pending' => 'Menunggu', + 'approved' => 'Disetujui', + 'published' => 'Diterbitkan', + 'rejected' => 'Ditolak', + default => $state, }), - TextColumn::make('author.name')->label('Penulis')->visible($isAdmin), - TextColumn::make('rejection_reason')->label('Alasan Penolakan') - ->limit(40)->default('-') - ->visible(fn ($record) => $record?->status === 'rejected'), + TextColumn::make('author.name')->label('Penulis')->visible($canReview), TextColumn::make('published_at')->label('Dipublikasi') - ->dateTime('d M Y')->default('-')->sortable(), + ->dateTime('d M Y')->placeholder('-')->sortable(), ]) ->filters([ SelectFilter::make('status')->options([ 'draft' => 'Draft', 'pending' => 'Menunggu', + 'approved' => 'Disetujui', 'published' => 'Diterbitkan', 'rejected' => 'Ditolak', ]), ]) ->recordActions([ - // Untuk anggota/pengurus/bendahara: ajukan artikel + // Member: ajukan artikel Action::make('submit') ->label('Ajukan') ->icon('heroicon-o-paper-airplane') ->color('info') ->requiresConfirmation() - ->visible(fn ($record) => ! $isAdmin && in_array($record->status, ['draft', 'rejected'])) + ->visible(fn ($record) => ! $canReview && in_array($record->status, ['draft', 'rejected'])) ->action(function ($record): void { $record->update(['status' => 'pending', 'rejection_reason' => null]); - NotificationService::toRole('ketua', 'Artikel Menunggu Persetujuan', + NotificationService::toRole('editor', 'Artikel Menunggu Persetujuan', "\"{$record->title}\" oleh {$record->author->name} menunggu persetujuan.", 'warning', route('filament.admin.resources.posts.edit', $record)); }), - // Untuk admin: approve - Action::make('publish') - ->label('Terbitkan') + // Editor: approve + Action::make('approve') + ->label('Setujui') ->icon('heroicon-o-check-circle') ->color('success') ->requiresConfirmation() - ->visible(fn ($record) => $isAdmin && $record->status === 'pending') + ->visible(fn ($record) => $canReview && $record->status === 'pending') ->action(fn ($record) => tap($record->update([ - 'status' => 'published', - 'published_at' => now(), - 'reviewed_by' => auth()->id(), + 'status' => 'approved', + 'approved_by' => auth()->id(), + 'approved_at' => now(), + 'reviewed_by' => auth()->id(), ]), fn () => NotificationService::send( - $record->author, 'Artikel Diterbitkan', - "Artikel \"{$record->title}\" Anda telah diterbitkan.", 'success', + $record->author, 'Artikel Disetujui', + "Artikel \"{$record->title}\" Anda telah disetujui dan akan segera diterbitkan.", 'success', route('filament.admin.resources.posts.edit', $record) ))), - // Untuk admin: tolak + // Editor: tolak Action::make('reject') ->label('Tolak') ->icon('heroicon-o-x-circle') ->color('danger') - ->visible(fn ($record) => $isAdmin && $record->status === 'pending') - ->form([ - Textarea::make('rejection_reason')->label('Alasan Penolakan')->required(), - ]) + ->visible(fn ($record) => $canReview && $record->status === 'pending') + ->form([Textarea::make('rejection_reason')->label('Alasan Penolakan')->required()]) ->action(fn ($record, array $data) => tap($record->update([ - 'status' => 'rejected', + 'status' => 'draft', 'reviewed_by' => auth()->id(), 'rejection_reason' => $data['rejection_reason'], ]), fn () => NotificationService::send( @@ -100,8 +108,35 @@ class PostsTable route('filament.admin.resources.posts.edit', $record) ))), + // Editor: publish (approved → published) + Action::make('publish') + ->label('Terbitkan') + ->icon('heroicon-o-globe-alt') + ->color('success') + ->visible(fn ($record) => $canPublish && $record->status === 'approved') + ->form([ + DateTimePicker::make('published_at')->label('Tanggal Publikasi') + ->default(now())->required(), + ]) + ->action(fn ($record, array $data) => $record->update([ + 'status' => 'published', + 'published_at' => $data['published_at'], + ])), + + // Editor: unpublish + Action::make('unpublish') + ->label('Batalkan Publikasi') + ->icon('heroicon-o-eye-slash') + ->color('warning') + ->requiresConfirmation() + ->visible(fn ($record) => $canPublish && $record->status === 'published') + ->action(fn ($record) => $record->update([ + 'status' => 'approved', + 'published_at' => null, + ])), + EditAction::make() - ->visible(fn ($record) => $isAdmin || in_array($record->status, ['draft', 'rejected'])), + ->visible(fn ($record) => $canReview || in_array($record->status, ['draft', 'rejected'])), ]) ->toolbarActions([BulkActionGroup::make([DeleteBulkAction::make()])]); } diff --git a/app/Filament/Resources/Users/RelationManagers/AttendanceRelationManager.php b/app/Filament/Resources/Users/RelationManagers/AttendanceRelationManager.php new file mode 100644 index 0000000..5055875 --- /dev/null +++ b/app/Filament/Resources/Users/RelationManagers/AttendanceRelationManager.php @@ -0,0 +1,34 @@ +columns([ + TextColumn::make('title')->label('Kegiatan'), + TextColumn::make('start_date')->label('Tanggal')->date('d M Y')->sortable(), + TextColumn::make('pivot.status')->label('Status') + ->badge() + ->color(fn ($state) => match ($state) { + 'hadir' => 'success', + 'izin' => 'warning', + 'alpha' => 'danger', + default => 'gray', + }) + ->formatStateUsing(fn ($state) => ucfirst($state ?? '-')), + TextColumn::make('pivot.notes')->label('Catatan')->placeholder('-'), + ]) + ->defaultSort('activities.start_date', 'desc') + ->paginated([10, 25]); + } +} diff --git a/app/Filament/Resources/Users/UserResource.php b/app/Filament/Resources/Users/UserResource.php index e292c6c..7da799e 100644 --- a/app/Filament/Resources/Users/UserResource.php +++ b/app/Filament/Resources/Users/UserResource.php @@ -5,6 +5,7 @@ namespace App\Filament\Resources\Users; use App\Filament\Resources\Users\Pages\CreateUser; use App\Filament\Resources\Users\Pages\EditUser; use App\Filament\Resources\Users\Pages\ListUsers; +use App\Filament\Resources\Users\RelationManagers\AttendanceRelationManager; use App\Filament\Resources\Users\Schemas\UserForm; use App\Filament\Resources\Users\Tables\UsersTable; use App\Models\User; @@ -30,6 +31,13 @@ class UserResource extends Resource return UsersTable::configure($table); } + public static function getRelations(): array + { + return [ + AttendanceRelationManager::class, + ]; + } + public static function getPages(): array { return [ diff --git a/app/Filament/Widgets/CashStatsWidget.php b/app/Filament/Widgets/CashStatsWidget.php index 2c608ac..0516c3f 100644 --- a/app/Filament/Widgets/CashStatsWidget.php +++ b/app/Filament/Widgets/CashStatsWidget.php @@ -21,7 +21,7 @@ class CashStatsWidget extends StatsOverviewWidget $saldo = fn ($query) => $query ->whereNotNull('verified_at') ->join('cash_categories', 'cash_records.category_id', '=', 'cash_categories.id') - ->selectRaw("SUM(CASE WHEN cash_categories.name = 'pemasukan' THEN amount ELSE -amount END) as saldo") + ->selectRaw("SUM(CASE WHEN cash_categories.type = 'pemasukan' THEN amount ELSE -amount END) as saldo") ->value('saldo') ?? 0; $bulanIni = now()->startOfMonth(); @@ -30,12 +30,12 @@ class CashStatsWidget extends StatsOverviewWidget $totalSaldo = $saldo(CashRecord::query()); $pemasukanBulanIni = CashRecord::whereNotNull('verified_at') ->join('cash_categories', 'cash_records.category_id', '=', 'cash_categories.id') - ->where('cash_categories.name', 'pemasukan') + ->where('cash_categories.type', 'pemasukan') ->whereMonth('date', $bulanIni->month)->whereYear('date', $bulanIni->year) ->sum('amount'); $pengeluaranBulanIni = CashRecord::whereNotNull('verified_at') ->join('cash_categories', 'cash_records.category_id', '=', 'cash_categories.id') - ->where('cash_categories.name', 'pengeluaran') + ->where('cash_categories.type', 'pengeluaran') ->whereMonth('date', $bulanIni->month)->whereYear('date', $bulanIni->year) ->sum('amount'); $saldoBulanLalu = $saldo(CashRecord::query()->where('date', '<', $bulanIni)); diff --git a/app/Filament/Widgets/LeaderboardWidget.php b/app/Filament/Widgets/LeaderboardWidget.php new file mode 100644 index 0000000..105cbbf --- /dev/null +++ b/app/Filament/Widgets/LeaderboardWidget.php @@ -0,0 +1,40 @@ +user_id); + } + + public function table(Table $table): Table + { + return $table + ->query( + MemberPoint::query() + ->selectRaw('user_id, SUM(points) as total_points') + ->groupBy('user_id') + ->orderByDesc('total_points') + ->limit(10) + ->with('user') + ) + ->columns([ + TextColumn::make('user.name')->label('Anggota'), + TextColumn::make('total_points')->label('Total Poin') + ->badge()->color('success'), + ]) + ->paginated(false); + } +} diff --git a/app/Filament/Widgets/StatsOverview.php b/app/Filament/Widgets/StatsOverview.php index f60b3de..4454e53 100644 --- a/app/Filament/Widgets/StatsOverview.php +++ b/app/Filament/Widgets/StatsOverview.php @@ -14,7 +14,7 @@ class StatsOverview extends StatsOverviewWidget { $totalKas = CashRecord::whereNotNull('verified_at') ->join('cash_categories', 'cash_records.category_id', '=', 'cash_categories.id') - ->selectRaw("SUM(CASE WHEN cash_categories.name = 'pemasukan' THEN amount ELSE -amount END) as saldo") + ->selectRaw("SUM(CASE WHEN cash_categories.type = 'pemasukan' THEN amount ELSE -amount END) as saldo") ->value('saldo') ?? 0; return [ diff --git a/app/Http/Controllers/PublicController.php b/app/Http/Controllers/PublicController.php index daec1f1..460272b 100644 --- a/app/Http/Controllers/PublicController.php +++ b/app/Http/Controllers/PublicController.php @@ -51,6 +51,13 @@ class PublicController extends Controller ]); } + public function blogDetail(Post $post) + { + abort_if($post->status !== 'published' || ! $post->published_at, 404); + + return view('public.blog-detail', compact('post')); + } + public function kontak() { return view('public.kontak'); diff --git a/app/Models/CashCategory.php b/app/Models/CashCategory.php index 97d4276..5193b0f 100644 --- a/app/Models/CashCategory.php +++ b/app/Models/CashCategory.php @@ -7,7 +7,7 @@ use Illuminate\Database\Eloquent\Relations\HasMany; class CashCategory extends Model { - protected $fillable = ['name']; + protected $fillable = ['name', 'type']; public function records(): HasMany { diff --git a/app/Models/Post.php b/app/Models/Post.php index dc874e6..074f645 100644 --- a/app/Models/Post.php +++ b/app/Models/Post.php @@ -8,9 +8,9 @@ use Illuminate\Support\Str; class Post extends Model { - protected $fillable = ['title', 'slug', 'category', 'content', 'author_id', 'published_at', 'status', 'reviewed_by', 'rejection_reason']; + protected $fillable = ['title', 'slug', 'category', 'content', 'author_id', 'published_at', 'status', 'reviewed_by', 'rejection_reason', 'approved_by', 'approved_at']; - protected $casts = ['published_at' => 'datetime']; + protected $casts = ['published_at' => 'datetime', 'approved_at' => 'datetime']; protected static function booted(): void { @@ -30,6 +30,11 @@ class Post extends Model return $this->belongsTo(User::class, 'reviewed_by'); } + public function approver(): BelongsTo + { + return $this->belongsTo(User::class, 'approved_by'); + } + public function scopePublished($query) { return $query->where('status', 'published') diff --git a/app/Observers/PostObserver.php b/app/Observers/PostObserver.php index 96c6b8b..55d1fe1 100644 --- a/app/Observers/PostObserver.php +++ b/app/Observers/PostObserver.php @@ -9,14 +9,18 @@ class PostObserver { public function updated(Post $post): void { - if ($post->wasChanged('status') && $post->status === 'published') { - MemberPoint::create([ - 'user_id' => $post->author_id, - 'points' => 5, - 'reason' => "Artikel dipublikasi: {$post->title}", - 'source_type' => 'post', - 'source_id' => $post->id, - ]); + if ($post->wasChanged('status') && $post->status === 'approved') { + MemberPoint::firstOrCreate( + [ + 'user_id' => $post->author_id, + 'source_type' => Post::class, + 'source_id' => $post->id, + ], + [ + 'points' => 5, + 'reason' => "Artikel disetujui: {$post->title}", + ] + ); } } } diff --git a/app/Observers/UserObserver.php b/app/Observers/UserObserver.php index dd54f82..f224712 100644 --- a/app/Observers/UserObserver.php +++ b/app/Observers/UserObserver.php @@ -41,6 +41,11 @@ class UserObserver public function created(User $user): void { + // Auto-assign role anggota jika belum punya role + if ($user->roles->isEmpty()) { + $user->assignRole('anggota'); + } + ActivityLog::create([ 'user_id' => Auth::id(), 'action' => 'created', diff --git a/app/Providers/Filament/AdminPanelProvider.php b/app/Providers/Filament/AdminPanelProvider.php index d3047c5..c81556a 100644 --- a/app/Providers/Filament/AdminPanelProvider.php +++ b/app/Providers/Filament/AdminPanelProvider.php @@ -27,8 +27,11 @@ class AdminPanelProvider extends PanelProvider { return $panel ->default() + ->brandLogo(asset('images/logo.png')) + ->brandLogoHeight('2rem') ->id('admin') ->path('dashboard') + ->viteTheme('resources/css/filament/admin/theme.css') ->login() ->colors([ 'primary' => Color::Amber, @@ -59,6 +62,7 @@ class AdminPanelProvider extends PanelProvider AccountWidget::class, \App\Filament\Widgets\StatsOverview::class, \App\Filament\Widgets\ActivityLogWidget::class, + \App\Filament\Widgets\LeaderboardWidget::class, ]) ->middleware([ EncryptCookies::class, diff --git a/config/filament-shield.php b/config/filament-shield.php index c287e7e..9e7c472 100644 --- a/config/filament-shield.php +++ b/config/filament-shield.php @@ -234,6 +234,7 @@ return [ 'custom_permissions' => [ 'ViewDraft:Activity', // Lihat kegiatan berstatus draft milik user lain (hanya super_admin) + 'Publish:Post', // Publish / unpublish artikel (editor) ], /* diff --git a/database/migrations/2026_04_02_205141_create_cash_categories_table.php b/database/migrations/2026_04_02_205141_create_cash_categories_table.php index e52e660..ed76f36 100644 --- a/database/migrations/2026_04_02_205141_create_cash_categories_table.php +++ b/database/migrations/2026_04_02_205141_create_cash_categories_table.php @@ -10,7 +10,7 @@ return new class extends Migration { Schema::create('cash_categories', function (Blueprint $table) { $table->id(); - $table->string('name'); // pemasukan / pengeluaran + $table->string('name'); // nama bebas, tipe dikontrol via kolom type $table->timestamps(); }); } diff --git a/database/migrations/2026_04_04_085853_add_type_to_cash_categories_table.php b/database/migrations/2026_04_04_085853_add_type_to_cash_categories_table.php new file mode 100644 index 0000000..630bec9 --- /dev/null +++ b/database/migrations/2026_04_04_085853_add_type_to_cash_categories_table.php @@ -0,0 +1,26 @@ +enum('type', ['pemasukan', 'pengeluaran'])->after('name')->default('pemasukan'); + }); + + // Migrate existing data + DB::table('cash_categories')->where('name', 'pengeluaran')->update(['type' => 'pengeluaran']); + DB::table('cash_categories')->where('name', '!=', 'pengeluaran')->update(['type' => 'pemasukan']); + } + + public function down(): void + { + Schema::table('cash_categories', function (Blueprint $table) { + $table->dropColumn('type'); + }); + } +}; diff --git a/database/migrations/2026_04_04_114836_add_approved_fields_to_posts_table.php b/database/migrations/2026_04_04_114836_add_approved_fields_to_posts_table.php new file mode 100644 index 0000000..179a8e9 --- /dev/null +++ b/database/migrations/2026_04_04_114836_add_approved_fields_to_posts_table.php @@ -0,0 +1,30 @@ +enum('status', ['draft', 'pending', 'approved', 'published', 'rejected']) + ->default('draft')->change(); + + $table->foreignId('approved_by')->nullable()->constrained('users')->after('reviewed_by'); + $table->timestamp('approved_at')->nullable()->after('approved_by'); + }); + } + + public function down(): void + { + Schema::table('posts', function (Blueprint $table) { + $table->dropForeign(['approved_by']); + $table->dropColumn(['approved_by', 'approved_at']); + $table->enum('status', ['draft', 'pending', 'published', 'rejected']) + ->default('draft')->change(); + }); + } +}; diff --git a/database/seeders/ActivitySeeder.php b/database/seeders/ActivitySeeder.php index 189f51c..3e53267 100644 --- a/database/seeders/ActivitySeeder.php +++ b/database/seeders/ActivitySeeder.php @@ -47,11 +47,16 @@ class ActivitySeeder extends Seeder foreach ($activities as $data) { $activity = Activity::create(array_merge($data, ['created_by' => $pengurus?->id])); - // Attach peserta dengan status kehadiran - $syncData = $anggota->mapWithKeys(fn ($user) => [ - $user->id => ['status' => 'hadir', 'notes' => null] - ])->toArray(); - $activity->participants()->sync($syncData); + // Hanya kegiatan yang sudah executed yang punya data kehadiran + if (! empty($data['executed_at'])) { + $syncData = $anggota->mapWithKeys(fn ($user, $i) => [ + $user->id => [ + 'status' => $i % 4 === 0 ? 'izin' : 'hadir', + 'notes' => null, + ] + ])->toArray(); + $activity->participants()->sync($syncData); + } } } } diff --git a/database/seeders/CashSeeder.php b/database/seeders/CashSeeder.php index cb08603..d909eb2 100644 --- a/database/seeders/CashSeeder.php +++ b/database/seeders/CashSeeder.php @@ -2,6 +2,7 @@ namespace Database\Seeders; +use App\Models\Approval; use App\Models\CashCategory; use App\Models\CashRecord; use App\Models\User; @@ -11,8 +12,8 @@ class CashSeeder extends Seeder { public function run(): void { - $pemasukan = CashCategory::firstOrCreate(['name' => 'pemasukan']); - $pengeluaran = CashCategory::firstOrCreate(['name' => 'pengeluaran']); + $pemasukan = CashCategory::firstOrCreate(['name' => 'Iuran & Donasi'], ['type' => 'pemasukan']); + $pengeluaran = CashCategory::firstOrCreate(['name' => 'Operasional'], ['type' => 'pengeluaran']); $bendahara = User::role('bendahara')->first(); $ketua = User::role('ketua')->first(); @@ -26,11 +27,30 @@ class CashSeeder extends Seeder ]; foreach ($records as $data) { - CashRecord::create(array_merge($data, [ - 'created_by' => $bendahara?->id, - 'verified_by' => $ketua?->id, - 'verified_at' => now()->subDays(1), - ])); + $amount = $data['amount']; + + // 500rb–2jt: butuh approval ketua, belum verified + if ($amount >= 500_000 && $amount <= 2_000_000) { + $record = CashRecord::create(array_merge($data, [ + 'created_by' => $bendahara?->id, + 'verified_by' => null, + 'verified_at' => null, + ])); + + Approval::create([ + 'model_type' => CashRecord::class, + 'model_id' => $record->id, + 'required_approvals' => 1, + 'status' => 'pending', + ]); + } else { + // < 500rb: langsung verified + CashRecord::create(array_merge($data, [ + 'created_by' => $bendahara?->id, + 'verified_by' => $ketua?->id, + 'verified_at' => now()->subDays(1), + ])); + } } } } diff --git a/database/seeders/ContactMessageSeeder.php b/database/seeders/ContactMessageSeeder.php new file mode 100644 index 0000000..0c9a209 --- /dev/null +++ b/database/seeders/ContactMessageSeeder.php @@ -0,0 +1,27 @@ + 'Budi Santoso', 'email' => 'budi@example.com', 'phone' => '08123456789', 'subject' => 'Pendaftaran anggota baru', 'message' => 'Saya ingin bergabung dengan organisasi Persegi. Bagaimana cara mendaftarnya?'], + ['name' => 'Siti Rahayu', 'email' => null, 'phone' => '08987654321', 'subject' => 'Informasi kegiatan kerja bakti', 'message' => 'Apakah masyarakat umum boleh ikut kegiatan kerja bakti yang akan datang?'], + ['name' => 'Ahmad Fauzi', 'email' => 'ahmad@example.com', 'phone' => null, 'subject' => 'Donasi untuk kegiatan', 'message' => 'Saya ingin berdonasi untuk mendukung kegiatan. Kemana saya bisa menghubungi bendahara?'], + ['name' => 'Dewi Lestari', 'email' => 'dewi@example.com', 'phone' => '08111222333', 'subject' => 'Jadwal rapat bulanan', 'message' => 'Kapan jadwal rapat bulanan berikutnya? Saya ingin hadir sebagai tamu.'], + ['name' => 'Hendra Wijaya', 'email' => null, 'phone' => '08555666777', 'subject' => 'Laporan kerusakan fasilitas desa', 'message' => 'Ada lampu jalan yang mati di RT 03. Apakah Persegi bisa membantu melaporkan ke desa?'], + ['name' => 'Rina Kusuma', 'email' => 'rina@example.com', 'phone' => '08222333444', 'subject' => 'Kerjasama kegiatan sosial', 'message' => 'Kami dari karang taruna RT 05 ingin mengajak kerjasama untuk kegiatan sosial bulan depan.'], + ['name' => 'Joko Pramono', 'email' => null, 'phone' => '08444555666', 'subject' => 'Pertanyaan iuran anggota', 'message' => 'Berapa besaran iuran bulanan anggota Persegi? Saya tertarik untuk bergabung.'], + ['name' => 'Nurul Hidayah', 'email' => 'nurul@example.com', 'phone' => '08777888999', 'subject' => 'Saran program kerja', 'message' => 'Saya punya usulan program pelatihan digital untuk pemuda desa. Bagaimana cara menyampaikannya?'], + ]; + + foreach ($messages as $data) { + ContactMessage::create($data); + } + } +} diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index b26a65d..8120973 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -18,6 +18,8 @@ class DatabaseSeeder extends Seeder VoteSeeder::class, PostSeeder::class, AuditSeeder::class, + MemberDueSeeder::class, + ContactMessageSeeder::class, MemberPointSeeder::class, ]); } diff --git a/database/seeders/MemberDueSeeder.php b/database/seeders/MemberDueSeeder.php new file mode 100644 index 0000000..14b661e --- /dev/null +++ b/database/seeders/MemberDueSeeder.php @@ -0,0 +1,38 @@ +first(); + + $members = User::whereDoesntHave('roles', fn ($q) => $q->whereIn('name', ['super_admin', 'bendahara'])) + ->get(); + + $periods = [ + now()->subMonths(3)->format('Y-m'), + now()->subMonths(2)->format('Y-m'), + now()->subMonth()->format('Y-m'), + now()->format('Y-m'), + ]; + + foreach ($members as $i => $user) { + foreach ($periods as $j => $period) { + MemberDue::firstOrCreate( + ['user_id' => $user->id, 'period' => $period], + [ + 'amount' => 10000, + 'status' => ($i + $j) % 3 === 0 ? 'belum' : 'lunas', + 'created_by' => $bendahara?->id, + ] + ); + } + } + } +} diff --git a/database/seeders/MemberPointSeeder.php b/database/seeders/MemberPointSeeder.php index 1268bdb..ab6709d 100644 --- a/database/seeders/MemberPointSeeder.php +++ b/database/seeders/MemberPointSeeder.php @@ -16,17 +16,17 @@ class MemberPointSeeder extends Seeder Activity::whereNotNull('executed_at')->each(function ($activity) { $activity->participants()->wherePivot('status', 'hadir')->each(function ($user) use ($activity) { MemberPoint::firstOrCreate( - ['user_id' => $user->id, 'source_type' => 'activity', 'source_id' => $activity->id], + ['user_id' => $user->id, 'source_type' => Activity::class, 'source_id' => $activity->id], ['points' => 10, 'reason' => "Hadir di kegiatan: {$activity->title}"] ); }); }); - // Poin dari artikel yang sudah published - Post::where('status', 'published')->each(function ($post) { + // Poin dari artikel yang sudah approved + Post::where('status', 'approved')->orWhere('status', 'published')->each(function ($post) { MemberPoint::firstOrCreate( - ['user_id' => $post->author_id, 'source_type' => 'post', 'source_id' => $post->id], - ['points' => 5, 'reason' => "Artikel dipublikasi: {$post->title}"] + ['user_id' => $post->author_id, 'source_type' => Post::class, 'source_id' => $post->id], + ['points' => 5, 'reason' => "Artikel disetujui: {$post->title}"] ); }); } diff --git a/database/seeders/PermissionSeeder.php b/database/seeders/PermissionSeeder.php index b76deac..abef586 100644 --- a/database/seeders/PermissionSeeder.php +++ b/database/seeders/PermissionSeeder.php @@ -13,7 +13,7 @@ class PermissionSeeder extends Seeder app()[\Spatie\Permission\PermissionRegistrar::class]->forgetCachedPermissions(); // Buat roles jika belum ada - foreach (['super_admin', 'ketua', 'bendahara', 'pengurus', 'anggota', 'auditor'] as $role) { + foreach (['super_admin', 'ketua', 'bendahara', 'pengurus', 'anggota', 'auditor', 'editor'] as $role) { Role::firstOrCreate(['name' => $role, 'guard_name' => 'web']); } @@ -28,6 +28,7 @@ class PermissionSeeder extends Seeder $pengurus = Role::findByName('pengurus'); $anggota = Role::findByName('anggota'); $auditor = Role::findByName('auditor'); + $editor = Role::findByName('editor'); $ketua->syncPermissions(Permission::where('name', 'not like', '%Role%') ->where('name', 'not like', '%Permission%') @@ -63,5 +64,11 @@ class PermissionSeeder extends Seeder ->orWhere('name', 'like', 'View:%') ->orWhere('name', 'like', '%Audit%') ->get()); + + $editor->syncPermissions(Permission::whereIn('name', [ + 'ViewAny:Post', 'View:Post', 'Create:Post', 'Update:Post', 'Delete:Post', + 'DeleteAny:Post', 'ViewAny:Activity', 'View:Activity', + 'Publish:Post', + ])->get()); } } diff --git a/database/seeders/PostSeeder.php b/database/seeders/PostSeeder.php index bbb5010..b114b31 100644 --- a/database/seeders/PostSeeder.php +++ b/database/seeders/PostSeeder.php @@ -5,38 +5,87 @@ namespace Database\Seeders; use App\Models\Post; use App\Models\User; use Illuminate\Database\Seeder; +use Illuminate\Support\Str; class PostSeeder extends Seeder { public function run(): void { - $author = User::role('ketua')->first() ?? User::first(); + $editor = User::role('editor')->first(); + $anggota = User::role('anggota')->first(); + $ketua = User::role('ketua')->first(); $posts = [ + // Published — sudah melalui full workflow [ 'title' => 'Selamat Datang di Website Persegi', 'category' => 'pengumuman', 'content' => '

Kami dengan bangga mempersembahkan website resmi organisasi Persegi. Melalui website ini, masyarakat dapat mengikuti perkembangan kegiatan dan informasi terbaru dari organisasi kami.

', + 'author_id' => $ketua?->id, + 'status' => 'published', + 'approved_by' => $editor?->id, + 'approved_at' => now()->subDays(11), + 'reviewed_by' => $editor?->id, 'published_at' => now()->subDays(10), ], [ 'title' => 'Rekrutmen Anggota Baru 2026', 'category' => 'pengumuman', 'content' => '

Persegi membuka pendaftaran anggota baru untuk periode 2026. Bagi pemuda Desa Karangdadap yang ingin bergabung, silakan hubungi pengurus melalui kontak yang tersedia.

Pendaftaran dibuka hingga akhir bulan April 2026.

', + 'author_id' => $ketua?->id, + 'status' => 'published', + 'approved_by' => $editor?->id, + 'approved_at' => now()->subDays(6), + 'reviewed_by' => $editor?->id, 'published_at' => now()->subDays(5), ], [ 'title' => 'Laporan Kegiatan Kerja Bakti Desa', 'category' => 'berita', 'content' => '

Kegiatan kerja bakti yang dilaksanakan pada bulan lalu berjalan dengan lancar. Sebanyak 30 anggota turut berpartisipasi dalam membersihkan lingkungan desa.

Terima kasih kepada seluruh anggota yang telah berkontribusi.

', + 'author_id' => $anggota?->id, + 'status' => 'published', + 'approved_by' => $editor?->id, + 'approved_at' => now()->subDays(3), + 'reviewed_by' => $editor?->id, 'published_at' => now()->subDays(2), ], + // Approved — sudah disetujui editor, belum diterbitkan + [ + 'title' => 'Jadwal Rapat Bulanan April 2026', + 'category' => 'pengumuman', + 'content' => '

Rapat bulanan akan dilaksanakan pada akhir April 2026. Seluruh anggota diharapkan hadir.

', + 'author_id' => $anggota?->id, + 'status' => 'approved', + 'approved_by' => $editor?->id, + 'approved_at' => now()->subDay(), + 'reviewed_by' => $editor?->id, + 'published_at' => null, + ], + // Pending — menunggu review editor + [ + 'title' => 'Kegiatan Sosial Ramadan 2026', + 'category' => 'berita', + 'content' => '

Persegi berencana mengadakan kegiatan sosial berbagi sembako selama bulan Ramadan.

', + 'author_id' => $anggota?->id, + 'status' => 'pending', + 'published_at' => null, + ], + // Draft — belum diajukan + [ + 'title' => 'Profil Divisi Olahraga', + 'category' => 'umum', + 'content' => '

Divisi olahraga Persegi aktif mengadakan kegiatan rutin setiap minggu.

', + 'author_id' => $anggota?->id, + 'status' => 'draft', + 'published_at' => null, + ], ]; foreach ($posts as $data) { Post::firstOrCreate( - ['slug' => \Illuminate\Support\Str::slug($data['title'])], - array_merge($data, ['author_id' => $author->id, 'status' => 'published']) + ['slug' => Str::slug($data['title'])], + $data ); } } diff --git a/database/seeders/UserSeeder.php b/database/seeders/UserSeeder.php index f42172d..5f2a2d5 100644 --- a/database/seeders/UserSeeder.php +++ b/database/seeders/UserSeeder.php @@ -27,6 +27,15 @@ class UserSeeder extends Seeder ->each(fn ($user) => $user->assignRole($role)); } + // 1 editor + User::factory()->createOne([ + 'name' => 'Editor Konten', + 'email' => 'editor@persegi.test', + 'password' => bcrypt('password'), + 'status' => 'aktif', + 'division_id' => fake()->randomElement($divisions), + ])->assignRole('editor'); + // 2 user tanpa role User::factory(2)->create(['division_id' => fake()->randomElement($divisions)]); } diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..98d8589 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1912 @@ +{ + "name": "jetstream", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "devDependencies": { + "@tailwindcss/vite": "^4.2.2", + "axios": ">=1.11.0 <=1.14.0", + "concurrently": "^9.0.1", + "laravel-vite-plugin": "^3.0.0", + "tailwindcss": "^4.2.2", + "vite": "^8.0.0" + } + }, + "node_modules/@emnapi/core": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.9.2.tgz", + "integrity": "sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.1", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.9.2.tgz", + "integrity": "sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", + "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.2.tgz", + "integrity": "sha512-sNXv5oLJ7ob93xkZ1XnxisYhGYXfaG9f65/ZgYuAu3qt7b3NadcOEhLvx28hv31PgX8SZJRYrAIPQilQmFpLVw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@tybys/wasm-util": "^0.10.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "peerDependencies": { + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1" + } + }, + "node_modules/@oxc-project/types": { + "version": "0.122.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.122.0.tgz", + "integrity": "sha512-oLAl5kBpV4w69UtFZ9xqcmTi+GENWOcPF7FCrczTiBbmC0ibXxCwyvZGbO39rCVEuLGAZM84DH0pUIyyv/YJzA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/Boshen" + } + }, + "node_modules/@rolldown/binding-android-arm64": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-rc.12.tgz", + "integrity": "sha512-pv1y2Fv0JybcykuiiD3qBOBdz6RteYojRFY1d+b95WVuzx211CRh+ytI/+9iVyWQ6koTh5dawe4S/yRfOFjgaA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-rc.12.tgz", + "integrity": "sha512-cFYr6zTG/3PXXF3pUO+umXxt1wkRK/0AYT8lDwuqvRC+LuKYWSAQAQZjCWDQpAH172ZV6ieYrNnFzVVcnSflAg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-x64": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-rc.12.tgz", + "integrity": "sha512-ZCsYknnHzeXYps0lGBz8JrF37GpE9bFVefrlmDrAQhOEi4IOIlcoU1+FwHEtyXGx2VkYAvhu7dyBf75EJQffBw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-freebsd-x64": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-rc.12.tgz", + "integrity": "sha512-dMLeprcVsyJsKolRXyoTH3NL6qtsT0Y2xeuEA8WQJquWFXkEC4bcu1rLZZSnZRMtAqwtrF/Ib9Ddtpa/Gkge9Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm-gnueabihf": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-rc.12.tgz", + "integrity": "sha512-YqWjAgGC/9M1lz3GR1r1rP79nMgo3mQiiA+Hfo+pvKFK1fAJ1bCi0ZQVh8noOqNacuY1qIcfyVfP6HoyBRZ85Q==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-gnu": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-rc.12.tgz", + "integrity": "sha512-/I5AS4cIroLpslsmzXfwbe5OmWvSsrFuEw3mwvbQ1kDxJ822hFHIx+vsN/TAzNVyepI/j/GSzrtCIwQPeKCLIg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-musl": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-rc.12.tgz", + "integrity": "sha512-V6/wZztnBqlx5hJQqNWwFdxIKN0m38p8Jas+VoSfgH54HSj9tKTt1dZvG6JRHcjh6D7TvrJPWFGaY9UBVOaWPw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-ppc64-gnu": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.0-rc.12.tgz", + "integrity": "sha512-AP3E9BpcUYliZCxa3w5Kwj9OtEVDYK6sVoUzy4vTOJsjPOgdaJZKFmN4oOlX0Wp0RPV2ETfmIra9x1xuayFB7g==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-s390x-gnu": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.0-rc.12.tgz", + "integrity": "sha512-nWwpvUSPkoFmZo0kQazZYOrT7J5DGOJ/+QHHzjvNlooDZED8oH82Yg67HvehPPLAg5fUff7TfWFHQS8IV1n3og==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-gnu": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-rc.12.tgz", + "integrity": "sha512-RNrafz5bcwRy+O9e6P8Z/OCAJW/A+qtBczIqVYwTs14pf4iV1/+eKEjdOUta93q2TsT/FI0XYDP3TCky38LMAg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-musl": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-rc.12.tgz", + "integrity": "sha512-Jpw/0iwoKWx3LJ2rc1yjFrj+T7iHZn2JDg1Yny1ma0luviFS4mhAIcd1LFNxK3EYu3DHWCps0ydXQ5i/rrJ2ig==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-openharmony-arm64": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-rc.12.tgz", + "integrity": "sha512-vRugONE4yMfVn0+7lUKdKvN4D5YusEiPilaoO2sgUWpCvrncvWgPMzK00ZFFJuiPgLwgFNP5eSiUlv2tfc+lpA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-wasm32-wasi": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-rc.12.tgz", + "integrity": "sha512-ykGiLr/6kkiHc0XnBfmFJuCjr5ZYKKofkx+chJWDjitX+KsJuAmrzWhwyOMSHzPhzOHOy7u9HlFoa5MoAOJ/Zg==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@napi-rs/wasm-runtime": "^1.1.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@rolldown/binding-win32-arm64-msvc": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-rc.12.tgz", + "integrity": "sha512-5eOND4duWkwx1AzCxadcOrNeighiLwMInEADT0YM7xeEOOFcovWZCq8dadXgcRHSf3Ulh1kFo/qvzoFiCLOL1Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-rc.12.tgz", + "integrity": "sha512-PyqoipaswDLAZtot351MLhrlrh6lcZPo2LSYE+VDxbVk24LVKAGOuE4hb8xZQmrPAuEtTZW8E6D2zc5EUZX4Lw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.12.tgz", + "integrity": "sha512-HHMwmarRKvoFsJorqYlFeFRzXZqCt2ETQlEDOb9aqssrnVBB1/+xgTGtuTrIk5vzLNX1MjMtTf7W9z3tsSbrxw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tailwindcss/node": { + "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.32.0", + "magic-string": "^0.30.21", + "source-map-js": "^1.2.1", + "tailwindcss": "4.2.2" + } + }, + "node_modules/@tailwindcss/oxide": { + "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.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.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" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-darwin-arm64": { + "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" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-darwin-x64": { + "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" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-freebsd-x64": { + "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" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { + "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" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { + "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" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-musl": { + "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" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-gnu": { + "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" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-musl": { + "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" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi": { + "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", + "@emnapi/runtime", + "@tybys/wasm-util", + "@emnapi/wasi-threads", + "tslib" + ], + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.8.1", + "@emnapi/runtime": "^1.8.1", + "@emnapi/wasi-threads": "^1.1.0", + "@napi-rs/wasm-runtime": "^1.1.1", + "@tybys/wasm-util": "^0.10.1", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { + "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" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-win32-x64-msvc": { + "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" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/vite": { + "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.2", + "@tailwindcss/oxide": "4.2.2", + "tailwindcss": "4.2.2" + }, + "peerDependencies": { + "vite": "^5.2.0 || ^6 || ^7 || ^8" + } + }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz", + "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/axios": { + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.14.0.tgz", + "integrity": "sha512-3Y8yrqLSwjuzpXuZ0oIYZ/XGgLwUIBU3uLvbcpb0pidD9ctpShJd43KSlEEkVQg6DS0G9NKyzOvBfUtDKEyHvQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.11", + "form-data": "^4.0.5", + "proxy-from-env": "^2.1.0" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/concurrently": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-9.2.1.tgz", + "integrity": "sha512-fsfrO0MxV64Znoy8/l1vVIjjHa29SZyyqPgQBwhiDcaW8wJc2W3XWVOGx4M3oJBnv/zdUZIIp1gDeS98GzP8Ng==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "4.1.2", + "rxjs": "7.8.2", + "shell-quote": "1.8.3", + "supports-color": "8.1.1", + "tree-kill": "1.2.2", + "yargs": "17.7.2" + }, + "bin": { + "conc": "dist/bin/concurrently.js", + "concurrently": "dist/bin/concurrently.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/open-cli-tools/concurrently?sponsor=1" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/enhanced-resolve": { + "version": "5.20.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.20.1.tgz", + "integrity": "sha512-Qohcme7V1inbAfvjItgw0EaxVX5q2rdVEZHRBrEQdRZTssLDGsL8Lwrznl8oQ/6kuTJONLaDcGjkNP247XEhcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.3.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/follow-redirects": { + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", + "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", + "dev": true, + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jiti": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz", + "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/laravel-vite-plugin": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/laravel-vite-plugin/-/laravel-vite-plugin-3.0.1.tgz", + "integrity": "sha512-Bx8sVcLIaZT1d0eisABcmjQ1GZdJpaXcV66A8RhXGp9JgR3iL8jDnvakVDXuH87Tn5S9KNx3VOhmJZW1CSexOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "picocolors": "^1.0.0", + "tinyglobby": "^0.2.12", + "vite-plugin-full-reload": "^1.1.0" + }, + "bin": { + "clean-orphaned-assets": "bin/clean.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "peerDependencies": { + "vite": "^8.0.0" + } + }, + "node_modules/lightningcss": { + "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": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "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.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz", + "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "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" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "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" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "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" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "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" + ], + "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/lightningcss-linux-arm64-gnu": { + "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" + ], + "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/lightningcss-linux-arm64-musl": { + "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" + ], + "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/lightningcss-linux-x64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz", + "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==", + "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/lightningcss-linux-x64-musl": { + "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" + ], + "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/lightningcss-win32-arm64-msvc": { + "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" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "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" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.8", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.8.tgz", + "integrity": "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/proxy-from-env": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz", + "integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/rolldown": { + "version": "1.0.0-rc.12", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-rc.12.tgz", + "integrity": "sha512-yP4USLIMYrwpPHEFB5JGH1uxhcslv6/hL0OyvTuY+3qlOSJvZ7ntYnoWpehBxufkgN0cvXxppuTu5hHa/zPh+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@oxc-project/types": "=0.122.0", + "@rolldown/pluginutils": "1.0.0-rc.12" + }, + "bin": { + "rolldown": "bin/cli.mjs" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "optionalDependencies": { + "@rolldown/binding-android-arm64": "1.0.0-rc.12", + "@rolldown/binding-darwin-arm64": "1.0.0-rc.12", + "@rolldown/binding-darwin-x64": "1.0.0-rc.12", + "@rolldown/binding-freebsd-x64": "1.0.0-rc.12", + "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.12", + "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.12", + "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.12", + "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.12", + "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.12", + "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.12", + "@rolldown/binding-linux-x64-musl": "1.0.0-rc.12", + "@rolldown/binding-openharmony-arm64": "1.0.0-rc.12", + "@rolldown/binding-wasm32-wasi": "1.0.0-rc.12", + "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.12", + "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.12" + } + }, + "node_modules/rxjs": { + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", + "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/shell-quote": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz", + "integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/tailwindcss": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.2.2.tgz", + "integrity": "sha512-KWBIxs1Xb6NoLdMVqhbhgwZf2PGBpPEiwOqgI4pFIYbNTfBXiKYyWoTsXgBQ9WFg/OlhnvHaY+AEpW7wSmFo2Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/tapable": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.2.tgz", + "integrity": "sha512-1MOpMXuhGzGL5TTCZFItxCc0AARf1EZFQkGqMm7ERKj8+Hgr5oLvJOVFcC+lRmR8hCe2S3jC4T5D7Vg/d7/fhA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true, + "license": "MIT", + "bin": { + "tree-kill": "cli.js" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD" + }, + "node_modules/vite": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.3.tgz", + "integrity": "sha512-B9ifbFudT1TFhfltfaIPgjo9Z3mDynBTJSUYxTjOQruf/zHH+ezCQKcoqO+h7a9Pw9Nm/OtlXAiGT1axBgwqrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "lightningcss": "^1.32.0", + "picomatch": "^4.0.4", + "postcss": "^8.5.8", + "rolldown": "1.0.0-rc.12", + "tinyglobby": "^0.2.15" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "@vitejs/devtools": "^0.1.0", + "esbuild": "^0.27.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "@vitejs/devtools": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vite-plugin-full-reload": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/vite-plugin-full-reload/-/vite-plugin-full-reload-1.2.0.tgz", + "integrity": "sha512-kz18NW79x0IHbxRSHm0jttP4zoO9P9gXh+n6UTwlNKnviTTEpOlum6oS9SmecrTtSr+muHEn5TUuC75UovQzcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picocolors": "^1.0.0", + "picomatch": "^2.3.1" + } + }, + "node_modules/vite-plugin-full-reload/node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + } + } +} diff --git a/package.json b/package.json index d2456d5..995bb10 100644 --- a/package.json +++ b/package.json @@ -7,11 +7,11 @@ "dev": "vite" }, "devDependencies": { - "@tailwindcss/vite": "^4.0.0", + "@tailwindcss/vite": "^4.2.2", "axios": ">=1.11.0 <=1.14.0", "concurrently": "^9.0.1", "laravel-vite-plugin": "^3.0.0", - "tailwindcss": "^4.0.0", + "tailwindcss": "^4.2.2", "vite": "^8.0.0" } } diff --git a/public/images/logo.png b/public/images/logo.png new file mode 100644 index 0000000..87dbe56 Binary files /dev/null and b/public/images/logo.png differ diff --git a/resources/css/app.css b/resources/css/app.css index 3e6abea..4df81f2 100644 --- a/resources/css/app.css +++ b/resources/css/app.css @@ -6,6 +6,19 @@ @source '../**/*.js'; @theme { - --font-sans: 'Instrument Sans', ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', - 'Segoe UI Symbol', 'Noto Color Emoji'; + --font-sans: 'Roboto', ui-sans-serif, system-ui, sans-serif; + --font-heading: 'Playfair Display', ui-serif, serif; } + +[x-cloak] { display: none; } + +.line-clamp-3 { display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; } +.line-clamp-2 { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; } + +.prose p { margin-bottom: 1rem; } + +.skew-top { clip-path: polygon(0 4%, 100% 0, 100% 100%, 0 100%); margin-top: -2rem; padding-top: 5rem; } +.skew-bottom { clip-path: polygon(0 0, 100% 0, 100% 96%, 0 100%); padding-bottom: 5rem; } +.skew-both { clip-path: polygon(0 4%, 100% 0, 100% 96%, 0 100%); margin-top: -2rem; padding-top: 5rem; padding-bottom: 5rem; } + +h1, h2, h3, h4, h5, h6 { font-family: 'Playfair Display', serif; } diff --git a/resources/css/filament/admin/theme.css b/resources/css/filament/admin/theme.css new file mode 100644 index 0000000..506739a --- /dev/null +++ b/resources/css/filament/admin/theme.css @@ -0,0 +1,4 @@ +@import '../../../../vendor/filament/filament/resources/css/theme.css'; + +@source '../../../../app/Filament/**/*'; +@source '../../../../resources/views/filament/**/*'; diff --git a/resources/views/public/layout.blade.php b/resources/views/public/layout.blade.php index a7d7862..348114e 100644 --- a/resources/views/public/layout.blade.php +++ b/resources/views/public/layout.blade.php @@ -4,32 +4,10 @@ @yield('title', 'Persegi') — Organisasi Pemuda Desa Karangdadap - - - + @vite('resources/css/app.css') diff --git a/vite.config.js b/vite.config.js index f35b4e7..552427b 100644 --- a/vite.config.js +++ b/vite.config.js @@ -1,16 +1,19 @@ import { defineConfig } from 'vite'; import laravel from 'laravel-vite-plugin'; import tailwindcss from '@tailwindcss/vite'; +import os from 'os'; export default defineConfig({ plugins: [ laravel({ - input: ['resources/css/app.css', 'resources/js/app.js'], + input: ['resources/css/app.css', 'resources/js/app.js', 'resources/css/filament/admin/theme.css'], refresh: true, }), tailwindcss(), ], server: { + host: os.networkInterfaces().eth0?.[0].address, + cors: true, watch: { ignored: ['**/storage/framework/views/**'], },