From e0306d55798faac109cff1d2f80202ddfc65a451 Mon Sep 17 00:00:00 2001 From: Endyfadlullah Date: Fri, 8 Aug 2025 21:41:17 +0700 Subject: [PATCH] first commit --- .editorconfig | 18 + .env.example | 65 + .gitattributes | 11 + .gitignore | 24 + README.md | 202 + README_TTS.md | 194 + README_TTS_VOICES.md | 166 + TTS_CONFIG.md | 63 + app/Http/Controllers/AdminController.php | 504 + app/Http/Controllers/AuthController.php | 175 + app/Http/Controllers/Controller.php | 8 + app/Http/Controllers/DashboardController.php | 215 + app/Http/Controllers/DisplayController.php | 78 + app/Http/Controllers/LandingController.php | 13 + app/Http/Controllers/TTSController.php | 101 + app/Models/Admin.php | 31 + app/Models/Antrian.php | 49 + app/Models/Loket.php | 19 + app/Models/Poli.php | 19 + app/Models/RiwayatPanggilan.php | 23 + app/Models/User.php | 57 + app/Providers/AppServiceProvider.php | 24 + app/Services/TTSService.php | 148 + artisan | 18 + bootstrap/app.php | 18 + bootstrap/cache/.gitignore | 2 + bootstrap/providers.php | 5 + composer.json | 78 + composer.lock | 8583 +++++++++++++++++ config/app.php | 126 + config/auth.php | 118 + config/cache.php | 108 + config/database.php | 174 + config/filesystems.php | 80 + config/logging.php | 132 + config/mail.php | 118 + config/queue.php | 112 + config/sanctum.php | 84 + config/services.php | 42 + config/session.php | 217 + database/.gitignore | 1 + database/factories/UserFactory.php | 44 + .../0001_01_01_000000_create_users_table.php | 38 + .../0001_01_01_000001_create_cache_table.php | 34 + .../2024_01_01_000001_create_admins_table.php | 28 + .../2024_01_01_000002_create_polis_table.php | 27 + .../2024_01_01_000003_create_lokets_table.php | 27 + ...2024_01_01_000004_recreate_users_table.php | 51 + ...024_01_01_000005_create_antrians_table.php | 33 + ..._000006_create_riwayat_panggilan_table.php | 28 + ...007_add_remember_token_to_admins_table.php | 33 + ...1_000008_add_poli_id_to_antrians_table.php | 37 + ...000009_remove_poli_id_from_users_table.php | 28 + ...03_create_personal_access_tokens_table.php | 32 + ...025_08_08_125912_create_sessions_table.php | 30 + database/seeders/AdminSeeder.php | 29 + database/seeders/AntrianPuskesmasSeeder.php | 122 + database/seeders/DatabaseSeeder.php | 21 + database/seeders/LoketSeeder.php | 22 + database/seeders/PoliSeeder.php | 23 + package.json | 17 + phpunit.xml | 34 + public/.htaccess | 25 + .../assets/music/call-to-attention-123107.mp3 | Bin 0 -> 137926 bytes public/favicon.ico | 0 public/index.php | 20 + public/robots.txt | 2 + puskesmas | Bin 0 -> 118784 bytes resources/css/app.css | 40 + resources/js/app.js | 1 + resources/js/bootstrap.js | 4 + resources/views/admin/antrian/print.blade.php | 167 + resources/views/admin/dashboard.blade.php | 411 + resources/views/admin/laporan/index.blade.php | 497 + resources/views/admin/laporan/pdf.blade.php | 143 + resources/views/admin/poli/index.blade.php | 486 + resources/views/admin/users/index.blade.php | 534 + resources/views/admin/users/show.blade.php | 255 + .../views/auth/forgot-password.blade.php | 180 + resources/views/auth/login.blade.php | 227 + resources/views/auth/register.blade.php | 350 + resources/views/auth/reset-password.blade.php | 207 + resources/views/dashboard/index.blade.php | 560 ++ resources/views/display/index.blade.php | 435 + resources/views/landing.blade.php | 336 + resources/views/layouts/app.blade.php | 125 + resources/views/user/antrian/print.blade.php | 167 + resources/views/welcome.blade.php | 83 + routes/console.php | 8 + routes/web.php | 90 + storage/app/.gitignore | 4 + storage/app/private/.gitignore | 2 + storage/app/public/.gitignore | 2 + storage/framework/.gitignore | 9 + storage/framework/cache/.gitignore | 3 + storage/framework/cache/data/.gitignore | 2 + storage/framework/sessions/.gitignore | 2 + storage/framework/testing/.gitignore | 2 + storage/framework/views/.gitignore | 2 + storage/logs/.gitignore | 2 + test_riwayat.php | 1 + test_tts.php | 35 + test_tts_simple.php | 53 + test_voice_config.php | 80 + tests/Feature/ExampleTest.php | 19 + tests/TestCase.php | 10 + tests/Unit/ExampleTest.php | 16 + vite.config.js | 13 + 108 files changed, 18571 insertions(+) create mode 100644 .editorconfig create mode 100644 .env.example create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 README.md create mode 100644 README_TTS.md create mode 100644 README_TTS_VOICES.md create mode 100644 TTS_CONFIG.md create mode 100644 app/Http/Controllers/AdminController.php create mode 100644 app/Http/Controllers/AuthController.php create mode 100644 app/Http/Controllers/Controller.php create mode 100644 app/Http/Controllers/DashboardController.php create mode 100644 app/Http/Controllers/DisplayController.php create mode 100644 app/Http/Controllers/LandingController.php create mode 100644 app/Http/Controllers/TTSController.php create mode 100644 app/Models/Admin.php create mode 100644 app/Models/Antrian.php create mode 100644 app/Models/Loket.php create mode 100644 app/Models/Poli.php create mode 100644 app/Models/RiwayatPanggilan.php create mode 100644 app/Models/User.php create mode 100644 app/Providers/AppServiceProvider.php create mode 100644 app/Services/TTSService.php create mode 100644 artisan create mode 100644 bootstrap/app.php create mode 100644 bootstrap/cache/.gitignore create mode 100644 bootstrap/providers.php create mode 100644 composer.json create mode 100644 composer.lock create mode 100644 config/app.php create mode 100644 config/auth.php create mode 100644 config/cache.php create mode 100644 config/database.php create mode 100644 config/filesystems.php create mode 100644 config/logging.php create mode 100644 config/mail.php create mode 100644 config/queue.php create mode 100644 config/sanctum.php create mode 100644 config/services.php create mode 100644 config/session.php create mode 100644 database/.gitignore create mode 100644 database/factories/UserFactory.php create mode 100644 database/migrations/0001_01_01_000000_create_users_table.php create mode 100644 database/migrations/0001_01_01_000001_create_cache_table.php create mode 100644 database/migrations/2024_01_01_000001_create_admins_table.php create mode 100644 database/migrations/2024_01_01_000002_create_polis_table.php create mode 100644 database/migrations/2024_01_01_000003_create_lokets_table.php create mode 100644 database/migrations/2024_01_01_000004_recreate_users_table.php create mode 100644 database/migrations/2024_01_01_000005_create_antrians_table.php create mode 100644 database/migrations/2024_01_01_000006_create_riwayat_panggilan_table.php create mode 100644 database/migrations/2024_01_01_000007_add_remember_token_to_admins_table.php create mode 100644 database/migrations/2024_01_01_000008_add_poli_id_to_antrians_table.php create mode 100644 database/migrations/2024_01_01_000009_remove_poli_id_from_users_table.php create mode 100644 database/migrations/2025_08_08_092603_create_personal_access_tokens_table.php create mode 100644 database/migrations/2025_08_08_125912_create_sessions_table.php create mode 100644 database/seeders/AdminSeeder.php create mode 100644 database/seeders/AntrianPuskesmasSeeder.php create mode 100644 database/seeders/DatabaseSeeder.php create mode 100644 database/seeders/LoketSeeder.php create mode 100644 database/seeders/PoliSeeder.php create mode 100644 package.json create mode 100644 phpunit.xml create mode 100644 public/.htaccess create mode 100644 public/assets/music/call-to-attention-123107.mp3 create mode 100644 public/favicon.ico create mode 100644 public/index.php create mode 100644 public/robots.txt create mode 100644 puskesmas create mode 100644 resources/css/app.css create mode 100644 resources/js/app.js create mode 100644 resources/js/bootstrap.js create mode 100644 resources/views/admin/antrian/print.blade.php create mode 100644 resources/views/admin/dashboard.blade.php create mode 100644 resources/views/admin/laporan/index.blade.php create mode 100644 resources/views/admin/laporan/pdf.blade.php create mode 100644 resources/views/admin/poli/index.blade.php create mode 100644 resources/views/admin/users/index.blade.php create mode 100644 resources/views/admin/users/show.blade.php create mode 100644 resources/views/auth/forgot-password.blade.php create mode 100644 resources/views/auth/login.blade.php create mode 100644 resources/views/auth/register.blade.php create mode 100644 resources/views/auth/reset-password.blade.php create mode 100644 resources/views/dashboard/index.blade.php create mode 100644 resources/views/display/index.blade.php create mode 100644 resources/views/landing.blade.php create mode 100644 resources/views/layouts/app.blade.php create mode 100644 resources/views/user/antrian/print.blade.php create mode 100644 resources/views/welcome.blade.php create mode 100644 routes/console.php create mode 100644 routes/web.php create mode 100644 storage/app/.gitignore create mode 100644 storage/app/private/.gitignore create mode 100644 storage/app/public/.gitignore create mode 100644 storage/framework/.gitignore create mode 100644 storage/framework/cache/.gitignore create mode 100644 storage/framework/cache/data/.gitignore create mode 100644 storage/framework/sessions/.gitignore create mode 100644 storage/framework/testing/.gitignore create mode 100644 storage/framework/views/.gitignore create mode 100644 storage/logs/.gitignore create mode 100644 test_riwayat.php create mode 100644 test_tts.php create mode 100644 test_tts_simple.php create mode 100644 test_voice_config.php create mode 100644 tests/Feature/ExampleTest.php create mode 100644 tests/TestCase.php create mode 100644 tests/Unit/ExampleTest.php create mode 100644 vite.config.js diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..8f0de65 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,18 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_size = 4 +indent_style = space +insert_final_newline = true +trim_trailing_whitespace = true + +[*.md] +trim_trailing_whitespace = false + +[*.{yml,yaml}] +indent_size = 2 + +[docker-compose.yml] +indent_size = 4 diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..35db1dd --- /dev/null +++ b/.env.example @@ -0,0 +1,65 @@ +APP_NAME=Laravel +APP_ENV=local +APP_KEY= +APP_DEBUG=true +APP_URL=http://localhost + +APP_LOCALE=en +APP_FALLBACK_LOCALE=en +APP_FAKER_LOCALE=en_US + +APP_MAINTENANCE_DRIVER=file +# APP_MAINTENANCE_STORE=database + +PHP_CLI_SERVER_WORKERS=4 + +BCRYPT_ROUNDS=12 + +LOG_CHANNEL=stack +LOG_STACK=single +LOG_DEPRECATIONS_CHANNEL=null +LOG_LEVEL=debug + +DB_CONNECTION=sqlite +# DB_HOST=127.0.0.1 +# DB_PORT=3306 +# DB_DATABASE=laravel +# DB_USERNAME=root +# DB_PASSWORD= + +SESSION_DRIVER=database +SESSION_LIFETIME=120 +SESSION_ENCRYPT=false +SESSION_PATH=/ +SESSION_DOMAIN=null + +BROADCAST_CONNECTION=log +FILESYSTEM_DISK=local +QUEUE_CONNECTION=database + +CACHE_STORE=database +# CACHE_PREFIX= + +MEMCACHED_HOST=127.0.0.1 + +REDIS_CLIENT=phpredis +REDIS_HOST=127.0.0.1 +REDIS_PASSWORD=null +REDIS_PORT=6379 + +MAIL_MAILER=log +MAIL_SCHEME=null +MAIL_HOST=127.0.0.1 +MAIL_PORT=2525 +MAIL_USERNAME=null +MAIL_PASSWORD=null +MAIL_FROM_ADDRESS="hello@example.com" +MAIL_FROM_NAME="${APP_NAME}" + +AWS_ACCESS_KEY_ID= +AWS_SECRET_ACCESS_KEY= +AWS_DEFAULT_REGION=us-east-1 +AWS_BUCKET= +AWS_USE_PATH_STYLE_ENDPOINT=false + +VITE_APP_NAME="${APP_NAME}" diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..fcb21d3 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,11 @@ +* text=auto eol=lf + +*.blade.php diff=html +*.css diff=css +*.html diff=html +*.md diff=markdown +*.php diff=php + +/.github export-ignore +CHANGELOG.md export-ignore +.styleci.yml export-ignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b71b1ea --- /dev/null +++ b/.gitignore @@ -0,0 +1,24 @@ +*.log +.DS_Store +.env +.env.backup +.env.production +.phpactor.json +.phpunit.result.cache +/.fleet +/.idea +/.nova +/.phpunit.cache +/.vscode +/.zed +/auth.json +/node_modules +/public/build +/public/hot +/public/storage +/storage/*.key +/storage/pail +/vendor +Homestead.json +Homestead.yaml +Thumbs.db diff --git a/README.md b/README.md new file mode 100644 index 0000000..c8c4d4f --- /dev/null +++ b/README.md @@ -0,0 +1,202 @@ +# Sistem Antrian Puskesmas + +Sistem antrian digital untuk Puskesmas yang dibangun dengan Laravel dan Tailwind CSS. + +## šŸš€ Fitur + +- **Landing Page** - Halaman utama yang menarik dengan informasi layanan +- **Sistem Login/Register** - Autentikasi pengguna dengan validasi +- **Dashboard Admin** - Panel admin untuk mengelola antrian +- **Display Antrian** - Layar display untuk menampilkan antrian yang sedang dipanggil +- **Responsive Design** - Tampilan yang responsif untuk semua perangkat + +## šŸ› ļø Teknologi + +- **Backend**: Laravel 11 +- **Frontend**: Tailwind CSS +- **Database**: MySQL +- **Authentication**: Laravel Built-in Auth + +## šŸ“‹ Struktur Database + +### Tabel Users +- `id` - Primary Key +- `nama` - Nama lengkap pasien +- `alamat` - Alamat pasien +- `jenis_kelamin` - Laki-laki/Perempuan +- `no_hp` - Nomor HP +- `no_ktp` - Nomor KTP (unique) +- `poli_id` - Foreign key ke tabel polis +- `pekerjaan` - Pekerjaan pasien +- `password` - Password untuk login +- `remember_token` - Token untuk remember me + +### Tabel Polis +- `id` - Primary Key +- `nama_poli` - Nama poli (umum, gigi, kesehatan jiwa, kesehatan tradisional) + +### Tabel Lokets +- `id` - Primary Key +- `nama_loket` - Nama loket + +### Tabel Antrians +- `id` - Primary Key +- `user_id` - Foreign key ke users +- `no_antrian` - Nomor antrian +- `tanggal_antrian` - Tanggal antrian +- `is_call` - Status dipanggil +- `status` - Status antrian (menunggu, dipanggil, selesai, batal) +- `waktu_panggil` - Waktu dipanggil +- `loket_id` - Foreign key ke lokets + +### Tabel Riwayat Panggilan +- `id` - Primary Key +- `antrian_id` - Foreign key ke antrians +- `waktu_panggilan` - Waktu panggilan + +## šŸš€ Instalasi + +1. **Clone repository** + ```bash + git clone + cd Puskesmas + ``` + +2. **Install dependencies** + ```bash + composer install + npm install + ``` + +3. **Setup environment** + ```bash + cp .env.example .env + php artisan key:generate + ``` + +4. **Konfigurasi database** + - Edit file `.env` dan sesuaikan konfigurasi database + ```env + DB_CONNECTION=mysql + DB_HOST=127.0.0.1 + DB_PORT=3306 + DB_DATABASE=puskesmas + DB_USERNAME=root + DB_PASSWORD= + ``` + +5. **Jalankan migrasi dan seeder** + ```bash + php artisan migrate:fresh --seed + ``` + +6. **Jalankan server development** + ```bash + php artisan serve + ``` + +## šŸ“± Halaman yang Tersedia + +### 1. Landing Page (`/`) +- Halaman utama dengan informasi layanan +- Navigasi ke login dan register +- Informasi tentang cara kerja sistem + +### 2. Login (`/login`) +- Form login dengan email dan password +- Remember me functionality +- Link ke halaman register + +### 3. Register (`/register`) +- Form pendaftaran dengan data lengkap +- Validasi input +- Pilihan poli + +### 4. Dashboard (`/dashboard`) +- Panel admin dengan statistik +- Quick actions untuk mengelola antrian +- Tabel antrian terbaru +- Logout functionality + +### 5. Display (`/display`) +- Layar display untuk antrian +- Auto-refresh setiap 5 detik +- Tampilan antrian per poli +- Antrian berikutnya + +## šŸ‘¤ Akun Default + +Setelah menjalankan seeder, tersedia akun default: + +**Admin:** +- Username: `admin` +- Password: `password` + +**User:** +- Nama: `Budi Santoso` +- No KTP: `1234567890123456` +- Password: `password` + +## šŸŽØ Customization + +### Warna +Sistem menggunakan warna custom yang dapat diubah di `resources/views/layouts/app.blade.php`: + +```javascript +tailwind.config = { + theme: { + extend: { + colors: { + primary: '#3B82F6', // Blue + secondary: '#1E40AF', // Dark Blue + accent: '#10B981' // Green + } + } + } +} +``` + +### Layout +Layout utama dapat dimodifikasi di `resources/views/layouts/app.blade.php` + +## šŸ”§ Development + +### Menambah Poli Baru +1. Tambahkan data di seeder `AntrianPuskesmasSeeder.php` +2. Update controller `DisplayController.php` untuk menampilkan poli baru +3. Update view `display/index.blade.php` untuk menampilkan poli baru + +### Menambah Fitur Baru +1. Buat controller baru di `app/Http/Controllers/` +2. Buat view di `resources/views/` +3. Tambahkan route di `routes/web.php` +4. Update navigasi di layout + +## šŸ“Š Monitoring + +Sistem menyediakan monitoring real-time untuk: +- Total pasien terdaftar +- Antrian yang sedang menunggu +- Antrian yang sudah selesai +- Poli yang aktif + +## šŸ”’ Security + +- Password di-hash menggunakan bcrypt +- CSRF protection aktif +- Validasi input pada semua form +- Session management yang aman + +## šŸ“ž Support + +Untuk bantuan atau pertanyaan, silakan hubungi: +- Email: support@puskesmas.com +- Phone: (021) 1234-5678 + +## šŸ“„ License + +Proyek ini dilisensikan di bawah MIT License. + +--- + +**Dibuat dengan ā¤ļø untuk Puskesmas** diff --git a/README_TTS.md b/README_TTS.md new file mode 100644 index 0000000..66db1ac --- /dev/null +++ b/README_TTS.md @@ -0,0 +1,194 @@ +# Fitur TTS (Text-to-Speech) untuk Sistem Antrian Puskesmas + +## Overview + +Fitur TTS telah ditambahkan ke sistem antrian puskesmas untuk memanggil antrian secara otomatis dengan suara. Ketika admin menekan tombol "Panggil", sistem akan memainkan urutan audio berikut: + +1. **Attention Sound** - Bunyi perhatian +2. **TTS Announcement** - "Nomor antrian X, silakan menuju ke [nama poli]" +3. **Attention Sound** - Bunyi perhatian lagi + +## Cara Kerja + +### 1. Admin Panel + +- Admin membuka halaman poli (Umum, Gigi, Jiwa, Tradisional) +- Klik tombol "Panggil" pada antrian yang menunggu +- Sistem akan: + - Update status antrian menjadi "dipanggil" + - Generate audio TTS sequence + - Kirim pesan ke halaman display (jika terbuka) + - Mainkan audio di browser admin sebagai fallback + +### 2. Display Page + +- Halaman display akan menerima pesan TTS +- Audio sequence akan diputar secara otomatis +- Urutan: Attention Sound → TTS → Attention Sound + +## Komponen yang Ditambahkan + +### 1. Service + +- `app/Services/TTSService.php` - Service untuk mengelola TTS + +### 2. Controller + +- `app/Http/Controllers/TTSController.php` - Controller untuk endpoint TTS + +### 3. Routes + +```php +// Admin TTS Routes +Route::post('/admin/tts/generate', [TTSController::class, 'generateQueueCall']); +Route::post('/admin/tts/audio-sequence', [TTSController::class, 'getAudioSequence']); +Route::post('/admin/tts/play-sequence', [TTSController::class, 'playAudioSequence']); + +// Public TTS Routes +Route::post('/tts/play-sequence', [TTSController::class, 'playAudioSequence']); +``` + +### 4. JavaScript + +- TTS Audio Player class di halaman display +- Browser TTS fallback di halaman admin + +## Konfigurasi + +### 1. Google TTS API (Opsional) + +Untuk kualitas TTS yang lebih baik, Anda bisa menggunakan Google TTS API: + +1. Dapatkan API Key dari Google Cloud Console +2. Tambahkan ke file `.env`: + +```env +GOOGLE_TTS_API_KEY=your_api_key_here +``` + +### 2. Browser TTS (Default) + +Jika Google TTS API tidak tersedia, sistem akan menggunakan browser's built-in Speech Synthesis API. + +## Testing + +### 1. Tanpa Google TTS API + +1. Biarkan `GOOGLE_TTS_API_KEY` kosong di `.env` +2. Sistem akan menggunakan browser TTS +3. Buka halaman admin dan klik "Panggil" +4. Audio akan diputar di browser + +### 2. Dengan Google TTS API + +1. Set `GOOGLE_TTS_API_KEY` di `.env` +2. Sistem akan generate file audio MP3 +3. File disimpan di `public/storage/audio/queue_calls/` + +## File Audio + +### 1. Attention Sound + +- Lokasi: `public/assets/music/call-to-attention-123107.mp3` +- Digunakan di awal dan akhir sequence + +### 2. TTS Audio Files + +- Lokasi: `public/storage/audio/queue_calls/` +- Format: `queue_call_{number}_{poli}_{timestamp}.mp3` +- Dibuat otomatis saat menggunakan Google TTS API + +## Troubleshooting + +### 1. Audio tidak diputar + +- Periksa console browser untuk error +- Pastikan file attention sound ada +- Periksa permission folder storage + +### 2. TTS tidak berfungsi + +- Pastikan browser mendukung Speech Synthesis +- Periksa CSRF token untuk request AJAX +- Coba refresh halaman + +### 3. Google TTS API error + +- Periksa API key valid +- Pastikan Cloud Text-to-Speech API aktif +- Cek quota dan billing + +## Fitur Tambahan + +### 1. Audio Queue + +- Multiple panggilan akan di-queue +- Tidak ada overlap audio + +### 2. Cross-page Communication + +- Admin page bisa kirim pesan ke display page +- Menggunakan `postMessage` API + +### 3. Fallback System + +- Google TTS → Browser TTS → Silent +- Memastikan sistem tetap berfungsi + +## Keamanan + +### 1. CSRF Protection + +- Semua request TTS dilindungi CSRF token +- Validasi input untuk mencegah injection + +### 2. File Storage + +- Audio files disimpan di public storage +- Nama file menggunakan timestamp untuk uniqueness + +## Performance + +### 1. Audio Caching + +- Browser akan cache audio files +- Mengurangi bandwidth usage + +### 2. Async Processing + +- TTS generation tidak blocking +- Audio playback asynchronous + +## Monitoring + +### 1. Console Logs + +- Error dan warning di console browser +- Debug info untuk troubleshooting + +### 2. Network Tab + +- Monitor request ke TTS endpoints +- Check audio file downloads + +## Future Enhancements + +### 1. Multiple Languages + +- Support untuk bahasa lain +- Configurable voice settings + +### 2. Custom Audio + +- Upload custom attention sounds +- Per-poli audio customization + +### 3. Volume Control + +- User-adjustable volume +- Per-device audio settings + +### 4. Audio Analytics + +- Track audio playback success +- Monitor TTS usage statistics diff --git a/README_TTS_VOICES.md b/README_TTS_VOICES.md new file mode 100644 index 0000000..c5a3b6d --- /dev/null +++ b/README_TTS_VOICES.md @@ -0,0 +1,166 @@ +# TTS Voice Configuration untuk Bahasa Indonesia + +## Google Cloud Text-to-Speech API + +### Suara Indonesia yang Tersedia + +Google TTS API menyediakan beberapa opsi suara untuk bahasa Indonesia: + +#### 1. **Wavenet Voices (Lebih Natural)** +- `id-ID-Wavenet-A` - Suara wanita Indonesia yang natural dan fasih ⭐ **DIGUNAKAN SAAT INI** +- `id-ID-Wavenet-B` - Suara pria Indonesia yang natural +- `id-ID-Wavenet-C` - Suara wanita Indonesia alternatif +- `id-ID-Wavenet-D` - Suara pria Indonesia alternatif + +#### 2. **Standard Voices (Lebih Cepat)** +- `id-ID-Standard-A` - Suara wanita Indonesia standar +- `id-ID-Standard-B` - Suara pria Indonesia standar +- `id-ID-Standard-C` - Suara wanita Indonesia alternatif +- `id-ID-Standard-D` - Suara pria Indonesia alternatif + +### Konfigurasi Saat Ini + +```php +'voice' => [ + 'languageCode' => 'id-ID', + 'name' => 'id-ID-Wavenet-A', // Suara wanita Indonesia yang natural + 'ssmlGender' => 'FEMALE' +], +'audioConfig' => [ + 'audioEncoding' => 'MP3', + 'speakingRate' => 0.85, // Sedikit lebih cepat untuk alur yang natural + 'pitch' => 0, + 'volumeGainDb' => 0 +] +``` + +### Keunggulan Wavenet vs Standard + +**Wavenet Voices:** +- āœ… Suara lebih natural dan manusiawi +- āœ… Intonasi yang lebih baik +- āœ… Pengucapan yang lebih akurat +- āš ļø Lebih lambat dalam generate +- āš ļø Lebih mahal (2x lipat) + +**Standard Voices:** +- āœ… Lebih cepat dalam generate +- āœ… Lebih murah +- āš ļø Suara lebih robotik +- āš ļø Intonasi kurang natural + +## Browser Speech Synthesis API + +### Konfigurasi Saat Ini + +```javascript +utterance.lang = 'id-ID'; +utterance.rate = 0.85; // Sedikit lebih cepat untuk alur yang natural +utterance.volume = 1.0; + +// Mencoba memilih suara wanita Indonesia jika tersedia +const voices = speechSynthesis.getVoices(); +const indonesianVoice = voices.find(voice => + voice.lang === 'id-ID' && + voice.name.toLowerCase().includes('female') +) || voices.find(voice => voice.lang === 'id-ID'); + +if (indonesianVoice) { + utterance.voice = indonesianVoice; +} +``` + +### Suara Browser yang Tersedia + +Browser TTS bergantung pada sistem operasi: + +**Windows:** +- Microsoft Zira Desktop (English, tapi bisa digunakan) +- Microsoft David Desktop (English, tapi bisa digunakan) + +**macOS:** +- Siri (Female) +- Tom (Male) + +**Linux:** +- Festival voices +- eSpeak voices + +## Cara Mengubah Suara + +### 1. Mengubah Google TTS Voice + +Edit file `app/Services/TTSService.php`: + +```php +'voice' => [ + 'languageCode' => 'id-ID', + 'name' => 'id-ID-Wavenet-B', // Ganti dengan suara yang diinginkan + 'ssmlGender' => 'FEMALE' +], +``` + +### 2. Mengubah Browser TTS Voice + +Edit file `resources/views/display/index.blade.php` dan `resources/views/admin/poli/index.blade.php`: + +```javascript +// Untuk memilih suara tertentu +const voices = speechSynthesis.getVoices(); +const specificVoice = voices.find(voice => voice.name === 'Nama Suara Spesifik'); +if (specificVoice) { + utterance.voice = specificVoice; +} +``` + +## Testing Suara + +### 1. Test Google TTS + +```bash +# Pastikan API key sudah diset +echo "GOOGLE_TTS_API_KEY=your_api_key_here" >> .env + +# Test via artisan command (buat sendiri) +php artisan tts:test "Nomor antrian 001, silakan menuju ke Poli Umum" +``` + +### 2. Test Browser TTS + +Buka browser console dan jalankan: + +```javascript +// Test browser TTS +const utterance = new SpeechSynthesisUtterance("Nomor antrian 001, silakan menuju ke Poli Umum"); +utterance.lang = 'id-ID'; +utterance.rate = 0.85; +speechSynthesis.speak(utterance); + +// Lihat suara yang tersedia +speechSynthesis.getVoices().forEach(voice => { + console.log(`${voice.name} - ${voice.lang}`); +}); +``` + +## Rekomendasi + +1. **Untuk Produksi:** Gunakan `id-ID-Wavenet-A` (suara wanita natural) +2. **Untuk Testing:** Gunakan `id-ID-Standard-A` (lebih cepat dan murah) +3. **Fallback:** Browser TTS dengan konfigurasi yang sudah dioptimalkan + +## Troubleshooting + +### Suara Google TTS Tidak Berfungsi +1. Periksa API key di `.env` +2. Pastikan billing Google Cloud aktif +3. Periksa quota API + +### Suara Browser TTS Tidak Berfungsi +1. Periksa browser support untuk `speechSynthesis` +2. Pastikan sistem operasi memiliki TTS engine +3. Coba browser berbeda (Chrome, Firefox, Safari) + +### Suara Terdengar Robotik +1. Gunakan Wavenet voices untuk Google TTS +2. Sesuaikan `speakingRate` (0.8 - 1.0) +3. Pastikan teks menggunakan bahasa Indonesia yang benar diff --git a/TTS_CONFIG.md b/TTS_CONFIG.md new file mode 100644 index 0000000..6590e92 --- /dev/null +++ b/TTS_CONFIG.md @@ -0,0 +1,63 @@ +# Konfigurasi TTS (Text-to-Speech) + +## Setup Google Text-to-Speech API + +Untuk menggunakan fitur TTS, Anda perlu mengatur Google Text-to-Speech API: + +### 1. Dapatkan API Key +1. Kunjungi [Google Cloud Console](https://console.cloud.google.com/) +2. Buat project baru atau pilih project yang ada +3. Aktifkan Cloud Text-to-Speech API +4. Buat credentials (API Key) +5. Salin API Key + +### 2. Tambahkan ke .env +Tambahkan baris berikut ke file `.env`: + +```env +GOOGLE_TTS_API_KEY=your_google_tts_api_key_here +``` + +### 3. Fitur TTS + +Fitur TTS akan memainkan urutan audio berikut: +1. **Attention Sound** - `call-to-attention-123107.mp3` +2. **TTS Poli** - "Nomor antrian X, silakan menuju ke [nama poli]" +3. **TTS Nomor** - "Nomor antrian X" +4. **Attention Sound** - `call-to-attention-123107.mp3` + +### 4. Fallback TTS + +Jika Google TTS API tidak tersedia, sistem akan menggunakan: +- Browser's built-in Speech Synthesis API +- File audio attention sound yang sudah ada + +### 5. Cara Kerja + +1. Admin klik button "Panggil" di halaman admin +2. Sistem mengupdate status antrian menjadi "dipanggil" +3. Sistem generate audio TTS sequence +4. Audio diputar di halaman display +5. Jika display page tidak terbuka, audio diputar di browser admin + +### 6. File Audio + +File audio TTS akan disimpan di: +``` +public/storage/audio/queue_calls/ +``` + +### 7. Testing + +Untuk testing tanpa Google TTS API: +1. Biarkan `GOOGLE_TTS_API_KEY` kosong di .env +2. Sistem akan menggunakan browser TTS sebagai fallback +3. Audio attention sound tetap akan diputar + +### 8. Troubleshooting + +Jika TTS tidak berfungsi: +1. Periksa console browser untuk error +2. Pastikan file audio attention sound ada di `public/assets/music/` +3. Periksa permission folder `public/storage/audio/queue_calls/` +4. Pastikan CSRF token valid untuk request AJAX diff --git a/app/Http/Controllers/AdminController.php b/app/Http/Controllers/AdminController.php new file mode 100644 index 0000000..b9831bb --- /dev/null +++ b/app/Http/Controllers/AdminController.php @@ -0,0 +1,504 @@ +count(); + $polis = Poli::count(); + + // Get counts for each poli + $poliUmumCount = Antrian::whereHas('poli', function ($query) { + $query->where('nama_poli', 'umum'); + })->where('status', 'menunggu')->count(); + + $poliGigiCount = Antrian::whereHas('poli', function ($query) { + $query->where('nama_poli', 'gigi'); + })->where('status', 'menunggu')->count(); + + $poliJiwaCount = Antrian::whereHas('poli', function ($query) { + $query->where('nama_poli', 'kesehatan jiwa'); + })->where('status', 'menunggu')->count(); + + $poliTradisionalCount = Antrian::whereHas('poli', function ($query) { + $query->where('nama_poli', 'kesehatan tradisional'); + })->where('status', 'menunggu')->count(); + + // Get recent antrian + $antrianTerbaru = Antrian::with(['user', 'poli']) + ->orderBy('created_at', 'desc') + ->limit(10) + ->get(); + + return view('admin.dashboard', compact( + 'totalUsers', + 'totalAntrian', + 'antrianHariIni', + 'polis', + 'poliUmumCount', + 'poliGigiCount', + 'poliJiwaCount', + 'poliTradisionalCount', + 'antrianTerbaru' + )); + } + + public function manageUsers(Request $request) + { + $query = User::with(['antrians.poli']); + + // Search functionality + if ($request->filled('search')) { + $search = $request->search; + $query->where(function ($q) use ($search) { + $q->where('nama', 'like', "%{$search}%") + ->orWhere('no_ktp', 'like', "%{$search}%") + ->orWhere('no_hp', 'like', "%{$search}%") + ->orWhere('alamat', 'like', "%{$search}%") + ->orWhere('pekerjaan', 'like', "%{$search}%") + ->orWhere('jenis_kelamin', 'like', "%{$search}%"); + }); + } + + $users = $query->orderBy('created_at', 'desc')->get(); + return view('admin.users.index', compact('users')); + } + + public function showUser(User $user) + { + $user->load(['antrians.poli']); + return view('admin.users.show', compact('user')); + } + + public function updateUser(Request $request, User $user) + { + $request->validate([ + 'nama' => 'required|string|max:255', + 'alamat' => 'required|string', + 'jenis_kelamin' => 'required|in:laki-laki,perempuan', + 'no_hp' => 'required|string|max:20', + 'no_ktp' => 'required|string|max:50|unique:users,no_ktp,' . $user->id, + 'pekerjaan' => 'required|string|max:100', + ]); + + try { + $user->update([ + 'nama' => $request->nama, + 'alamat' => $request->alamat, + 'jenis_kelamin' => $request->jenis_kelamin, + 'no_hp' => $request->no_hp, + 'no_ktp' => $request->no_ktp, + 'pekerjaan' => $request->pekerjaan, + ]); + + return response()->json([ + 'success' => true, + 'message' => 'Data user berhasil diperbarui!' + ]); + } catch (\Exception $e) { + return response()->json([ + 'success' => false, + 'message' => 'Terjadi kesalahan: ' . $e->getMessage() + ], 500); + } + } + + public function resetUserPassword(Request $request, User $user) + { + $request->validate([ + 'new_password' => 'required|string|min:8', + ]); + + try { + $user->update([ + 'password' => Hash::make($request->new_password) + ]); + + return response()->json([ + 'success' => true, + 'message' => 'Password user berhasil direset!' + ]); + } catch (\Exception $e) { + return response()->json([ + 'success' => false, + 'message' => 'Terjadi kesalahan: ' . $e->getMessage() + ], 500); + } + } + + public function laporan(Request $request) + { + $query = Antrian::with(['user', 'poli']); + + // Filter berdasarkan tanggal + if ($request->filled('tanggal_mulai')) { + $query->whereDate('created_at', '>=', $request->tanggal_mulai); + } + + if ($request->filled('tanggal_akhir')) { + $query->whereDate('created_at', '<=', $request->tanggal_akhir); + } + + // Filter berdasarkan poli + if ($request->filled('poli_id')) { + $query->where('poli_id', $request->poli_id); + } + + // Filter berdasarkan status + if ($request->filled('status')) { + $query->where('status', $request->status); + } + + // Filter berdasarkan jenis kelamin + if ($request->filled('jenis_kelamin')) { + $query->whereHas('user', function ($q) use ($request) { + $q->where('jenis_kelamin', $request->jenis_kelamin); + }); + } + + $antrian = $query->orderBy('created_at', 'desc')->get(); + $polis = Poli::all(); + + // Statistik + $totalAntrian = $antrian->count(); + $antrianSelesai = $antrian->where('status', 'selesai')->count(); + $antrianMenunggu = $antrian->where('status', 'menunggu')->count(); + $antrianSedang = $antrian->where('status', 'sedang')->count(); + + return view('admin.laporan.index', compact('antrian', 'polis', 'totalAntrian', 'antrianSelesai', 'antrianMenunggu', 'antrianSedang')); + } + + public function exportPDF(Request $request) + { + $query = Antrian::with(['user', 'poli']); + + // Filter berdasarkan tanggal + if ($request->filled('tanggal_mulai')) { + $query->whereDate('created_at', '>=', $request->tanggal_mulai); + } + + if ($request->filled('tanggal_akhir')) { + $query->whereDate('created_at', '<=', $request->tanggal_akhir); + } + + // Filter berdasarkan poli + if ($request->filled('poli_id')) { + $query->where('poli_id', $request->poli_id); + } + + // Filter berdasarkan status + if ($request->filled('status')) { + $query->where('status', $request->status); + } + + // Filter berdasarkan jenis kelamin + if ($request->filled('jenis_kelamin')) { + $query->whereHas('user', function ($q) use ($request) { + $q->where('jenis_kelamin', $request->jenis_kelamin); + }); + } + + $antrian = $query->orderBy('created_at', 'desc')->get(); + + $pdf = Pdf::loadView('admin.laporan.pdf', compact('antrian')); + return $pdf->download('laporan-antrian-' . date('Y-m-d') . '.pdf'); + } + + public function exportExcel(Request $request) + { + $query = Antrian::with(['user', 'poli']); + + // Filter berdasarkan tanggal + if ($request->filled('tanggal_mulai')) { + $query->whereDate('created_at', '>=', $request->tanggal_mulai); + } + + if ($request->filled('tanggal_akhir')) { + $query->whereDate('created_at', '<=', $request->tanggal_akhir); + } + + // Filter berdasarkan poli + if ($request->filled('poli_id')) { + $query->where('poli_id', $request->poli_id); + } + + // Filter berdasarkan status + if ($request->filled('status')) { + $query->where('status', $request->status); + } + + // Filter berdasarkan jenis kelamin + if ($request->filled('jenis_kelamin')) { + $query->whereHas('user', function ($q) use ($request) { + $q->where('jenis_kelamin', $request->jenis_kelamin); + }); + } + + $antrian = $query->orderBy('created_at', 'desc')->get(); + + $filename = 'laporan-antrian-' . date('Y-m-d') . '.csv'; + + $headers = [ + 'Content-Type' => 'text/csv', + 'Content-Disposition' => 'attachment; filename="' . $filename . '"', + ]; + + $callback = function () use ($antrian) { + $file = fopen('php://output', 'w'); + + // Header CSV + fputcsv($file, [ + 'No Antrian', + 'Nama Pasien', + 'No KTP', + 'Jenis Kelamin', + 'Poli', + 'Status', + 'Tanggal Daftar', + 'Waktu Daftar', + 'Waktu Panggil' + ]); + + // Data CSV + foreach ($antrian as $item) { + fputcsv($file, [ + $item->no_antrian, + $item->user->nama, + $item->user->no_ktp, + $item->user->jenis_kelamin, + $item->poli->nama_poli, + ucfirst($item->status), + $item->created_at ? $item->created_at->format('d/m/Y') : '-', + $item->created_at ? $item->created_at->format('H:i') : '-', + $item->waktu_panggil ? $item->waktu_panggil->format('H:i') : '-' + ]); + } + + fclose($file); + }; + + return response()->stream($callback, 200, $headers); + } + + public function poliUmum() + { + $antrians = Antrian::with(['user', 'poli']) + ->whereHas('poli', function ($query) { + $query->where('nama_poli', 'umum'); + }) + ->orderBy('created_at', 'asc') + ->get(); + + $title = 'Poli Umum'; + return view('admin.poli.index', compact('antrians', 'title')); + } + + public function poliGigi() + { + $antrians = Antrian::with(['user', 'poli']) + ->whereHas('poli', function ($query) { + $query->where('nama_poli', 'gigi'); + }) + ->orderBy('created_at', 'asc') + ->get(); + + $title = 'Poli Gigi'; + return view('admin.poli.index', compact('antrians', 'title')); + } + + public function poliJiwa() + { + $antrians = Antrian::with(['user', 'poli']) + ->whereHas('poli', function ($query) { + $query->where('nama_poli', 'kesehatan jiwa'); + }) + ->orderBy('created_at', 'asc') + ->get(); + + $title = 'Poli Jiwa'; + return view('admin.poli.index', compact('antrians', 'title')); + } + + public function poliTradisional() + { + $antrians = Antrian::with(['user', 'poli']) + ->whereHas('poli', function ($query) { + $query->where('nama_poli', 'kesehatan tradisional'); + }) + ->orderBy('created_at', 'asc') + ->get(); + + $title = 'Poli Tradisional'; + return view('admin.poli.index', compact('antrians', 'title')); + } + + public function panggilAntrian(Request $request) + { + try { + // Get the next waiting queue + $antrian = Antrian::where('status', 'menunggu') + ->orderBy('created_at', 'asc') + ->first(); + + if (!$antrian) { + return response()->json([ + 'success' => false, + 'message' => 'Tidak ada antrian yang menunggu' + ]); + } + + // Update status to 'dipanggil' + $antrian->update(['status' => 'dipanggil']); + + // Record call history + RiwayatPanggilan::create([ + 'antrian_id' => $antrian->id, + 'waktu_panggilan' => now() + ]); + + return response()->json([ + 'success' => true, + 'message' => 'Antrian ' . $antrian->no_antrian . ' dipanggil' + ]); + } catch (\Exception $e) { + return response()->json([ + 'success' => false, + 'message' => 'Terjadi kesalahan: ' . $e->getMessage() + ], 500); + } + } + + public function panggilAntrianById(Antrian $antrian) + { + try { + if ($antrian->status !== 'menunggu') { + return response()->json([ + 'success' => false, + 'message' => 'Antrian ini tidak dalam status menunggu' + ]); + } + + // Update status to 'dipanggil' + $antrian->update(['status' => 'dipanggil']); + + // Record call history + RiwayatPanggilan::create([ + 'antrian_id' => $antrian->id, + 'waktu_panggilan' => now() + ]); + + // Generate TTS audio sequence + $ttsService = new TTSService(); + $audioSequence = $ttsService->createCompleteAudioSequence( + $antrian->poli->nama_poli, + $antrian->no_antrian + ); + + return response()->json([ + 'success' => true, + 'message' => 'Antrian ' . $antrian->no_antrian . ' dipanggil', + 'audio_sequence' => $audioSequence, + 'poli_name' => $antrian->poli->nama_poli, + 'queue_number' => $antrian->no_antrian + ]); + } catch (\Exception $e) { + return response()->json([ + 'success' => false, + 'message' => 'Terjadi kesalahan: ' . $e->getMessage() + ], 500); + } + } + + public function selesaiAntrian(Request $request) + { + try { + $request->validate([ + 'antrian_id' => 'required|exists:antrians,id' + ]); + + $antrian = Antrian::findOrFail($request->antrian_id); + + if ($antrian->status !== 'dipanggil') { + return response()->json([ + 'success' => false, + 'message' => 'Antrian ini tidak dalam status dipanggil' + ]); + } + + // Update status to 'selesai' + $antrian->update(['status' => 'selesai']); + + return response()->json([ + 'success' => true, + 'message' => 'Antrian ' . $antrian->no_antrian . ' selesai' + ]); + } catch (\Exception $e) { + return response()->json([ + 'success' => false, + 'message' => 'Terjadi kesalahan: ' . $e->getMessage() + ], 500); + } + } + + public function batalAntrian(Request $request) + { + try { + $request->validate([ + 'antrian_id' => 'required|exists:antrians,id' + ]); + + $antrian = Antrian::findOrFail($request->antrian_id); + + if ($antrian->status === 'selesai') { + return response()->json([ + 'success' => false, + 'message' => 'Antrian yang sudah selesai tidak dapat dibatalkan' + ]); + } + + // Update status to 'batal' + $antrian->update(['status' => 'batal']); + + return response()->json([ + 'success' => true, + 'message' => 'Antrian ' . $antrian->no_antrian . ' dibatalkan' + ]); + } catch (\Exception $e) { + return response()->json([ + 'success' => false, + 'message' => 'Terjadi kesalahan: ' . $e->getMessage() + ], 500); + } + } + + public function cetakAntrian(Antrian $antrian) + { + try { + $antrian->load(['user', 'poli']); + + $pdf = Pdf::loadView('admin.antrian.print', compact('antrian')); + return $pdf->stream('antrian-' . $antrian->no_antrian . '.pdf'); + } catch (\Exception $e) { + return response()->json([ + 'success' => false, + 'message' => 'Terjadi kesalahan: ' . $e->getMessage() + ], 500); + } + } +} diff --git a/app/Http/Controllers/AuthController.php b/app/Http/Controllers/AuthController.php new file mode 100644 index 0000000..3a9cca2 --- /dev/null +++ b/app/Http/Controllers/AuthController.php @@ -0,0 +1,175 @@ +validate([ + 'email_or_ktp' => 'required|string', + 'password' => 'required', + ]); + + $emailOrKtp = $request->email_or_ktp; + $password = $request->password; + + // First, try to find admin by username + $admin = Admin::where('username', $emailOrKtp)->first(); + + if ($admin && Hash::check($password, $admin->password)) { + Auth::guard('admin')->login($admin, $request->remember); + $request->session()->regenerate(); + return redirect()->intended('/admin/dashboard')->with('success', 'Selamat datang, Admin!'); + } + + // If not admin, try to find user by nama (username) or no_ktp + $user = User::where('nama', $emailOrKtp) + ->orWhere('no_ktp', $emailOrKtp) + ->first(); + + if ($user && Hash::check($password, $user->password)) { + Auth::login($user, $request->remember); + $request->session()->regenerate(); + return redirect()->intended('/dashboard')->with('success', 'Selamat datang, ' . $user->nama . '!'); + } + + // If neither admin nor user found, return error + return back()->withErrors([ + 'email_or_ktp' => 'Username/Nama/No KTP atau password salah.', + ])->withInput($request->only('email_or_ktp')); + } + + public function showRegister() + { + return view('auth.register'); + } + + public function register(Request $request) + { + $request->validate([ + 'nama' => 'required|string|max:255', + 'alamat' => 'required|string', + 'jenis_kelamin' => 'required|in:laki-laki,perempuan', + 'no_hp' => 'required|string|max:20', + 'no_ktp' => 'required|string|size:16|unique:users|regex:/^[0-9]+$/', + 'pekerjaan' => 'required|string|max:100', + 'password' => 'required|string|min:8|confirmed', + ], [ + 'no_ktp.size' => 'Nomor KTP harus tepat 16 digit.', + 'no_ktp.regex' => 'Nomor KTP hanya boleh berisi angka.', + 'no_ktp.unique' => 'Nomor KTP sudah terdaftar.', + ]); + + $user = User::create([ + 'nama' => $request->nama, + 'alamat' => $request->alamat, + 'jenis_kelamin' => $request->jenis_kelamin, + 'no_hp' => $request->no_hp, + 'no_ktp' => $request->no_ktp, + 'pekerjaan' => $request->pekerjaan, + 'password' => Hash::make($request->password), + ]); + + Auth::login($user); + + return redirect('/dashboard')->with('success', 'Akun berhasil dibuat!'); + } + + public function logout(Request $request) + { + // Check if admin is logged in + if (Auth::guard('admin')->check()) { + Auth::guard('admin')->logout(); + } else { + Auth::logout(); + } + + $request->session()->invalidate(); + $request->session()->regenerateToken(); + return redirect('/')->with('success', 'Anda berhasil logout!'); + } + + public function showForgotPassword() + { + return view('auth.forgot-password'); + } + + public function forgotPassword(Request $request) + { + $request->validate([ + 'nama' => 'required|string|max:255', + 'no_ktp' => 'required|string|max:50', + ]); + + $nama = $request->nama; + $noKtp = $request->no_ktp; + + // Cari user berdasarkan nama dan no_ktp + $user = User::where('nama', $nama) + ->where('no_ktp', $noKtp) + ->first(); + + if ($user) { + // Jika kedua data benar, simpan user_id di session dan arahkan ke reset password + $request->session()->put('reset_user_id', $user->id); + return redirect()->route('reset-password')->with('success', 'Verifikasi berhasil! Silakan masukkan password baru.'); + } else { + // Jika salah satu atau keduanya salah, berikan pesan error + return back()->withErrors([ + 'nama' => 'Nama atau nomor KTP tidak ditemukan. Silakan hubungi admin untuk verifikasi data.', + ])->withInput($request->only('nama', 'no_ktp')); + } + } + + public function showResetPassword(Request $request) + { + // Cek apakah ada user_id di session + if (!$request->session()->has('reset_user_id')) { + return redirect()->route('forgot-password')->with('error', 'Sesi verifikasi tidak valid. Silakan verifikasi ulang.'); + } + + return view('auth.reset-password'); + } + + public function resetPassword(Request $request) + { + $request->validate([ + 'user_id' => 'required|exists:users,id', + 'password' => 'required|string|min:8|confirmed', + ]); + + // Cek apakah user_id di session sama dengan yang dikirim + if ($request->session()->get('reset_user_id') != $request->user_id) { + return redirect()->route('forgot-password')->with('error', 'Sesi verifikasi tidak valid. Silakan verifikasi ulang.'); + } + + $user = User::find($request->user_id); + + if (!$user) { + return redirect()->route('forgot-password')->with('error', 'User tidak ditemukan.'); + } + + // Update password + $user->update([ + 'password' => Hash::make($request->password) + ]); + + // Hapus session reset_user_id + $request->session()->forget('reset_user_id'); + + return redirect()->route('login')->with('success', 'Password berhasil direset! Silakan login dengan password baru.'); + } +} diff --git a/app/Http/Controllers/Controller.php b/app/Http/Controllers/Controller.php new file mode 100644 index 0000000..8677cd5 --- /dev/null +++ b/app/Http/Controllers/Controller.php @@ -0,0 +1,8 @@ +where('user_id', Auth::id()) + ->whereDate('created_at', today()) + ->orderBy('created_at', 'desc') + ->get(); + + return view('dashboard.index', compact('antrianSaya')); + } + + public function addQueue(Request $request) + { + $request->validate([ + 'poli_id' => 'required|exists:polis,id' + ]); + + try { + DB::beginTransaction(); + + $user = Auth::user(); + + // Check if user already has a queue today for the same poli + $existingQueue = Antrian::where('user_id', $user->id) + ->where('poli_id', $request->poli_id) + ->whereDate('created_at', today()) + ->whereIn('status', ['menunggu', 'dipanggil']) + ->first(); + + if ($existingQueue) { + // Get poli name for error message + $poliName = Poli::find($request->poli_id)->nama_poli; + return redirect()->back()->with('error', 'Anda sudah memiliki antrian di ' . $poliName . ' hari ini.'); + } + + // Get poli info for prefix + $poli = Poli::find($request->poli_id); + $prefix = $this->getPoliPrefix($poli->nama_poli); + + // Get next queue number for the poli + $lastQueue = Antrian::where('poli_id', $request->poli_id) + ->whereDate('created_at', today()) + ->max('no_antrian'); + + // Extract number from last queue (remove prefix) + $lastNumber = 0; + if ($lastQueue) { + $lastNumber = (int) preg_replace('/[^0-9]/', '', $lastQueue); + } + + $nextNumber = $lastNumber + 1; + $nextQueueNumber = $prefix . $nextNumber; + + // Create new queue using current user's data + $antrian = Antrian::create([ + 'user_id' => $user->id, + 'poli_id' => $request->poli_id, + 'no_antrian' => $nextQueueNumber, + 'tanggal_antrian' => now()->toDateString(), + 'status' => 'menunggu' + ]); + + DB::commit(); + + // Get poli name for success message + $poliName = $poli->nama_poli; + return redirect()->back()->with('success', 'Antrian berhasil diambil! Nomor antrian Anda di ' . $poliName . ': ' . $nextQueueNumber); + + } catch (\Exception $e) { + DB::rollback(); + return redirect()->back()->with('error', 'Terjadi kesalahan saat mengambil antrian: ' . $e->getMessage()); + } + } + + public function updateProfile(Request $request) + { + $request->validate([ + 'nama' => 'required|string|max:255', + 'no_hp' => 'required|string|max:15', + 'no_ktp' => 'required|string|max:16', + 'jenis_kelamin' => 'required|in:laki-laki,perempuan', + 'alamat' => 'required|string', + 'pekerjaan' => 'required|string|max:100' + ]); + + try { + $user = Auth::user(); + + // Check if KTP number is already used by another user + $existingUser = User::where('no_ktp', $request->no_ktp) + ->where('id', '!=', $user->id) + ->first(); + + if ($existingUser) { + return response()->json([ + 'success' => false, + 'message' => 'Nomor KTP sudah digunakan oleh user lain.' + ]); + } + + $user->nama = $request->nama; + $user->no_hp = $request->no_hp; + $user->no_ktp = $request->no_ktp; + $user->jenis_kelamin = $request->jenis_kelamin; + $user->alamat = $request->alamat; + $user->pekerjaan = $request->pekerjaan; + $user->save(); + + return response()->json([ + 'success' => true, + 'message' => 'Data diri berhasil diperbarui!' + ]); + + } catch (\Exception $e) { + return response()->json([ + 'success' => false, + 'message' => 'Terjadi kesalahan saat memperbarui data: ' . $e->getMessage() + ]); + } + } + + private function getPoliPrefix($namaPoli) + { + switch (strtolower($namaPoli)) { + case 'umum': + return 'U'; + case 'gigi': + return 'G'; + case 'kesehatan jiwa': + return 'J'; + case 'kesehatan tradisional': + return 'T'; + default: + return 'A'; // Default prefix + } + } + + public function batalAntrian(Request $request) + { + try { + $request->validate([ + 'antrian_id' => 'required|exists:antrians,id' + ]); + + $antrian = Antrian::findOrFail($request->antrian_id); + + // Check if the antrian belongs to the authenticated user + if ($antrian->user_id !== Auth::id()) { + return response()->json([ + 'success' => false, + 'message' => 'Anda tidak memiliki akses untuk membatalkan antrian ini' + ], 403); + } + + if ($antrian->status === 'selesai') { + return response()->json([ + 'success' => false, + 'message' => 'Antrian yang sudah selesai tidak dapat dibatalkan' + ]); + } + + // Update status to 'batal' + $antrian->update(['status' => 'batal']); + + return response()->json([ + 'success' => true, + 'message' => 'Antrian ' . $antrian->no_antrian . ' berhasil dibatalkan' + ]); + } catch (\Exception $e) { + return response()->json([ + 'success' => false, + 'message' => 'Terjadi kesalahan: ' . $e->getMessage() + ], 500); + } + } + + public function cetakAntrian(Antrian $antrian) + { + try { + // Check if the antrian belongs to the authenticated user + if ($antrian->user_id !== Auth::id()) { + abort(403, 'Anda tidak memiliki akses untuk mencetak antrian ini'); + } + + // Check if antrian can be printed (only 'menunggu' status can be printed) + if ($antrian->status !== 'menunggu') { + abort(400, 'Antrian dengan status "' . ucfirst($antrian->status) . '" tidak dapat dicetak'); + } + + $antrian->load(['user', 'poli']); + + $pdf = \Barryvdh\DomPDF\Facade\Pdf::loadView('user.antrian.print', compact('antrian')); + return $pdf->stream('antrian-' . $antrian->no_antrian . '.pdf'); + } catch (\Exception $e) { + return response()->json([ + 'success' => false, + 'message' => 'Terjadi kesalahan: ' . $e->getMessage() + ], 500); + } + } +} diff --git a/app/Http/Controllers/DisplayController.php b/app/Http/Controllers/DisplayController.php new file mode 100644 index 0000000..4e43f83 --- /dev/null +++ b/app/Http/Controllers/DisplayController.php @@ -0,0 +1,78 @@ +where('status', 'dipanggil') + ->whereDate('created_at', today()) + ->orderByDesc('updated_at') + ->first(); + + $poliGigiCurrent = Antrian::where('poli_id', 2) + ->where('status', 'dipanggil') + ->whereDate('created_at', today()) + ->orderByDesc('updated_at') + ->first(); + + $poliJiwaCurrent = Antrian::where('poli_id', 3) + ->where('status', 'dipanggil') + ->whereDate('created_at', today()) + ->orderByDesc('updated_at') + ->first(); + + $poliTradisionalCurrent = Antrian::where('poli_id', 4) + ->where('status', 'dipanggil') + ->whereDate('created_at', today()) + ->orderByDesc('updated_at') + ->first(); + + // Next: menunggu per poli (maks 3) + $poliUmumNext = Antrian::where('poli_id', 1) + ->where('status', 'menunggu') + ->whereDate('created_at', today()) + ->orderBy('created_at', 'asc') + ->take(3) + ->get(); + + $poliGigiNext = Antrian::where('poli_id', 2) + ->where('status', 'menunggu') + ->whereDate('created_at', today()) + ->orderBy('created_at', 'asc') + ->take(3) + ->get(); + + $poliJiwaNext = Antrian::where('poli_id', 3) + ->where('status', 'menunggu') + ->whereDate('created_at', today()) + ->orderBy('created_at', 'asc') + ->take(3) + ->get(); + + $poliTradisionalNext = Antrian::where('poli_id', 4) + ->where('status', 'menunggu') + ->whereDate('created_at', today()) + ->orderBy('created_at', 'asc') + ->take(3) + ->get(); + + return view('display.index', compact( + 'poliUmumCurrent', + 'poliGigiCurrent', + 'poliJiwaCurrent', + 'poliTradisionalCurrent', + 'poliUmumNext', + 'poliGigiNext', + 'poliJiwaNext', + 'poliTradisionalNext' + )); + } +} diff --git a/app/Http/Controllers/LandingController.php b/app/Http/Controllers/LandingController.php new file mode 100644 index 0000000..f452c74 --- /dev/null +++ b/app/Http/Controllers/LandingController.php @@ -0,0 +1,13 @@ +ttsService = new TTSService(); + } + + /** + * Generate TTS for queue call + */ + public function generateQueueCall(Request $request) + { + $request->validate([ + 'poli_name' => 'required|string', + 'queue_number' => 'required|string' + ]); + + try { + $result = $this->ttsService->generateQueueCall( + $request->poli_name, + $request->queue_number + ); + + return response()->json($result); + } catch (\Exception $e) { + return response()->json([ + 'success' => false, + 'message' => 'Error generating TTS: ' . $e->getMessage() + ], 500); + } + } + + /** + * Get complete audio sequence for queue call + */ + public function getAudioSequence(Request $request) + { + $request->validate([ + 'poli_name' => 'required|string', + 'queue_number' => 'required|string' + ]); + + try { + $audioSequence = $this->ttsService->createCompleteAudioSequence( + $request->poli_name, + $request->queue_number + ); + + return response()->json([ + 'success' => true, + 'audio_sequence' => $audioSequence + ]); + } catch (\Exception $e) { + return response()->json([ + 'success' => false, + 'message' => 'Error creating audio sequence: ' . $e->getMessage() + ], 500); + } + } + + /** + * Play audio sequence on display + */ + public function playAudioSequence(Request $request) + { + $request->validate([ + 'antrian_id' => 'required|exists:antrians,id' + ]); + + try { + $antrian = Antrian::with('poli')->findOrFail($request->antrian_id); + + $audioSequence = $this->ttsService->createCompleteAudioSequence( + $antrian->poli->nama_poli, + $antrian->no_antrian + ); + + return response()->json([ + 'success' => true, + 'audio_sequence' => $audioSequence, + 'poli_name' => $antrian->poli->nama_poli, + 'queue_number' => $antrian->no_antrian + ]); + } catch (\Exception $e) { + return response()->json([ + 'success' => false, + 'message' => 'Error playing audio sequence: ' . $e->getMessage() + ], 500); + } + } +} diff --git a/app/Models/Admin.php b/app/Models/Admin.php new file mode 100644 index 0000000..814ee4d --- /dev/null +++ b/app/Models/Admin.php @@ -0,0 +1,31 @@ + 'hashed', + ]; + } +} diff --git a/app/Models/Antrian.php b/app/Models/Antrian.php new file mode 100644 index 0000000..86b220e --- /dev/null +++ b/app/Models/Antrian.php @@ -0,0 +1,49 @@ + 'date', + 'waktu_panggil' => 'datetime', + 'is_call' => 'boolean', + ]; + + public function user() + { + return $this->belongsTo(User::class); + } + + public function poli() + { + return $this->belongsTo(Poli::class); + } + + public function loket() + { + return $this->belongsTo(Loket::class); + } + + public function riwayatPanggilan() + { + return $this->hasMany(RiwayatPanggilan::class); + } +} diff --git a/app/Models/Loket.php b/app/Models/Loket.php new file mode 100644 index 0000000..4a5733c --- /dev/null +++ b/app/Models/Loket.php @@ -0,0 +1,19 @@ +hasMany(Antrian::class); + } +} diff --git a/app/Models/Poli.php b/app/Models/Poli.php new file mode 100644 index 0000000..8d0f980 --- /dev/null +++ b/app/Models/Poli.php @@ -0,0 +1,19 @@ +hasMany(User::class); + } +} diff --git a/app/Models/RiwayatPanggilan.php b/app/Models/RiwayatPanggilan.php new file mode 100644 index 0000000..ec8e465 --- /dev/null +++ b/app/Models/RiwayatPanggilan.php @@ -0,0 +1,23 @@ + 'datetime', + ]; + + public function antrian() + { + return $this->belongsTo(Antrian::class); + } +} diff --git a/app/Models/User.php b/app/Models/User.php new file mode 100644 index 0000000..1199a88 --- /dev/null +++ b/app/Models/User.php @@ -0,0 +1,57 @@ + */ + use HasFactory, Notifiable; + + /** + * The attributes that are mass assignable. + * + * @var list + */ + protected $fillable = [ + 'nama', + 'alamat', + 'jenis_kelamin', + 'no_hp', + 'no_ktp', + 'pekerjaan', + 'password', + ]; + + /** + * The attributes that should be hidden for serialization. + * + * @var list + */ + protected $hidden = [ + 'password', + 'remember_token', + ]; + + /** + * Get the attributes that should be cast. + * + * @return array + */ + protected function casts(): array + { + return [ + 'email_verified_at' => 'datetime', + 'password' => 'hashed', + ]; + } + + public function antrians() + { + return $this->hasMany(Antrian::class); + } +} diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php new file mode 100644 index 0000000..452e6b6 --- /dev/null +++ b/app/Providers/AppServiceProvider.php @@ -0,0 +1,24 @@ +apiKey = config('services.google.tts_api_key'); + } + + /** + * Generate TTS audio for queue call + */ + public function generateQueueCall($poliName, $queueNumber) + { + try { + // Create the text to be spoken + $text = "Nomor antrian {$queueNumber}, silakan menuju ke {$poliName}"; + + // Generate TTS audio + $audioContent = $this->synthesizeSpeech($text); + + if ($audioContent) { + // Save audio file + $filename = "queue_call_{$queueNumber}_{$poliName}_" . time() . ".mp3"; + $filepath = "audio/queue_calls/" . $filename; + + Storage::disk('public')->put($filepath, base64_decode($audioContent)); + + return [ + 'success' => true, + 'audio_url' => asset('storage/' . $filepath), + 'filename' => $filename + ]; + } + + // Fallback: return browser TTS info + return [ + 'success' => true, + 'audio_url' => null, + 'filename' => null, + 'text' => $text, + 'use_browser_tts' => true + ]; + + } catch (\Exception $e) { + return [ + 'success' => false, + 'message' => 'Error generating TTS: ' . $e->getMessage() + ]; + } + } + + /** + * Synthesize speech using Google TTS API + */ + private function synthesizeSpeech($text) + { + if (!$this->apiKey) { + // Fallback: use browser's built-in TTS + return null; + } + + $requestData = [ + 'input' => [ + 'text' => $text + ], + 'voice' => [ + 'languageCode' => 'id-ID', + 'name' => 'id-ID-Wavenet-A', // More natural and fluent Indonesian female voice + 'ssmlGender' => 'FEMALE' + ], + 'audioConfig' => [ + 'audioEncoding' => 'MP3', + 'speakingRate' => 0.85, // Slightly faster for more natural flow + 'pitch' => 0, + 'volumeGainDb' => 0 + ] + ]; + + try { + $response = Http::withHeaders([ + 'Content-Type' => 'application/json', + ])->post($this->baseUrl . '?key=' . $this->apiKey, $requestData); + + if ($response->successful()) { + $data = $response->json(); + return $data['audioContent'] ?? null; + } + + return null; + } catch (\Exception $e) { + return null; + } + } + + /** + * Create complete audio sequence for queue call + */ + public function createCompleteAudioSequence($poliName, $queueNumber) + { + $audioFiles = []; + + // 1. Attention sound + $attentionSound = asset('assets/music/call-to-attention-123107.mp3'); + $audioFiles[] = [ + 'type' => 'attention', + 'url' => $attentionSound, + 'duration' => 2000 // 2 seconds + ]; + + // 2. TTS for poli name and number + $ttsResult = $this->generateQueueCall($poliName, $queueNumber); + if ($ttsResult['success']) { + if ($ttsResult['use_browser_tts']) { + // Use browser TTS + $audioFiles[] = [ + 'type' => 'browser_tts', + 'text' => $ttsResult['text'], + 'duration' => 4000 // 4 seconds + ]; + } else { + // Use generated audio file + $audioFiles[] = [ + 'type' => 'tts', + 'url' => $ttsResult['audio_url'], + 'duration' => 4000 // 4 seconds + ]; + } + } + + // 3. Final attention sound + $audioFiles[] = [ + 'type' => 'attention', + 'url' => $attentionSound, + 'duration' => 2000 // 2 seconds + ]; + + return $audioFiles; + } +} diff --git a/artisan b/artisan new file mode 100644 index 0000000..c35e31d --- /dev/null +++ b/artisan @@ -0,0 +1,18 @@ +#!/usr/bin/env php +handleCommand(new ArgvInput); + +exit($status); diff --git a/bootstrap/app.php b/bootstrap/app.php new file mode 100644 index 0000000..c183276 --- /dev/null +++ b/bootstrap/app.php @@ -0,0 +1,18 @@ +withRouting( + web: __DIR__.'/../routes/web.php', + commands: __DIR__.'/../routes/console.php', + health: '/up', + ) + ->withMiddleware(function (Middleware $middleware): void { + // + }) + ->withExceptions(function (Exceptions $exceptions): void { + // + })->create(); diff --git a/bootstrap/cache/.gitignore b/bootstrap/cache/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/bootstrap/cache/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/bootstrap/providers.php b/bootstrap/providers.php new file mode 100644 index 0000000..38b258d --- /dev/null +++ b/bootstrap/providers.php @@ -0,0 +1,5 @@ +=5.0.0" + }, + "require-dev": { + "doctrine/dbal": "^4.0.0", + "nesbot/carbon": "^2.71.0 || ^3.0.0", + "phpunit/phpunit": "^10.3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Carbon\\Doctrine\\": "src/Carbon/Doctrine/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "KyleKatarn", + "email": "kylekatarnls@gmail.com" + } + ], + "description": "Types to use Carbon in Doctrine", + "keywords": [ + "carbon", + "date", + "datetime", + "doctrine", + "time" + ], + "support": { + "issues": "https://github.com/CarbonPHP/carbon-doctrine-types/issues", + "source": "https://github.com/CarbonPHP/carbon-doctrine-types/tree/3.2.0" + }, + "funding": [ + { + "url": "https://github.com/kylekatarnls", + "type": "github" + }, + { + "url": "https://opencollective.com/Carbon", + "type": "open_collective" + }, + { + "url": "https://tidelift.com/funding/github/packagist/nesbot/carbon", + "type": "tidelift" + } + ], + "time": "2024-02-09T16:56:22+00:00" + }, + { + "name": "dflydev/dot-access-data", + "version": "v3.0.3", + "source": { + "type": "git", + "url": "https://github.com/dflydev/dflydev-dot-access-data.git", + "reference": "a23a2bf4f31d3518f3ecb38660c95715dfead60f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dflydev/dflydev-dot-access-data/zipball/a23a2bf4f31d3518f3ecb38660c95715dfead60f", + "reference": "a23a2bf4f31d3518f3ecb38660c95715dfead60f", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^0.12.42", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.3", + "scrutinizer/ocular": "1.6.0", + "squizlabs/php_codesniffer": "^3.5", + "vimeo/psalm": "^4.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Dflydev\\DotAccessData\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Dragonfly Development Inc.", + "email": "info@dflydev.com", + "homepage": "http://dflydev.com" + }, + { + "name": "Beau Simensen", + "email": "beau@dflydev.com", + "homepage": "http://beausimensen.com" + }, + { + "name": "Carlos Frutos", + "email": "carlos@kiwing.it", + "homepage": "https://github.com/cfrutos" + }, + { + "name": "Colin O'Dell", + "email": "colinodell@gmail.com", + "homepage": "https://www.colinodell.com" + } + ], + "description": "Given a deep data structure, access data by dot notation.", + "homepage": "https://github.com/dflydev/dflydev-dot-access-data", + "keywords": [ + "access", + "data", + "dot", + "notation" + ], + "support": { + "issues": "https://github.com/dflydev/dflydev-dot-access-data/issues", + "source": "https://github.com/dflydev/dflydev-dot-access-data/tree/v3.0.3" + }, + "time": "2024-07-08T12:26:09+00:00" + }, + { + "name": "doctrine/inflector", + "version": "2.0.10", + "source": { + "type": "git", + "url": "https://github.com/doctrine/inflector.git", + "reference": "5817d0659c5b50c9b950feb9af7b9668e2c436bc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/inflector/zipball/5817d0659c5b50c9b950feb9af7b9668e2c436bc", + "reference": "5817d0659c5b50c9b950feb9af7b9668e2c436bc", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^11.0", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-phpunit": "^1.1", + "phpstan/phpstan-strict-rules": "^1.3", + "phpunit/phpunit": "^8.5 || ^9.5", + "vimeo/psalm": "^4.25 || ^5.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Inflector\\": "lib/Doctrine/Inflector" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "PHP Doctrine Inflector is a small library that can perform string manipulations with regard to upper/lowercase and singular/plural forms of words.", + "homepage": "https://www.doctrine-project.org/projects/inflector.html", + "keywords": [ + "inflection", + "inflector", + "lowercase", + "manipulation", + "php", + "plural", + "singular", + "strings", + "uppercase", + "words" + ], + "support": { + "issues": "https://github.com/doctrine/inflector/issues", + "source": "https://github.com/doctrine/inflector/tree/2.0.10" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finflector", + "type": "tidelift" + } + ], + "time": "2024-02-18T20:23:39+00:00" + }, + { + "name": "doctrine/lexer", + "version": "3.0.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/lexer.git", + "reference": "31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd", + "reference": "31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd", + "shasum": "" + }, + "require": { + "php": "^8.1" + }, + "require-dev": { + "doctrine/coding-standard": "^12", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^10.5", + "psalm/plugin-phpunit": "^0.18.3", + "vimeo/psalm": "^5.21" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Common\\Lexer\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.", + "homepage": "https://www.doctrine-project.org/projects/lexer.html", + "keywords": [ + "annotations", + "docblock", + "lexer", + "parser", + "php" + ], + "support": { + "issues": "https://github.com/doctrine/lexer/issues", + "source": "https://github.com/doctrine/lexer/tree/3.0.1" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Flexer", + "type": "tidelift" + } + ], + "time": "2024-02-05T11:56:58+00:00" + }, + { + "name": "dompdf/dompdf", + "version": "v3.1.0", + "source": { + "type": "git", + "url": "https://github.com/dompdf/dompdf.git", + "reference": "a51bd7a063a65499446919286fb18b518177155a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dompdf/dompdf/zipball/a51bd7a063a65499446919286fb18b518177155a", + "reference": "a51bd7a063a65499446919286fb18b518177155a", + "shasum": "" + }, + "require": { + "dompdf/php-font-lib": "^1.0.0", + "dompdf/php-svg-lib": "^1.0.0", + "ext-dom": "*", + "ext-mbstring": "*", + "masterminds/html5": "^2.0", + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "ext-gd": "*", + "ext-json": "*", + "ext-zip": "*", + "mockery/mockery": "^1.3", + "phpunit/phpunit": "^7.5 || ^8 || ^9 || ^10 || ^11", + "squizlabs/php_codesniffer": "^3.5", + "symfony/process": "^4.4 || ^5.4 || ^6.2 || ^7.0" + }, + "suggest": { + "ext-gd": "Needed to process images", + "ext-gmagick": "Improves image processing performance", + "ext-imagick": "Improves image processing performance", + "ext-zlib": "Needed for pdf stream compression" + }, + "type": "library", + "autoload": { + "psr-4": { + "Dompdf\\": "src/" + }, + "classmap": [ + "lib/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-2.1" + ], + "authors": [ + { + "name": "The Dompdf Community", + "homepage": "https://github.com/dompdf/dompdf/blob/master/AUTHORS.md" + } + ], + "description": "DOMPDF is a CSS 2.1 compliant HTML to PDF converter", + "homepage": "https://github.com/dompdf/dompdf", + "support": { + "issues": "https://github.com/dompdf/dompdf/issues", + "source": "https://github.com/dompdf/dompdf/tree/v3.1.0" + }, + "time": "2025-01-15T14:09:04+00:00" + }, + { + "name": "dompdf/php-font-lib", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/dompdf/php-font-lib.git", + "reference": "6137b7d4232b7f16c882c75e4ca3991dbcf6fe2d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dompdf/php-font-lib/zipball/6137b7d4232b7f16c882c75e4ca3991dbcf6fe2d", + "reference": "6137b7d4232b7f16c882c75e4ca3991dbcf6fe2d", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "symfony/phpunit-bridge": "^3 || ^4 || ^5 || ^6" + }, + "type": "library", + "autoload": { + "psr-4": { + "FontLib\\": "src/FontLib" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-2.1-or-later" + ], + "authors": [ + { + "name": "The FontLib Community", + "homepage": "https://github.com/dompdf/php-font-lib/blob/master/AUTHORS.md" + } + ], + "description": "A library to read, parse, export and make subsets of different types of font files.", + "homepage": "https://github.com/dompdf/php-font-lib", + "support": { + "issues": "https://github.com/dompdf/php-font-lib/issues", + "source": "https://github.com/dompdf/php-font-lib/tree/1.0.1" + }, + "time": "2024-12-02T14:37:59+00:00" + }, + { + "name": "dompdf/php-svg-lib", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/dompdf/php-svg-lib.git", + "reference": "eb045e518185298eb6ff8d80d0d0c6b17aecd9af" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dompdf/php-svg-lib/zipball/eb045e518185298eb6ff8d80d0d0c6b17aecd9af", + "reference": "eb045e518185298eb6ff8d80d0d0c6b17aecd9af", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": "^7.1 || ^8.0", + "sabberworm/php-css-parser": "^8.4" + }, + "require-dev": { + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Svg\\": "src/Svg" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-3.0-or-later" + ], + "authors": [ + { + "name": "The SvgLib Community", + "homepage": "https://github.com/dompdf/php-svg-lib/blob/master/AUTHORS.md" + } + ], + "description": "A library to read, parse and export to PDF SVG files.", + "homepage": "https://github.com/dompdf/php-svg-lib", + "support": { + "issues": "https://github.com/dompdf/php-svg-lib/issues", + "source": "https://github.com/dompdf/php-svg-lib/tree/1.0.0" + }, + "time": "2024-04-29T13:26:35+00:00" + }, + { + "name": "dragonmantank/cron-expression", + "version": "v3.4.0", + "source": { + "type": "git", + "url": "https://github.com/dragonmantank/cron-expression.git", + "reference": "8c784d071debd117328803d86b2097615b457500" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dragonmantank/cron-expression/zipball/8c784d071debd117328803d86b2097615b457500", + "reference": "8c784d071debd117328803d86b2097615b457500", + "shasum": "" + }, + "require": { + "php": "^7.2|^8.0", + "webmozart/assert": "^1.0" + }, + "replace": { + "mtdowling/cron-expression": "^1.0" + }, + "require-dev": { + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^1.0", + "phpunit/phpunit": "^7.0|^8.0|^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Cron\\": "src/Cron/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Chris Tankersley", + "email": "chris@ctankersley.com", + "homepage": "https://github.com/dragonmantank" + } + ], + "description": "CRON for PHP: Calculate the next or previous run date and determine if a CRON expression is due", + "keywords": [ + "cron", + "schedule" + ], + "support": { + "issues": "https://github.com/dragonmantank/cron-expression/issues", + "source": "https://github.com/dragonmantank/cron-expression/tree/v3.4.0" + }, + "funding": [ + { + "url": "https://github.com/dragonmantank", + "type": "github" + } + ], + "time": "2024-10-09T13:47:03+00:00" + }, + { + "name": "egulias/email-validator", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/egulias/EmailValidator.git", + "reference": "d42c8731f0624ad6bdc8d3e5e9a4524f68801cfa" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/d42c8731f0624ad6bdc8d3e5e9a4524f68801cfa", + "reference": "d42c8731f0624ad6bdc8d3e5e9a4524f68801cfa", + "shasum": "" + }, + "require": { + "doctrine/lexer": "^2.0 || ^3.0", + "php": ">=8.1", + "symfony/polyfill-intl-idn": "^1.26" + }, + "require-dev": { + "phpunit/phpunit": "^10.2", + "vimeo/psalm": "^5.12" + }, + "suggest": { + "ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Egulias\\EmailValidator\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eduardo Gulias Davis" + } + ], + "description": "A library for validating emails against several RFCs", + "homepage": "https://github.com/egulias/EmailValidator", + "keywords": [ + "email", + "emailvalidation", + "emailvalidator", + "validation", + "validator" + ], + "support": { + "issues": "https://github.com/egulias/EmailValidator/issues", + "source": "https://github.com/egulias/EmailValidator/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/egulias", + "type": "github" + } + ], + "time": "2025-03-06T22:45:56+00:00" + }, + { + "name": "fruitcake/php-cors", + "version": "v1.3.0", + "source": { + "type": "git", + "url": "https://github.com/fruitcake/php-cors.git", + "reference": "3d158f36e7875e2f040f37bc0573956240a5a38b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/fruitcake/php-cors/zipball/3d158f36e7875e2f040f37bc0573956240a5a38b", + "reference": "3d158f36e7875e2f040f37bc0573956240a5a38b", + "shasum": "" + }, + "require": { + "php": "^7.4|^8.0", + "symfony/http-foundation": "^4.4|^5.4|^6|^7" + }, + "require-dev": { + "phpstan/phpstan": "^1.4", + "phpunit/phpunit": "^9", + "squizlabs/php_codesniffer": "^3.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2-dev" + } + }, + "autoload": { + "psr-4": { + "Fruitcake\\Cors\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fruitcake", + "homepage": "https://fruitcake.nl" + }, + { + "name": "Barryvdh", + "email": "barryvdh@gmail.com" + } + ], + "description": "Cross-origin resource sharing library for the Symfony HttpFoundation", + "homepage": "https://github.com/fruitcake/php-cors", + "keywords": [ + "cors", + "laravel", + "symfony" + ], + "support": { + "issues": "https://github.com/fruitcake/php-cors/issues", + "source": "https://github.com/fruitcake/php-cors/tree/v1.3.0" + }, + "funding": [ + { + "url": "https://fruitcake.nl", + "type": "custom" + }, + { + "url": "https://github.com/barryvdh", + "type": "github" + } + ], + "time": "2023-10-12T05:21:21+00:00" + }, + { + "name": "graham-campbell/result-type", + "version": "v1.1.3", + "source": { + "type": "git", + "url": "https://github.com/GrahamCampbell/Result-Type.git", + "reference": "3ba905c11371512af9d9bdd27d99b782216b6945" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/3ba905c11371512af9d9bdd27d99b782216b6945", + "reference": "3ba905c11371512af9d9bdd27d99b782216b6945", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0", + "phpoption/phpoption": "^1.9.3" + }, + "require-dev": { + "phpunit/phpunit": "^8.5.39 || ^9.6.20 || ^10.5.28" + }, + "type": "library", + "autoload": { + "psr-4": { + "GrahamCampbell\\ResultType\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + } + ], + "description": "An Implementation Of The Result Type", + "keywords": [ + "Graham Campbell", + "GrahamCampbell", + "Result Type", + "Result-Type", + "result" + ], + "support": { + "issues": "https://github.com/GrahamCampbell/Result-Type/issues", + "source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.1.3" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/graham-campbell/result-type", + "type": "tidelift" + } + ], + "time": "2024-07-20T21:45:45+00:00" + }, + { + "name": "guzzlehttp/guzzle", + "version": "7.9.3", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "7b2f29fe81dc4da0ca0ea7d42107a0845946ea77" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/7b2f29fe81dc4da0ca0ea7d42107a0845946ea77", + "reference": "7b2f29fe81dc4da0ca0ea7d42107a0845946ea77", + "shasum": "" + }, + "require": { + "ext-json": "*", + "guzzlehttp/promises": "^1.5.3 || ^2.0.3", + "guzzlehttp/psr7": "^2.7.0", + "php": "^7.2.5 || ^8.0", + "psr/http-client": "^1.0", + "symfony/deprecation-contracts": "^2.2 || ^3.0" + }, + "provide": { + "psr/http-client-implementation": "1.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "ext-curl": "*", + "guzzle/client-integration-tests": "3.0.2", + "php-http/message-factory": "^1.1", + "phpunit/phpunit": "^8.5.39 || ^9.6.20", + "psr/log": "^1.1 || ^2.0 || ^3.0" + }, + "suggest": { + "ext-curl": "Required for CURL handler support", + "ext-intl": "Required for Internationalized Domain Name (IDN) support", + "psr/log": "Required for using the Log middleware" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "GuzzleHttp\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Jeremy Lindblom", + "email": "jeremeamia@gmail.com", + "homepage": "https://github.com/jeremeamia" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "MĆ”rk SĆ”gi-KazĆ”r", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "Guzzle is a PHP HTTP client library", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "psr-18", + "psr-7", + "rest", + "web service" + ], + "support": { + "issues": "https://github.com/guzzle/guzzle/issues", + "source": "https://github.com/guzzle/guzzle/tree/7.9.3" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/guzzle", + "type": "tidelift" + } + ], + "time": "2025-03-27T13:37:11+00:00" + }, + { + "name": "guzzlehttp/promises", + "version": "2.2.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "7c69f28996b0a6920945dd20b3857e499d9ca96c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/promises/zipball/7c69f28996b0a6920945dd20b3857e499d9ca96c", + "reference": "7c69f28996b0a6920945dd20b3857e499d9ca96c", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "phpunit/phpunit": "^8.5.39 || ^9.6.20" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Promise\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "Guzzle promises library", + "keywords": [ + "promise" + ], + "support": { + "issues": "https://github.com/guzzle/promises/issues", + "source": "https://github.com/guzzle/promises/tree/2.2.0" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises", + "type": "tidelift" + } + ], + "time": "2025-03-27T13:27:01+00:00" + }, + { + "name": "guzzlehttp/psr7", + "version": "2.7.1", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "c2270caaabe631b3b44c85f99e5a04bbb8060d16" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/c2270caaabe631b3b44c85f99e5a04bbb8060d16", + "reference": "c2270caaabe631b3b44c85f99e5a04bbb8060d16", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.1 || ^2.0", + "ralouphie/getallheaders": "^3.0" + }, + "provide": { + "psr/http-factory-implementation": "1.0", + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "http-interop/http-factory-tests": "0.9.0", + "phpunit/phpunit": "^8.5.39 || ^9.6.20" + }, + "suggest": { + "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Psr7\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "MĆ”rk SĆ”gi-KazĆ”r", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + }, + { + "name": "MĆ”rk SĆ”gi-KazĆ”r", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://sagikazarmark.hu" + } + ], + "description": "PSR-7 message implementation that also provides common utility methods", + "keywords": [ + "http", + "message", + "psr-7", + "request", + "response", + "stream", + "uri", + "url" + ], + "support": { + "issues": "https://github.com/guzzle/psr7/issues", + "source": "https://github.com/guzzle/psr7/tree/2.7.1" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/psr7", + "type": "tidelift" + } + ], + "time": "2025-03-27T12:30:47+00:00" + }, + { + "name": "guzzlehttp/uri-template", + "version": "v1.0.4", + "source": { + "type": "git", + "url": "https://github.com/guzzle/uri-template.git", + "reference": "30e286560c137526eccd4ce21b2de477ab0676d2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/uri-template/zipball/30e286560c137526eccd4ce21b2de477ab0676d2", + "reference": "30e286560c137526eccd4ce21b2de477ab0676d2", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0", + "symfony/polyfill-php80": "^1.24" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "phpunit/phpunit": "^8.5.36 || ^9.6.15", + "uri-template/tests": "1.0.0" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\UriTemplate\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + } + ], + "description": "A polyfill class for uri_template of PHP", + "keywords": [ + "guzzlehttp", + "uri-template" + ], + "support": { + "issues": "https://github.com/guzzle/uri-template/issues", + "source": "https://github.com/guzzle/uri-template/tree/v1.0.4" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/uri-template", + "type": "tidelift" + } + ], + "time": "2025-02-03T10:55:03+00:00" + }, + { + "name": "laravel/framework", + "version": "v12.22.0", + "source": { + "type": "git", + "url": "https://github.com/laravel/framework.git", + "reference": "6ab00c913ef6ec6fad0bd506f7452c0bb9e792c3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/framework/zipball/6ab00c913ef6ec6fad0bd506f7452c0bb9e792c3", + "reference": "6ab00c913ef6ec6fad0bd506f7452c0bb9e792c3", + "shasum": "" + }, + "require": { + "brick/math": "^0.11|^0.12|^0.13", + "composer-runtime-api": "^2.2", + "doctrine/inflector": "^2.0.5", + "dragonmantank/cron-expression": "^3.4", + "egulias/email-validator": "^3.2.1|^4.0", + "ext-ctype": "*", + "ext-filter": "*", + "ext-hash": "*", + "ext-mbstring": "*", + "ext-openssl": "*", + "ext-session": "*", + "ext-tokenizer": "*", + "fruitcake/php-cors": "^1.3", + "guzzlehttp/guzzle": "^7.8.2", + "guzzlehttp/uri-template": "^1.0", + "laravel/prompts": "^0.3.0", + "laravel/serializable-closure": "^1.3|^2.0", + "league/commonmark": "^2.7", + "league/flysystem": "^3.25.1", + "league/flysystem-local": "^3.25.1", + "league/uri": "^7.5.1", + "monolog/monolog": "^3.0", + "nesbot/carbon": "^3.8.4", + "nunomaduro/termwind": "^2.0", + "php": "^8.2", + "psr/container": "^1.1.1|^2.0.1", + "psr/log": "^1.0|^2.0|^3.0", + "psr/simple-cache": "^1.0|^2.0|^3.0", + "ramsey/uuid": "^4.7", + "symfony/console": "^7.2.0", + "symfony/error-handler": "^7.2.0", + "symfony/finder": "^7.2.0", + "symfony/http-foundation": "^7.2.0", + "symfony/http-kernel": "^7.2.0", + "symfony/mailer": "^7.2.0", + "symfony/mime": "^7.2.0", + "symfony/polyfill-php83": "^1.31", + "symfony/process": "^7.2.0", + "symfony/routing": "^7.2.0", + "symfony/uid": "^7.2.0", + "symfony/var-dumper": "^7.2.0", + "tijsverkoyen/css-to-inline-styles": "^2.2.5", + "vlucas/phpdotenv": "^5.6.1", + "voku/portable-ascii": "^2.0.2" + }, + "conflict": { + "tightenco/collect": "<5.5.33" + }, + "provide": { + "psr/container-implementation": "1.1|2.0", + "psr/log-implementation": "1.0|2.0|3.0", + "psr/simple-cache-implementation": "1.0|2.0|3.0" + }, + "replace": { + "illuminate/auth": "self.version", + "illuminate/broadcasting": "self.version", + "illuminate/bus": "self.version", + "illuminate/cache": "self.version", + "illuminate/collections": "self.version", + "illuminate/concurrency": "self.version", + "illuminate/conditionable": "self.version", + "illuminate/config": "self.version", + "illuminate/console": "self.version", + "illuminate/container": "self.version", + "illuminate/contracts": "self.version", + "illuminate/cookie": "self.version", + "illuminate/database": "self.version", + "illuminate/encryption": "self.version", + "illuminate/events": "self.version", + "illuminate/filesystem": "self.version", + "illuminate/hashing": "self.version", + "illuminate/http": "self.version", + "illuminate/log": "self.version", + "illuminate/macroable": "self.version", + "illuminate/mail": "self.version", + "illuminate/notifications": "self.version", + "illuminate/pagination": "self.version", + "illuminate/pipeline": "self.version", + "illuminate/process": "self.version", + "illuminate/queue": "self.version", + "illuminate/redis": "self.version", + "illuminate/routing": "self.version", + "illuminate/session": "self.version", + "illuminate/support": "self.version", + "illuminate/testing": "self.version", + "illuminate/translation": "self.version", + "illuminate/validation": "self.version", + "illuminate/view": "self.version", + "spatie/once": "*" + }, + "require-dev": { + "ably/ably-php": "^1.0", + "aws/aws-sdk-php": "^3.322.9", + "ext-gmp": "*", + "fakerphp/faker": "^1.24", + "guzzlehttp/promises": "^2.0.3", + "guzzlehttp/psr7": "^2.4", + "laravel/pint": "^1.18", + "league/flysystem-aws-s3-v3": "^3.25.1", + "league/flysystem-ftp": "^3.25.1", + "league/flysystem-path-prefixing": "^3.25.1", + "league/flysystem-read-only": "^3.25.1", + "league/flysystem-sftp-v3": "^3.25.1", + "mockery/mockery": "^1.6.10", + "orchestra/testbench-core": "^10.0.0", + "pda/pheanstalk": "^5.0.6|^7.0.0", + "php-http/discovery": "^1.15", + "phpstan/phpstan": "^2.0", + "phpunit/phpunit": "^10.5.35|^11.5.3|^12.0.1", + "predis/predis": "^2.3|^3.0", + "resend/resend-php": "^0.10.0", + "symfony/cache": "^7.2.0", + "symfony/http-client": "^7.2.0", + "symfony/psr-http-message-bridge": "^7.2.0", + "symfony/translation": "^7.2.0" + }, + "suggest": { + "ably/ably-php": "Required to use the Ably broadcast driver (^1.0).", + "aws/aws-sdk-php": "Required to use the SQS queue driver, DynamoDb failed job storage, and SES mail driver (^3.322.9).", + "brianium/paratest": "Required to run tests in parallel (^7.0|^8.0).", + "ext-apcu": "Required to use the APC cache driver.", + "ext-fileinfo": "Required to use the Filesystem class.", + "ext-ftp": "Required to use the Flysystem FTP driver.", + "ext-gd": "Required to use Illuminate\\Http\\Testing\\FileFactory::image().", + "ext-memcached": "Required to use the memcache cache driver.", + "ext-pcntl": "Required to use all features of the queue worker and console signal trapping.", + "ext-pdo": "Required to use all database features.", + "ext-posix": "Required to use all features of the queue worker.", + "ext-redis": "Required to use the Redis cache and queue drivers (^4.0|^5.0|^6.0).", + "fakerphp/faker": "Required to use the eloquent factory builder (^1.9.1).", + "filp/whoops": "Required for friendly error pages in development (^2.14.3).", + "laravel/tinker": "Required to use the tinker console command (^2.0).", + "league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (^3.25.1).", + "league/flysystem-ftp": "Required to use the Flysystem FTP driver (^3.25.1).", + "league/flysystem-path-prefixing": "Required to use the scoped driver (^3.25.1).", + "league/flysystem-read-only": "Required to use read-only disks (^3.25.1)", + "league/flysystem-sftp-v3": "Required to use the Flysystem SFTP driver (^3.25.1).", + "mockery/mockery": "Required to use mocking (^1.6).", + "pda/pheanstalk": "Required to use the beanstalk queue driver (^5.0).", + "php-http/discovery": "Required to use PSR-7 bridging features (^1.15).", + "phpunit/phpunit": "Required to use assertions and run tests (^10.5.35|^11.5.3|^12.0.1).", + "predis/predis": "Required to use the predis connector (^2.3|^3.0).", + "psr/http-message": "Required to allow Storage::put to accept a StreamInterface (^1.0).", + "pusher/pusher-php-server": "Required to use the Pusher broadcast driver (^6.0|^7.0).", + "resend/resend-php": "Required to enable support for the Resend mail transport (^0.10.0).", + "symfony/cache": "Required to PSR-6 cache bridge (^7.2).", + "symfony/filesystem": "Required to enable support for relative symbolic links (^7.2).", + "symfony/http-client": "Required to enable support for the Symfony API mail transports (^7.2).", + "symfony/mailgun-mailer": "Required to enable support for the Mailgun mail transport (^7.2).", + "symfony/postmark-mailer": "Required to enable support for the Postmark mail transport (^7.2).", + "symfony/psr-http-message-bridge": "Required to use PSR-7 bridging features (^7.2)." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "12.x-dev" + } + }, + "autoload": { + "files": [ + "src/Illuminate/Collections/functions.php", + "src/Illuminate/Collections/helpers.php", + "src/Illuminate/Events/functions.php", + "src/Illuminate/Filesystem/functions.php", + "src/Illuminate/Foundation/helpers.php", + "src/Illuminate/Log/functions.php", + "src/Illuminate/Support/functions.php", + "src/Illuminate/Support/helpers.php" + ], + "psr-4": { + "Illuminate\\": "src/Illuminate/", + "Illuminate\\Support\\": [ + "src/Illuminate/Macroable/", + "src/Illuminate/Collections/", + "src/Illuminate/Conditionable/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Laravel Framework.", + "homepage": "https://laravel.com", + "keywords": [ + "framework", + "laravel" + ], + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "time": "2025-08-07T13:49:53+00:00" + }, + { + "name": "laravel/prompts", + "version": "v0.3.6", + "source": { + "type": "git", + "url": "https://github.com/laravel/prompts.git", + "reference": "86a8b692e8661d0fb308cec64f3d176821323077" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/prompts/zipball/86a8b692e8661d0fb308cec64f3d176821323077", + "reference": "86a8b692e8661d0fb308cec64f3d176821323077", + "shasum": "" + }, + "require": { + "composer-runtime-api": "^2.2", + "ext-mbstring": "*", + "php": "^8.1", + "symfony/console": "^6.2|^7.0" + }, + "conflict": { + "illuminate/console": ">=10.17.0 <10.25.0", + "laravel/framework": ">=10.17.0 <10.25.0" + }, + "require-dev": { + "illuminate/collections": "^10.0|^11.0|^12.0", + "mockery/mockery": "^1.5", + "pestphp/pest": "^2.3|^3.4", + "phpstan/phpstan": "^1.11", + "phpstan/phpstan-mockery": "^1.1" + }, + "suggest": { + "ext-pcntl": "Required for the spinner to be animated." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "0.3.x-dev" + } + }, + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "Laravel\\Prompts\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Add beautiful and user-friendly forms to your command-line applications.", + "support": { + "issues": "https://github.com/laravel/prompts/issues", + "source": "https://github.com/laravel/prompts/tree/v0.3.6" + }, + "time": "2025-07-07T14:17:42+00:00" + }, + { + "name": "laravel/sanctum", + "version": "v4.2.0", + "source": { + "type": "git", + "url": "https://github.com/laravel/sanctum.git", + "reference": "fd6df4f79f48a72992e8d29a9c0ee25422a0d677" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/sanctum/zipball/fd6df4f79f48a72992e8d29a9c0ee25422a0d677", + "reference": "fd6df4f79f48a72992e8d29a9c0ee25422a0d677", + "shasum": "" + }, + "require": { + "ext-json": "*", + "illuminate/console": "^11.0|^12.0", + "illuminate/contracts": "^11.0|^12.0", + "illuminate/database": "^11.0|^12.0", + "illuminate/support": "^11.0|^12.0", + "php": "^8.2", + "symfony/console": "^7.0" + }, + "require-dev": { + "mockery/mockery": "^1.6", + "orchestra/testbench": "^9.0|^10.0", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^11.3" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Laravel\\Sanctum\\SanctumServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Laravel\\Sanctum\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "Laravel Sanctum provides a featherweight authentication system for SPAs and simple APIs.", + "keywords": [ + "auth", + "laravel", + "sanctum" + ], + "support": { + "issues": "https://github.com/laravel/sanctum/issues", + "source": "https://github.com/laravel/sanctum" + }, + "time": "2025-07-09T19:45:24+00:00" + }, + { + "name": "laravel/serializable-closure", + "version": "v2.0.4", + "source": { + "type": "git", + "url": "https://github.com/laravel/serializable-closure.git", + "reference": "b352cf0534aa1ae6b4d825d1e762e35d43f8a841" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/b352cf0534aa1ae6b4d825d1e762e35d43f8a841", + "reference": "b352cf0534aa1ae6b4d825d1e762e35d43f8a841", + "shasum": "" + }, + "require": { + "php": "^8.1" + }, + "require-dev": { + "illuminate/support": "^10.0|^11.0|^12.0", + "nesbot/carbon": "^2.67|^3.0", + "pestphp/pest": "^2.36|^3.0", + "phpstan/phpstan": "^2.0", + "symfony/var-dumper": "^6.2.0|^7.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Laravel\\SerializableClosure\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + }, + { + "name": "Nuno Maduro", + "email": "nuno@laravel.com" + } + ], + "description": "Laravel Serializable Closure provides an easy and secure way to serialize closures in PHP.", + "keywords": [ + "closure", + "laravel", + "serializable" + ], + "support": { + "issues": "https://github.com/laravel/serializable-closure/issues", + "source": "https://github.com/laravel/serializable-closure" + }, + "time": "2025-03-19T13:51:03+00:00" + }, + { + "name": "laravel/tinker", + "version": "v2.10.1", + "source": { + "type": "git", + "url": "https://github.com/laravel/tinker.git", + "reference": "22177cc71807d38f2810c6204d8f7183d88a57d3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/tinker/zipball/22177cc71807d38f2810c6204d8f7183d88a57d3", + "reference": "22177cc71807d38f2810c6204d8f7183d88a57d3", + "shasum": "" + }, + "require": { + "illuminate/console": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0|^12.0", + "illuminate/contracts": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0|^12.0", + "illuminate/support": "^6.0|^7.0|^8.0|^9.0|^10.0|^11.0|^12.0", + "php": "^7.2.5|^8.0", + "psy/psysh": "^0.11.1|^0.12.0", + "symfony/var-dumper": "^4.3.4|^5.0|^6.0|^7.0" + }, + "require-dev": { + "mockery/mockery": "~1.3.3|^1.4.2", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^8.5.8|^9.3.3|^10.0" + }, + "suggest": { + "illuminate/database": "The Illuminate Database package (^6.0|^7.0|^8.0|^9.0|^10.0|^11.0|^12.0)." + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Laravel\\Tinker\\TinkerServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Laravel\\Tinker\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "Powerful REPL for the Laravel framework.", + "keywords": [ + "REPL", + "Tinker", + "laravel", + "psysh" + ], + "support": { + "issues": "https://github.com/laravel/tinker/issues", + "source": "https://github.com/laravel/tinker/tree/v2.10.1" + }, + "time": "2025-01-27T14:24:01+00:00" + }, + { + "name": "league/commonmark", + "version": "2.7.1", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/commonmark.git", + "reference": "10732241927d3971d28e7ea7b5712721fa2296ca" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/10732241927d3971d28e7ea7b5712721fa2296ca", + "reference": "10732241927d3971d28e7ea7b5712721fa2296ca", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "league/config": "^1.1.1", + "php": "^7.4 || ^8.0", + "psr/event-dispatcher": "^1.0", + "symfony/deprecation-contracts": "^2.1 || ^3.0", + "symfony/polyfill-php80": "^1.16" + }, + "require-dev": { + "cebe/markdown": "^1.0", + "commonmark/cmark": "0.31.1", + "commonmark/commonmark.js": "0.31.1", + "composer/package-versions-deprecated": "^1.8", + "embed/embed": "^4.4", + "erusev/parsedown": "^1.0", + "ext-json": "*", + "github/gfm": "0.29.0", + "michelf/php-markdown": "^1.4 || ^2.0", + "nyholm/psr7": "^1.5", + "phpstan/phpstan": "^1.8.2", + "phpunit/phpunit": "^9.5.21 || ^10.5.9 || ^11.0.0", + "scrutinizer/ocular": "^1.8.1", + "symfony/finder": "^5.3 | ^6.0 | ^7.0", + "symfony/process": "^5.4 | ^6.0 | ^7.0", + "symfony/yaml": "^2.3 | ^3.0 | ^4.0 | ^5.0 | ^6.0 | ^7.0", + "unleashedtech/php-coding-standard": "^3.1.1", + "vimeo/psalm": "^4.24.0 || ^5.0.0 || ^6.0.0" + }, + "suggest": { + "symfony/yaml": "v2.3+ required if using the Front Matter extension" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.8-dev" + } + }, + "autoload": { + "psr-4": { + "League\\CommonMark\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Colin O'Dell", + "email": "colinodell@gmail.com", + "homepage": "https://www.colinodell.com", + "role": "Lead Developer" + } + ], + "description": "Highly-extensible PHP Markdown parser which fully supports the CommonMark spec and GitHub-Flavored Markdown (GFM)", + "homepage": "https://commonmark.thephpleague.com", + "keywords": [ + "commonmark", + "flavored", + "gfm", + "github", + "github-flavored", + "markdown", + "md", + "parser" + ], + "support": { + "docs": "https://commonmark.thephpleague.com/", + "forum": "https://github.com/thephpleague/commonmark/discussions", + "issues": "https://github.com/thephpleague/commonmark/issues", + "rss": "https://github.com/thephpleague/commonmark/releases.atom", + "source": "https://github.com/thephpleague/commonmark" + }, + "funding": [ + { + "url": "https://www.colinodell.com/sponsor", + "type": "custom" + }, + { + "url": "https://www.paypal.me/colinpodell/10.00", + "type": "custom" + }, + { + "url": "https://github.com/colinodell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/league/commonmark", + "type": "tidelift" + } + ], + "time": "2025-07-20T12:47:49+00:00" + }, + { + "name": "league/config", + "version": "v1.2.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/config.git", + "reference": "754b3604fb2984c71f4af4a9cbe7b57f346ec1f3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/config/zipball/754b3604fb2984c71f4af4a9cbe7b57f346ec1f3", + "reference": "754b3604fb2984c71f4af4a9cbe7b57f346ec1f3", + "shasum": "" + }, + "require": { + "dflydev/dot-access-data": "^3.0.1", + "nette/schema": "^1.2", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.8.2", + "phpunit/phpunit": "^9.5.5", + "scrutinizer/ocular": "^1.8.1", + "unleashedtech/php-coding-standard": "^3.1", + "vimeo/psalm": "^4.7.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.2-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Config\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Colin O'Dell", + "email": "colinodell@gmail.com", + "homepage": "https://www.colinodell.com", + "role": "Lead Developer" + } + ], + "description": "Define configuration arrays with strict schemas and access values with dot notation", + "homepage": "https://config.thephpleague.com", + "keywords": [ + "array", + "config", + "configuration", + "dot", + "dot-access", + "nested", + "schema" + ], + "support": { + "docs": "https://config.thephpleague.com/", + "issues": "https://github.com/thephpleague/config/issues", + "rss": "https://github.com/thephpleague/config/releases.atom", + "source": "https://github.com/thephpleague/config" + }, + "funding": [ + { + "url": "https://www.colinodell.com/sponsor", + "type": "custom" + }, + { + "url": "https://www.paypal.me/colinpodell/10.00", + "type": "custom" + }, + { + "url": "https://github.com/colinodell", + "type": "github" + } + ], + "time": "2022-12-11T20:36:23+00:00" + }, + { + "name": "league/flysystem", + "version": "3.30.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/flysystem.git", + "reference": "2203e3151755d874bb2943649dae1eb8533ac93e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/2203e3151755d874bb2943649dae1eb8533ac93e", + "reference": "2203e3151755d874bb2943649dae1eb8533ac93e", + "shasum": "" + }, + "require": { + "league/flysystem-local": "^3.0.0", + "league/mime-type-detection": "^1.0.0", + "php": "^8.0.2" + }, + "conflict": { + "async-aws/core": "<1.19.0", + "async-aws/s3": "<1.14.0", + "aws/aws-sdk-php": "3.209.31 || 3.210.0", + "guzzlehttp/guzzle": "<7.0", + "guzzlehttp/ringphp": "<1.1.1", + "phpseclib/phpseclib": "3.0.15", + "symfony/http-client": "<5.2" + }, + "require-dev": { + "async-aws/s3": "^1.5 || ^2.0", + "async-aws/simple-s3": "^1.1 || ^2.0", + "aws/aws-sdk-php": "^3.295.10", + "composer/semver": "^3.0", + "ext-fileinfo": "*", + "ext-ftp": "*", + "ext-mongodb": "^1.3|^2", + "ext-zip": "*", + "friendsofphp/php-cs-fixer": "^3.5", + "google/cloud-storage": "^1.23", + "guzzlehttp/psr7": "^2.6", + "microsoft/azure-storage-blob": "^1.1", + "mongodb/mongodb": "^1.2|^2", + "phpseclib/phpseclib": "^3.0.36", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^9.5.11|^10.0", + "sabre/dav": "^4.6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "League\\Flysystem\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frankdejonge.nl" + } + ], + "description": "File storage abstraction for PHP", + "keywords": [ + "WebDAV", + "aws", + "cloud", + "file", + "files", + "filesystem", + "filesystems", + "ftp", + "s3", + "sftp", + "storage" + ], + "support": { + "issues": "https://github.com/thephpleague/flysystem/issues", + "source": "https://github.com/thephpleague/flysystem/tree/3.30.0" + }, + "time": "2025-06-25T13:29:59+00:00" + }, + { + "name": "league/flysystem-local", + "version": "3.30.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/flysystem-local.git", + "reference": "6691915f77c7fb69adfb87dcd550052dc184ee10" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/flysystem-local/zipball/6691915f77c7fb69adfb87dcd550052dc184ee10", + "reference": "6691915f77c7fb69adfb87dcd550052dc184ee10", + "shasum": "" + }, + "require": { + "ext-fileinfo": "*", + "league/flysystem": "^3.0.0", + "league/mime-type-detection": "^1.0.0", + "php": "^8.0.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "League\\Flysystem\\Local\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frankdejonge.nl" + } + ], + "description": "Local filesystem adapter for Flysystem.", + "keywords": [ + "Flysystem", + "file", + "files", + "filesystem", + "local" + ], + "support": { + "source": "https://github.com/thephpleague/flysystem-local/tree/3.30.0" + }, + "time": "2025-05-21T10:34:19+00:00" + }, + { + "name": "league/mime-type-detection", + "version": "1.16.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/mime-type-detection.git", + "reference": "2d6702ff215bf922936ccc1ad31007edc76451b9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/2d6702ff215bf922936ccc1ad31007edc76451b9", + "reference": "2d6702ff215bf922936ccc1ad31007edc76451b9", + "shasum": "" + }, + "require": { + "ext-fileinfo": "*", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.2", + "phpstan/phpstan": "^0.12.68", + "phpunit/phpunit": "^8.5.8 || ^9.3 || ^10.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "League\\MimeTypeDetection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frankdejonge.nl" + } + ], + "description": "Mime-type detection for Flysystem", + "support": { + "issues": "https://github.com/thephpleague/mime-type-detection/issues", + "source": "https://github.com/thephpleague/mime-type-detection/tree/1.16.0" + }, + "funding": [ + { + "url": "https://github.com/frankdejonge", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/league/flysystem", + "type": "tidelift" + } + ], + "time": "2024-09-21T08:32:55+00:00" + }, + { + "name": "league/uri", + "version": "7.5.1", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/uri.git", + "reference": "81fb5145d2644324614cc532b28efd0215bda430" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/uri/zipball/81fb5145d2644324614cc532b28efd0215bda430", + "reference": "81fb5145d2644324614cc532b28efd0215bda430", + "shasum": "" + }, + "require": { + "league/uri-interfaces": "^7.5", + "php": "^8.1" + }, + "conflict": { + "league/uri-schemes": "^1.0" + }, + "suggest": { + "ext-bcmath": "to improve IPV4 host parsing", + "ext-fileinfo": "to create Data URI from file contennts", + "ext-gmp": "to improve IPV4 host parsing", + "ext-intl": "to handle IDN host with the best performance", + "jeremykendall/php-domain-parser": "to resolve Public Suffix and Top Level Domain", + "league/uri-components": "Needed to easily manipulate URI objects components", + "php-64bit": "to improve IPV4 host parsing", + "symfony/polyfill-intl-idn": "to handle IDN host via the Symfony polyfill if ext-intl is not present" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "7.x-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Uri\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ignace Nyamagana Butera", + "email": "nyamsprod@gmail.com", + "homepage": "https://nyamsprod.com" + } + ], + "description": "URI manipulation library", + "homepage": "https://uri.thephpleague.com", + "keywords": [ + "data-uri", + "file-uri", + "ftp", + "hostname", + "http", + "https", + "middleware", + "parse_str", + "parse_url", + "psr-7", + "query-string", + "querystring", + "rfc3986", + "rfc3987", + "rfc6570", + "uri", + "uri-template", + "url", + "ws" + ], + "support": { + "docs": "https://uri.thephpleague.com", + "forum": "https://thephpleague.slack.com", + "issues": "https://github.com/thephpleague/uri-src/issues", + "source": "https://github.com/thephpleague/uri/tree/7.5.1" + }, + "funding": [ + { + "url": "https://github.com/sponsors/nyamsprod", + "type": "github" + } + ], + "time": "2024-12-08T08:40:02+00:00" + }, + { + "name": "league/uri-interfaces", + "version": "7.5.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/uri-interfaces.git", + "reference": "08cfc6c4f3d811584fb09c37e2849e6a7f9b0742" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/uri-interfaces/zipball/08cfc6c4f3d811584fb09c37e2849e6a7f9b0742", + "reference": "08cfc6c4f3d811584fb09c37e2849e6a7f9b0742", + "shasum": "" + }, + "require": { + "ext-filter": "*", + "php": "^8.1", + "psr/http-factory": "^1", + "psr/http-message": "^1.1 || ^2.0" + }, + "suggest": { + "ext-bcmath": "to improve IPV4 host parsing", + "ext-gmp": "to improve IPV4 host parsing", + "ext-intl": "to handle IDN host with the best performance", + "php-64bit": "to improve IPV4 host parsing", + "symfony/polyfill-intl-idn": "to handle IDN host via the Symfony polyfill if ext-intl is not present" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "7.x-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Uri\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ignace Nyamagana Butera", + "email": "nyamsprod@gmail.com", + "homepage": "https://nyamsprod.com" + } + ], + "description": "Common interfaces and classes for URI representation and interaction", + "homepage": "https://uri.thephpleague.com", + "keywords": [ + "data-uri", + "file-uri", + "ftp", + "hostname", + "http", + "https", + "parse_str", + "parse_url", + "psr-7", + "query-string", + "querystring", + "rfc3986", + "rfc3987", + "rfc6570", + "uri", + "url", + "ws" + ], + "support": { + "docs": "https://uri.thephpleague.com", + "forum": "https://thephpleague.slack.com", + "issues": "https://github.com/thephpleague/uri-src/issues", + "source": "https://github.com/thephpleague/uri-interfaces/tree/7.5.0" + }, + "funding": [ + { + "url": "https://github.com/sponsors/nyamsprod", + "type": "github" + } + ], + "time": "2024-12-08T08:18:47+00:00" + }, + { + "name": "masterminds/html5", + "version": "2.10.0", + "source": { + "type": "git", + "url": "https://github.com/Masterminds/html5-php.git", + "reference": "fcf91eb64359852f00d921887b219479b4f21251" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Masterminds/html5-php/zipball/fcf91eb64359852f00d921887b219479b4f21251", + "reference": "fcf91eb64359852f00d921887b219479b4f21251", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7.21 || ^6 || ^7 || ^8 || ^9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "autoload": { + "psr-4": { + "Masterminds\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Matt Butcher", + "email": "technosophos@gmail.com" + }, + { + "name": "Matt Farina", + "email": "matt@mattfarina.com" + }, + { + "name": "Asmir Mustafic", + "email": "goetas@gmail.com" + } + ], + "description": "An HTML5 parser and serializer.", + "homepage": "http://masterminds.github.io/html5-php", + "keywords": [ + "HTML5", + "dom", + "html", + "parser", + "querypath", + "serializer", + "xml" + ], + "support": { + "issues": "https://github.com/Masterminds/html5-php/issues", + "source": "https://github.com/Masterminds/html5-php/tree/2.10.0" + }, + "time": "2025-07-25T09:04:22+00:00" + }, + { + "name": "monolog/monolog", + "version": "3.9.0", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/monolog.git", + "reference": "10d85740180ecba7896c87e06a166e0c95a0e3b6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/10d85740180ecba7896c87e06a166e0c95a0e3b6", + "reference": "10d85740180ecba7896c87e06a166e0c95a0e3b6", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/log": "^2.0 || ^3.0" + }, + "provide": { + "psr/log-implementation": "3.0.0" + }, + "require-dev": { + "aws/aws-sdk-php": "^3.0", + "doctrine/couchdb": "~1.0@dev", + "elasticsearch/elasticsearch": "^7 || ^8", + "ext-json": "*", + "graylog2/gelf-php": "^1.4.2 || ^2.0", + "guzzlehttp/guzzle": "^7.4.5", + "guzzlehttp/psr7": "^2.2", + "mongodb/mongodb": "^1.8", + "php-amqplib/php-amqplib": "~2.4 || ^3", + "php-console/php-console": "^3.1.8", + "phpstan/phpstan": "^2", + "phpstan/phpstan-deprecation-rules": "^2", + "phpstan/phpstan-strict-rules": "^2", + "phpunit/phpunit": "^10.5.17 || ^11.0.7", + "predis/predis": "^1.1 || ^2", + "rollbar/rollbar": "^4.0", + "ruflin/elastica": "^7 || ^8", + "symfony/mailer": "^5.4 || ^6", + "symfony/mime": "^5.4 || ^6" + }, + "suggest": { + "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB", + "doctrine/couchdb": "Allow sending log messages to a CouchDB server", + "elasticsearch/elasticsearch": "Allow sending log messages to an Elasticsearch server via official client", + "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", + "ext-curl": "Required to send log messages using the IFTTTHandler, the LogglyHandler, the SendGridHandler, the SlackWebhookHandler or the TelegramBotHandler", + "ext-mbstring": "Allow to work properly with unicode symbols", + "ext-mongodb": "Allow sending log messages to a MongoDB server (via driver)", + "ext-openssl": "Required to send log messages using SSL", + "ext-sockets": "Allow sending log messages to a Syslog server (via UDP driver)", + "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", + "mongodb/mongodb": "Allow sending log messages to a MongoDB server (via library)", + "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib", + "rollbar/rollbar": "Allow sending log messages to Rollbar", + "ruflin/elastica": "Allow sending log messages to an Elastic Search server" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Monolog\\": "src/Monolog" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "https://seld.be" + } + ], + "description": "Sends your logs to files, sockets, inboxes, databases and various web services", + "homepage": "https://github.com/Seldaek/monolog", + "keywords": [ + "log", + "logging", + "psr-3" + ], + "support": { + "issues": "https://github.com/Seldaek/monolog/issues", + "source": "https://github.com/Seldaek/monolog/tree/3.9.0" + }, + "funding": [ + { + "url": "https://github.com/Seldaek", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/monolog/monolog", + "type": "tidelift" + } + ], + "time": "2025-03-24T10:02:05+00:00" + }, + { + "name": "nesbot/carbon", + "version": "3.10.2", + "source": { + "type": "git", + "url": "https://github.com/CarbonPHP/carbon.git", + "reference": "76b5c07b8a9d2025ed1610e14cef1f3fd6ad2c24" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/CarbonPHP/carbon/zipball/76b5c07b8a9d2025ed1610e14cef1f3fd6ad2c24", + "reference": "76b5c07b8a9d2025ed1610e14cef1f3fd6ad2c24", + "shasum": "" + }, + "require": { + "carbonphp/carbon-doctrine-types": "<100.0", + "ext-json": "*", + "php": "^8.1", + "psr/clock": "^1.0", + "symfony/clock": "^6.3.12 || ^7.0", + "symfony/polyfill-mbstring": "^1.0", + "symfony/translation": "^4.4.18 || ^5.2.1 || ^6.0 || ^7.0" + }, + "provide": { + "psr/clock-implementation": "1.0" + }, + "require-dev": { + "doctrine/dbal": "^3.6.3 || ^4.0", + "doctrine/orm": "^2.15.2 || ^3.0", + "friendsofphp/php-cs-fixer": "^3.75.0", + "kylekatarnls/multi-tester": "^2.5.3", + "phpmd/phpmd": "^2.15.0", + "phpstan/extension-installer": "^1.4.3", + "phpstan/phpstan": "^2.1.17", + "phpunit/phpunit": "^10.5.46", + "squizlabs/php_codesniffer": "^3.13.0" + }, + "bin": [ + "bin/carbon" + ], + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Carbon\\Laravel\\ServiceProvider" + ] + }, + "phpstan": { + "includes": [ + "extension.neon" + ] + }, + "branch-alias": { + "dev-2.x": "2.x-dev", + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Carbon\\": "src/Carbon/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Brian Nesbitt", + "email": "brian@nesbot.com", + "homepage": "https://markido.com" + }, + { + "name": "kylekatarnls", + "homepage": "https://github.com/kylekatarnls" + } + ], + "description": "An API extension for DateTime that supports 281 different languages.", + "homepage": "https://carbon.nesbot.com", + "keywords": [ + "date", + "datetime", + "time" + ], + "support": { + "docs": "https://carbon.nesbot.com/docs", + "issues": "https://github.com/CarbonPHP/carbon/issues", + "source": "https://github.com/CarbonPHP/carbon" + }, + "funding": [ + { + "url": "https://github.com/sponsors/kylekatarnls", + "type": "github" + }, + { + "url": "https://opencollective.com/Carbon#sponsor", + "type": "opencollective" + }, + { + "url": "https://tidelift.com/subscription/pkg/packagist-nesbot-carbon?utm_source=packagist-nesbot-carbon&utm_medium=referral&utm_campaign=readme", + "type": "tidelift" + } + ], + "time": "2025-08-02T09:36:06+00:00" + }, + { + "name": "nette/schema", + "version": "v1.3.2", + "source": { + "type": "git", + "url": "https://github.com/nette/schema.git", + "reference": "da801d52f0354f70a638673c4a0f04e16529431d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/schema/zipball/da801d52f0354f70a638673c4a0f04e16529431d", + "reference": "da801d52f0354f70a638673c4a0f04e16529431d", + "shasum": "" + }, + "require": { + "nette/utils": "^4.0", + "php": "8.1 - 8.4" + }, + "require-dev": { + "nette/tester": "^2.5.2", + "phpstan/phpstan-nette": "^1.0", + "tracy/tracy": "^2.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "šŸ“ Nette Schema: validating data structures against a given Schema.", + "homepage": "https://nette.org", + "keywords": [ + "config", + "nette" + ], + "support": { + "issues": "https://github.com/nette/schema/issues", + "source": "https://github.com/nette/schema/tree/v1.3.2" + }, + "time": "2024-10-06T23:10:23+00:00" + }, + { + "name": "nette/utils", + "version": "v4.0.8", + "source": { + "type": "git", + "url": "https://github.com/nette/utils.git", + "reference": "c930ca4e3cf4f17dcfb03037703679d2396d2ede" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/utils/zipball/c930ca4e3cf4f17dcfb03037703679d2396d2ede", + "reference": "c930ca4e3cf4f17dcfb03037703679d2396d2ede", + "shasum": "" + }, + "require": { + "php": "8.0 - 8.5" + }, + "conflict": { + "nette/finder": "<3", + "nette/schema": "<1.2.2" + }, + "require-dev": { + "jetbrains/phpstorm-attributes": "^1.2", + "nette/tester": "^2.5", + "phpstan/phpstan-nette": "^2.0@stable", + "tracy/tracy": "^2.9" + }, + "suggest": { + "ext-gd": "to use Image", + "ext-iconv": "to use Strings::webalize(), toAscii(), chr() and reverse()", + "ext-intl": "to use Strings::webalize(), toAscii(), normalize() and compare()", + "ext-json": "to use Nette\\Utils\\Json", + "ext-mbstring": "to use Strings::lower() etc...", + "ext-tokenizer": "to use Nette\\Utils\\Reflection::getUseStatements()" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "psr-4": { + "Nette\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "šŸ›  Nette Utils: lightweight utilities for string & array manipulation, image handling, safe JSON encoding/decoding, validation, slug or strong password generating etc.", + "homepage": "https://nette.org", + "keywords": [ + "array", + "core", + "datetime", + "images", + "json", + "nette", + "paginator", + "password", + "slugify", + "string", + "unicode", + "utf-8", + "utility", + "validation" + ], + "support": { + "issues": "https://github.com/nette/utils/issues", + "source": "https://github.com/nette/utils/tree/v4.0.8" + }, + "time": "2025-08-06T21:43:34+00:00" + }, + { + "name": "nikic/php-parser", + "version": "v5.6.0", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "221b0d0fdf1369c71047ad1d18bb5880017bbc56" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/221b0d0fdf1369c71047ad1d18bb5880017bbc56", + "reference": "221b0d0fdf1369c71047ad1d18bb5880017bbc56", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "ext-json": "*", + "ext-tokenizer": "*", + "php": ">=7.4" + }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^9.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v5.6.0" + }, + "time": "2025-07-27T20:03:57+00:00" + }, + { + "name": "nunomaduro/termwind", + "version": "v2.3.1", + "source": { + "type": "git", + "url": "https://github.com/nunomaduro/termwind.git", + "reference": "dfa08f390e509967a15c22493dc0bac5733d9123" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nunomaduro/termwind/zipball/dfa08f390e509967a15c22493dc0bac5733d9123", + "reference": "dfa08f390e509967a15c22493dc0bac5733d9123", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": "^8.2", + "symfony/console": "^7.2.6" + }, + "require-dev": { + "illuminate/console": "^11.44.7", + "laravel/pint": "^1.22.0", + "mockery/mockery": "^1.6.12", + "pestphp/pest": "^2.36.0 || ^3.8.2", + "phpstan/phpstan": "^1.12.25", + "phpstan/phpstan-strict-rules": "^1.6.2", + "symfony/var-dumper": "^7.2.6", + "thecodingmachine/phpstan-strict-rules": "^1.0.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Termwind\\Laravel\\TermwindServiceProvider" + ] + }, + "branch-alias": { + "dev-2.x": "2.x-dev" + } + }, + "autoload": { + "files": [ + "src/Functions.php" + ], + "psr-4": { + "Termwind\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" + } + ], + "description": "Its like Tailwind CSS, but for the console.", + "keywords": [ + "cli", + "console", + "css", + "package", + "php", + "style" + ], + "support": { + "issues": "https://github.com/nunomaduro/termwind/issues", + "source": "https://github.com/nunomaduro/termwind/tree/v2.3.1" + }, + "funding": [ + { + "url": "https://www.paypal.com/paypalme/enunomaduro", + "type": "custom" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + }, + { + "url": "https://github.com/xiCO2k", + "type": "github" + } + ], + "time": "2025-05-08T08:14:37+00:00" + }, + { + "name": "phpoption/phpoption", + "version": "1.9.3", + "source": { + "type": "git", + "url": "https://github.com/schmittjoh/php-option.git", + "reference": "e3fac8b24f56113f7cb96af14958c0dd16330f54" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/e3fac8b24f56113f7cb96af14958c0dd16330f54", + "reference": "e3fac8b24f56113f7cb96af14958c0dd16330f54", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "phpunit/phpunit": "^8.5.39 || ^9.6.20 || ^10.5.28" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + }, + "branch-alias": { + "dev-master": "1.9-dev" + } + }, + "autoload": { + "psr-4": { + "PhpOption\\": "src/PhpOption/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Johannes M. Schmitt", + "email": "schmittjoh@gmail.com", + "homepage": "https://github.com/schmittjoh" + }, + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + } + ], + "description": "Option Type for PHP", + "keywords": [ + "language", + "option", + "php", + "type" + ], + "support": { + "issues": "https://github.com/schmittjoh/php-option/issues", + "source": "https://github.com/schmittjoh/php-option/tree/1.9.3" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpoption/phpoption", + "type": "tidelift" + } + ], + "time": "2024-07-20T21:41:07+00:00" + }, + { + "name": "psr/clock", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/clock.git", + "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/clock/zipball/e41a24703d4560fd0acb709162f73b8adfc3aa0d", + "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Psr\\Clock\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for reading the clock.", + "homepage": "https://github.com/php-fig/clock", + "keywords": [ + "clock", + "now", + "psr", + "psr-20", + "time" + ], + "support": { + "issues": "https://github.com/php-fig/clock/issues", + "source": "https://github.com/php-fig/clock/tree/1.0.0" + }, + "time": "2022-11-25T14:36:26+00:00" + }, + { + "name": "psr/container", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "shasum": "" + }, + "require": { + "php": ">=7.4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/2.0.2" + }, + "time": "2021-11-05T16:47:00+00:00" + }, + { + "name": "psr/event-dispatcher", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/event-dispatcher.git", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", + "shasum": "" + }, + "require": { + "php": ">=7.2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\EventDispatcher\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Standard interfaces for event handling.", + "keywords": [ + "events", + "psr", + "psr-14" + ], + "support": { + "issues": "https://github.com/php-fig/event-dispatcher/issues", + "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" + }, + "time": "2019-01-08T18:20:26+00:00" + }, + { + "name": "psr/http-client", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-client.git", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP clients", + "homepage": "https://github.com/php-fig/http-client", + "keywords": [ + "http", + "http-client", + "psr", + "psr-18" + ], + "support": { + "source": "https://github.com/php-fig/http-client" + }, + "time": "2023-09-23T14:17:50+00:00" + }, + { + "name": "psr/http-factory", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-factory.git", + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/2b4765fddfe3b508ac62f829e852b1501d3f6e8a", + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a", + "shasum": "" + }, + "require": { + "php": ">=7.1", + "psr/http-message": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "PSR-17: Common interfaces for PSR-7 HTTP message factories", + "keywords": [ + "factory", + "http", + "message", + "psr", + "psr-17", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-factory" + }, + "time": "2024-04-15T12:06:14+00:00" + }, + { + "name": "psr/http-message", + "version": "2.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-message/tree/2.0" + }, + "time": "2023-04-04T09:54:51+00:00" + }, + { + "name": "psr/log", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/3.0.2" + }, + "time": "2024-09-11T13:17:53+00:00" + }, + { + "name": "psr/simple-cache", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/simple-cache.git", + "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/764e0b3939f5ca87cb904f570ef9be2d78a07865", + "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\SimpleCache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interfaces for simple caching", + "keywords": [ + "cache", + "caching", + "psr", + "psr-16", + "simple-cache" + ], + "support": { + "source": "https://github.com/php-fig/simple-cache/tree/3.0.0" + }, + "time": "2021-10-29T13:26:27+00:00" + }, + { + "name": "psy/psysh", + "version": "v0.12.10", + "source": { + "type": "git", + "url": "https://github.com/bobthecow/psysh.git", + "reference": "6e80abe6f2257121f1eb9a4c55bf29d921025b22" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/bobthecow/psysh/zipball/6e80abe6f2257121f1eb9a4c55bf29d921025b22", + "reference": "6e80abe6f2257121f1eb9a4c55bf29d921025b22", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-tokenizer": "*", + "nikic/php-parser": "^5.0 || ^4.0", + "php": "^8.0 || ^7.4", + "symfony/console": "^7.0 || ^6.0 || ^5.0 || ^4.0 || ^3.4", + "symfony/var-dumper": "^7.0 || ^6.0 || ^5.0 || ^4.0 || ^3.4" + }, + "conflict": { + "symfony/console": "4.4.37 || 5.3.14 || 5.3.15 || 5.4.3 || 5.4.4 || 6.0.3 || 6.0.4" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.2" + }, + "suggest": { + "ext-pcntl": "Enabling the PCNTL extension makes PsySH a lot happier :)", + "ext-pdo-sqlite": "The doc command requires SQLite to work.", + "ext-posix": "If you have PCNTL, you'll want the POSIX extension as well." + }, + "bin": [ + "bin/psysh" + ], + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": false, + "forward-command": false + }, + "branch-alias": { + "dev-main": "0.12.x-dev" + } + }, + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Psy\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Justin Hileman", + "email": "justin@justinhileman.info" + } + ], + "description": "An interactive shell for modern PHP.", + "homepage": "https://psysh.org", + "keywords": [ + "REPL", + "console", + "interactive", + "shell" + ], + "support": { + "issues": "https://github.com/bobthecow/psysh/issues", + "source": "https://github.com/bobthecow/psysh/tree/v0.12.10" + }, + "time": "2025-08-04T12:39:37+00:00" + }, + { + "name": "ralouphie/getallheaders", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/ralouphie/getallheaders.git", + "reference": "120b605dfeb996808c31b6477290a714d356e822" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", + "reference": "120b605dfeb996808c31b6477290a714d356e822", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^5 || ^6.5" + }, + "type": "library", + "autoload": { + "files": [ + "src/getallheaders.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ralph Khattar", + "email": "ralph.khattar@gmail.com" + } + ], + "description": "A polyfill for getallheaders.", + "support": { + "issues": "https://github.com/ralouphie/getallheaders/issues", + "source": "https://github.com/ralouphie/getallheaders/tree/develop" + }, + "time": "2019-03-08T08:55:37+00:00" + }, + { + "name": "ramsey/collection", + "version": "2.1.1", + "source": { + "type": "git", + "url": "https://github.com/ramsey/collection.git", + "reference": "344572933ad0181accbf4ba763e85a0306a8c5e2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ramsey/collection/zipball/344572933ad0181accbf4ba763e85a0306a8c5e2", + "reference": "344572933ad0181accbf4ba763e85a0306a8c5e2", + "shasum": "" + }, + "require": { + "php": "^8.1" + }, + "require-dev": { + "captainhook/plugin-composer": "^5.3", + "ergebnis/composer-normalize": "^2.45", + "fakerphp/faker": "^1.24", + "hamcrest/hamcrest-php": "^2.0", + "jangregor/phpstan-prophecy": "^2.1", + "mockery/mockery": "^1.6", + "php-parallel-lint/php-console-highlighter": "^1.0", + "php-parallel-lint/php-parallel-lint": "^1.4", + "phpspec/prophecy-phpunit": "^2.3", + "phpstan/extension-installer": "^1.4", + "phpstan/phpstan": "^2.1", + "phpstan/phpstan-mockery": "^2.0", + "phpstan/phpstan-phpunit": "^2.0", + "phpunit/phpunit": "^10.5", + "ramsey/coding-standard": "^2.3", + "ramsey/conventional-commits": "^1.6", + "roave/security-advisories": "dev-latest" + }, + "type": "library", + "extra": { + "captainhook": { + "force-install": true + }, + "ramsey/conventional-commits": { + "configFile": "conventional-commits.json" + } + }, + "autoload": { + "psr-4": { + "Ramsey\\Collection\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ben Ramsey", + "email": "ben@benramsey.com", + "homepage": "https://benramsey.com" + } + ], + "description": "A PHP library for representing and manipulating collections.", + "keywords": [ + "array", + "collection", + "hash", + "map", + "queue", + "set" + ], + "support": { + "issues": "https://github.com/ramsey/collection/issues", + "source": "https://github.com/ramsey/collection/tree/2.1.1" + }, + "time": "2025-03-22T05:38:12+00:00" + }, + { + "name": "ramsey/uuid", + "version": "4.9.0", + "source": { + "type": "git", + "url": "https://github.com/ramsey/uuid.git", + "reference": "4e0e23cc785f0724a0e838279a9eb03f28b092a0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ramsey/uuid/zipball/4e0e23cc785f0724a0e838279a9eb03f28b092a0", + "reference": "4e0e23cc785f0724a0e838279a9eb03f28b092a0", + "shasum": "" + }, + "require": { + "brick/math": "^0.8.8 || ^0.9 || ^0.10 || ^0.11 || ^0.12 || ^0.13", + "php": "^8.0", + "ramsey/collection": "^1.2 || ^2.0" + }, + "replace": { + "rhumsaa/uuid": "self.version" + }, + "require-dev": { + "captainhook/captainhook": "^5.25", + "captainhook/plugin-composer": "^5.3", + "dealerdirect/phpcodesniffer-composer-installer": "^1.0", + "ergebnis/composer-normalize": "^2.47", + "mockery/mockery": "^1.6", + "paragonie/random-lib": "^2", + "php-mock/php-mock": "^2.6", + "php-mock/php-mock-mockery": "^1.5", + "php-parallel-lint/php-parallel-lint": "^1.4.0", + "phpbench/phpbench": "^1.2.14", + "phpstan/extension-installer": "^1.4", + "phpstan/phpstan": "^2.1", + "phpstan/phpstan-mockery": "^2.0", + "phpstan/phpstan-phpunit": "^2.0", + "phpunit/phpunit": "^9.6", + "slevomat/coding-standard": "^8.18", + "squizlabs/php_codesniffer": "^3.13" + }, + "suggest": { + "ext-bcmath": "Enables faster math with arbitrary-precision integers using BCMath.", + "ext-gmp": "Enables faster math with arbitrary-precision integers using GMP.", + "ext-uuid": "Enables the use of PeclUuidTimeGenerator and PeclUuidRandomGenerator.", + "paragonie/random-lib": "Provides RandomLib for use with the RandomLibAdapter", + "ramsey/uuid-doctrine": "Allows the use of Ramsey\\Uuid\\Uuid as Doctrine field type." + }, + "type": "library", + "extra": { + "captainhook": { + "force-install": true + } + }, + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Ramsey\\Uuid\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A PHP library for generating and working with universally unique identifiers (UUIDs).", + "keywords": [ + "guid", + "identifier", + "uuid" + ], + "support": { + "issues": "https://github.com/ramsey/uuid/issues", + "source": "https://github.com/ramsey/uuid/tree/4.9.0" + }, + "time": "2025-06-25T14:20:11+00:00" + }, + { + "name": "sabberworm/php-css-parser", + "version": "v8.9.0", + "source": { + "type": "git", + "url": "https://github.com/MyIntervals/PHP-CSS-Parser.git", + "reference": "d8e916507b88e389e26d4ab03c904a082aa66bb9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/MyIntervals/PHP-CSS-Parser/zipball/d8e916507b88e389e26d4ab03c904a082aa66bb9", + "reference": "d8e916507b88e389e26d4ab03c904a082aa66bb9", + "shasum": "" + }, + "require": { + "ext-iconv": "*", + "php": "^5.6.20 || ^7.0.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0" + }, + "require-dev": { + "phpunit/phpunit": "5.7.27 || 6.5.14 || 7.5.20 || 8.5.41", + "rawr/cross-data-providers": "^2.0.0" + }, + "suggest": { + "ext-mbstring": "for parsing UTF-8 CSS" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "9.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Sabberworm\\CSS\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Raphael Schweikert" + }, + { + "name": "Oliver Klee", + "email": "github@oliverklee.de" + }, + { + "name": "Jake Hotson", + "email": "jake.github@qzdesign.co.uk" + } + ], + "description": "Parser for CSS Files written in PHP", + "homepage": "https://www.sabberworm.com/blog/2010/6/10/php-css-parser", + "keywords": [ + "css", + "parser", + "stylesheet" + ], + "support": { + "issues": "https://github.com/MyIntervals/PHP-CSS-Parser/issues", + "source": "https://github.com/MyIntervals/PHP-CSS-Parser/tree/v8.9.0" + }, + "time": "2025-07-11T13:20:48+00:00" + }, + { + "name": "symfony/clock", + "version": "v7.3.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/clock.git", + "reference": "b81435fbd6648ea425d1ee96a2d8e68f4ceacd24" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/clock/zipball/b81435fbd6648ea425d1ee96a2d8e68f4ceacd24", + "reference": "b81435fbd6648ea425d1ee96a2d8e68f4ceacd24", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "psr/clock": "^1.0", + "symfony/polyfill-php83": "^1.28" + }, + "provide": { + "psr/clock-implementation": "1.0" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/now.php" + ], + "psr-4": { + "Symfony\\Component\\Clock\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Decouples applications from the system clock", + "homepage": "https://symfony.com", + "keywords": [ + "clock", + "psr20", + "time" + ], + "support": { + "source": "https://github.com/symfony/clock/tree/v7.3.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-25T14:21:43+00:00" + }, + { + "name": "symfony/console", + "version": "v7.3.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "5f360ebc65c55265a74d23d7fe27f957870158a1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/5f360ebc65c55265a74d23d7fe27f957870158a1", + "reference": "5f360ebc65c55265a74d23d7fe27f957870158a1", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-mbstring": "~1.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/string": "^7.2" + }, + "conflict": { + "symfony/dependency-injection": "<6.4", + "symfony/dotenv": "<6.4", + "symfony/event-dispatcher": "<6.4", + "symfony/lock": "<6.4", + "symfony/process": "<6.4" + }, + "provide": { + "psr/log-implementation": "1.0|2.0|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/lock": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/stopwatch": "^6.4|^7.0", + "symfony/var-dumper": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Eases the creation of beautiful and testable command line interfaces", + "homepage": "https://symfony.com", + "keywords": [ + "cli", + "command-line", + "console", + "terminal" + ], + "support": { + "source": "https://github.com/symfony/console/tree/v7.3.2" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-07-30T17:13:41+00:00" + }, + { + "name": "symfony/css-selector", + "version": "v7.3.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/css-selector.git", + "reference": "601a5ce9aaad7bf10797e3663faefce9e26c24e2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/601a5ce9aaad7bf10797e3663faefce9e26c24e2", + "reference": "601a5ce9aaad7bf10797e3663faefce9e26c24e2", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\CssSelector\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Jean-FranƧois Simon", + "email": "jeanfrancois.simon@sensiolabs.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Converts CSS selectors to XPath expressions", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/css-selector/tree/v7.3.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-25T14:21:43+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v3.6.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/63afe740e99a13ba87ec199bb07bbdee937a5b62", + "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.6-dev" + } + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.6.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-25T14:21:43+00:00" + }, + { + "name": "symfony/error-handler", + "version": "v7.3.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/error-handler.git", + "reference": "0b31a944fcd8759ae294da4d2808cbc53aebd0c3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/0b31a944fcd8759ae294da4d2808cbc53aebd0c3", + "reference": "0b31a944fcd8759ae294da4d2808cbc53aebd0c3", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "psr/log": "^1|^2|^3", + "symfony/var-dumper": "^6.4|^7.0" + }, + "conflict": { + "symfony/deprecation-contracts": "<2.5", + "symfony/http-kernel": "<6.4" + }, + "require-dev": { + "symfony/console": "^6.4|^7.0", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/serializer": "^6.4|^7.0", + "symfony/webpack-encore-bundle": "^1.0|^2.0" + }, + "bin": [ + "Resources/bin/patch-type-declarations" + ], + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\ErrorHandler\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides tools to manage errors and ease debugging PHP code", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/error-handler/tree/v7.3.2" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-07-07T08:17:57+00:00" + }, + { + "name": "symfony/event-dispatcher", + "version": "v7.3.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "497f73ac996a598c92409b44ac43b6690c4f666d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/497f73ac996a598c92409b44ac43b6690c4f666d", + "reference": "497f73ac996a598c92409b44ac43b6690c4f666d", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/event-dispatcher-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/dependency-injection": "<6.4", + "symfony/service-contracts": "<2.5" + }, + "provide": { + "psr/event-dispatcher-implementation": "1.0", + "symfony/event-dispatcher-implementation": "2.0|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/error-handler": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/stopwatch": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/event-dispatcher/tree/v7.3.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-04-22T09:11:45+00:00" + }, + { + "name": "symfony/event-dispatcher-contracts", + "version": "v3.6.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher-contracts.git", + "reference": "59eb412e93815df44f05f342958efa9f46b1e586" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/59eb412e93815df44f05f342958efa9f46b1e586", + "reference": "59eb412e93815df44f05f342958efa9f46b1e586", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/event-dispatcher": "^1" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.6-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\EventDispatcher\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to dispatching event", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.6.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-25T14:21:43+00:00" + }, + { + "name": "symfony/finder", + "version": "v7.3.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "2a6614966ba1074fa93dae0bc804227422df4dfe" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/2a6614966ba1074fa93dae0bc804227422df4dfe", + "reference": "2a6614966ba1074fa93dae0bc804227422df4dfe", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "symfony/filesystem": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Finds files and directories via an intuitive fluent interface", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/finder/tree/v7.3.2" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-07-15T13:41:35+00:00" + }, + { + "name": "symfony/http-foundation", + "version": "v7.3.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-foundation.git", + "reference": "6877c122b3a6cc3695849622720054f6e6fa5fa6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/6877c122b3a6cc3695849622720054f6e6fa5fa6", + "reference": "6877c122b3a6cc3695849622720054f6e6fa5fa6", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3.0", + "symfony/polyfill-mbstring": "~1.1", + "symfony/polyfill-php83": "^1.27" + }, + "conflict": { + "doctrine/dbal": "<3.6", + "symfony/cache": "<6.4.12|>=7.0,<7.1.5" + }, + "require-dev": { + "doctrine/dbal": "^3.6|^4", + "predis/predis": "^1.1|^2.0", + "symfony/cache": "^6.4.12|^7.1.5", + "symfony/clock": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/mime": "^6.4|^7.0", + "symfony/rate-limiter": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpFoundation\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Defines an object-oriented layer for the HTTP specification", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/http-foundation/tree/v7.3.2" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-07-10T08:47:49+00:00" + }, + { + "name": "symfony/http-kernel", + "version": "v7.3.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-kernel.git", + "reference": "6ecc895559ec0097e221ed2fd5eb44d5fede083c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/6ecc895559ec0097e221ed2fd5eb44d5fede083c", + "reference": "6ecc895559ec0097e221ed2fd5eb44d5fede083c", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "psr/log": "^1|^2|^3", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/error-handler": "^6.4|^7.0", + "symfony/event-dispatcher": "^7.3", + "symfony/http-foundation": "^7.3", + "symfony/polyfill-ctype": "^1.8" + }, + "conflict": { + "symfony/browser-kit": "<6.4", + "symfony/cache": "<6.4", + "symfony/config": "<6.4", + "symfony/console": "<6.4", + "symfony/dependency-injection": "<6.4", + "symfony/doctrine-bridge": "<6.4", + "symfony/form": "<6.4", + "symfony/http-client": "<6.4", + "symfony/http-client-contracts": "<2.5", + "symfony/mailer": "<6.4", + "symfony/messenger": "<6.4", + "symfony/translation": "<6.4", + "symfony/translation-contracts": "<2.5", + "symfony/twig-bridge": "<6.4", + "symfony/validator": "<6.4", + "symfony/var-dumper": "<6.4", + "twig/twig": "<3.12" + }, + "provide": { + "psr/log-implementation": "1.0|2.0|3.0" + }, + "require-dev": { + "psr/cache": "^1.0|^2.0|^3.0", + "symfony/browser-kit": "^6.4|^7.0", + "symfony/clock": "^6.4|^7.0", + "symfony/config": "^6.4|^7.0", + "symfony/console": "^6.4|^7.0", + "symfony/css-selector": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/dom-crawler": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/finder": "^6.4|^7.0", + "symfony/http-client-contracts": "^2.5|^3", + "symfony/process": "^6.4|^7.0", + "symfony/property-access": "^7.1", + "symfony/routing": "^6.4|^7.0", + "symfony/serializer": "^7.1", + "symfony/stopwatch": "^6.4|^7.0", + "symfony/translation": "^6.4|^7.0", + "symfony/translation-contracts": "^2.5|^3", + "symfony/uid": "^6.4|^7.0", + "symfony/validator": "^6.4|^7.0", + "symfony/var-dumper": "^6.4|^7.0", + "symfony/var-exporter": "^6.4|^7.0", + "twig/twig": "^3.12" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpKernel\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides a structured process for converting a Request into a Response", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/http-kernel/tree/v7.3.2" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-07-31T10:45:04+00:00" + }, + { + "name": "symfony/mailer", + "version": "v7.3.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/mailer.git", + "reference": "d43e84d9522345f96ad6283d5dfccc8c1cfc299b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/mailer/zipball/d43e84d9522345f96ad6283d5dfccc8c1cfc299b", + "reference": "d43e84d9522345f96ad6283d5dfccc8c1cfc299b", + "shasum": "" + }, + "require": { + "egulias/email-validator": "^2.1.10|^3|^4", + "php": ">=8.2", + "psr/event-dispatcher": "^1", + "psr/log": "^1|^2|^3", + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/mime": "^7.2", + "symfony/service-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/http-client-contracts": "<2.5", + "symfony/http-kernel": "<6.4", + "symfony/messenger": "<6.4", + "symfony/mime": "<6.4", + "symfony/twig-bridge": "<6.4" + }, + "require-dev": { + "symfony/console": "^6.4|^7.0", + "symfony/http-client": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/twig-bridge": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Mailer\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Helps sending emails", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/mailer/tree/v7.3.2" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-07-15T11:36:08+00:00" + }, + { + "name": "symfony/mime", + "version": "v7.3.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/mime.git", + "reference": "e0a0f859148daf1edf6c60b398eb40bfc96697d1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/mime/zipball/e0a0f859148daf1edf6c60b398eb40bfc96697d1", + "reference": "e0a0f859148daf1edf6c60b398eb40bfc96697d1", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/polyfill-intl-idn": "^1.10", + "symfony/polyfill-mbstring": "^1.0" + }, + "conflict": { + "egulias/email-validator": "~3.0.0", + "phpdocumentor/reflection-docblock": "<3.2.2", + "phpdocumentor/type-resolver": "<1.4.0", + "symfony/mailer": "<6.4", + "symfony/serializer": "<6.4.3|>7.0,<7.0.3" + }, + "require-dev": { + "egulias/email-validator": "^2.1.10|^3.1|^4", + "league/html-to-markdown": "^5.0", + "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/property-access": "^6.4|^7.0", + "symfony/property-info": "^6.4|^7.0", + "symfony/serializer": "^6.4.3|^7.0.3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Mime\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Allows manipulating MIME messages", + "homepage": "https://symfony.com", + "keywords": [ + "mime", + "mime-type" + ], + "support": { + "source": "https://github.com/symfony/mime/tree/v7.3.2" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-07-15T13:41:35+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.32.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.32.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/polyfill-intl-grapheme", + "version": "v1.32.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-grapheme.git", + "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe", + "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Grapheme\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's grapheme_* functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "grapheme", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.32.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/polyfill-intl-idn", + "version": "v1.32.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-idn.git", + "reference": "9614ac4d8061dc257ecc64cba1b140873dce8ad3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/9614ac4d8061dc257ecc64cba1b140873dce8ad3", + "reference": "9614ac4d8061dc257ecc64cba1b140873dce8ad3", + "shasum": "" + }, + "require": { + "php": ">=7.2", + "symfony/polyfill-intl-normalizer": "^1.10" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Idn\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Laurent Bassin", + "email": "laurent@bassin.info" + }, + { + "name": "Trevor Rowbotham", + "email": "trevor.rowbotham@pm.me" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "idn", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.32.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-10T14:38:51+00:00" + }, + { + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.32.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "3833d7255cc303546435cb650316bff708a1c75c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c", + "reference": "3833d7255cc303546435cb650316bff708a1c75c", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's Normalizer class and related functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "intl", + "normalizer", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.32.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.32.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6d857f4d76bd4b343eac26d6b539585d2bc56493", + "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493", + "shasum": "" + }, + "require": { + "ext-iconv": "*", + "php": ">=7.2" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.32.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-12-23T08:48:59+00:00" + }, + { + "name": "symfony/polyfill-php80", + "version": "v1.32.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/0cc9dd0f17f61d8131e7df6b84bd344899fe2608", + "reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.32.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-01-02T08:10:11+00:00" + }, + { + "name": "symfony/polyfill-php83", + "version": "v1.32.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php83.git", + "reference": "2fb86d65e2d424369ad2905e83b236a8805ba491" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/2fb86d65e2d424369ad2905e83b236a8805ba491", + "reference": "2fb86d65e2d424369ad2905e83b236a8805ba491", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php83\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.3+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php83/tree/v1.32.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/polyfill-uuid", + "version": "v1.32.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-uuid.git", + "reference": "21533be36c24be3f4b1669c4725c7d1d2bab4ae2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-uuid/zipball/21533be36c24be3f4b1669c4725c7d1d2bab4ae2", + "reference": "21533be36c24be3f4b1669c4725c7d1d2bab4ae2", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "provide": { + "ext-uuid": "*" + }, + "suggest": { + "ext-uuid": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Uuid\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "GrĆ©goire Pineau", + "email": "lyrixx@lyrixx.info" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for uuid functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "uuid" + ], + "support": { + "source": "https://github.com/symfony/polyfill-uuid/tree/v1.32.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/process", + "version": "v7.3.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "40c295f2deb408d5e9d2d32b8ba1dd61e36f05af" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/40c295f2deb408d5e9d2d32b8ba1dd61e36f05af", + "reference": "40c295f2deb408d5e9d2d32b8ba1dd61e36f05af", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Process\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Executes commands in sub-processes", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/process/tree/v7.3.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-04-17T09:11:12+00:00" + }, + { + "name": "symfony/routing", + "version": "v7.3.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/routing.git", + "reference": "7614b8ca5fa89b9cd233e21b627bfc5774f586e4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/routing/zipball/7614b8ca5fa89b9cd233e21b627bfc5774f586e4", + "reference": "7614b8ca5fa89b9cd233e21b627bfc5774f586e4", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/config": "<6.4", + "symfony/dependency-injection": "<6.4", + "symfony/yaml": "<6.4" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/yaml": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Routing\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Maps an HTTP request to a set of configuration variables", + "homepage": "https://symfony.com", + "keywords": [ + "router", + "routing", + "uri", + "url" + ], + "support": { + "source": "https://github.com/symfony/routing/tree/v7.3.2" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-07-15T11:36:08+00:00" + }, + { + "name": "symfony/service-contracts", + "version": "v3.6.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "f021b05a130d35510bd6b25fe9053c2a8a15d5d4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/f021b05a130d35510bd6b25fe9053c2a8a15d5d4", + "reference": "f021b05a130d35510bd6b25fe9053c2a8a15d5d4", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "conflict": { + "ext-psr": "<1.1|>=2" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.6-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/v3.6.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-04-25T09:37:31+00:00" + }, + { + "name": "symfony/string", + "version": "v7.3.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/string.git", + "reference": "42f505aff654e62ac7ac2ce21033818297ca89ca" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/string/zipball/42f505aff654e62ac7ac2ce21033818297ca89ca", + "reference": "42f505aff654e62ac7ac2ce21033818297ca89ca", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-intl-grapheme": "~1.0", + "symfony/polyfill-intl-normalizer": "~1.0", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/translation-contracts": "<2.5" + }, + "require-dev": { + "symfony/emoji": "^7.1", + "symfony/error-handler": "^6.4|^7.0", + "symfony/http-client": "^6.4|^7.0", + "symfony/intl": "^6.4|^7.0", + "symfony/translation-contracts": "^2.5|^3.0", + "symfony/var-exporter": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/functions.php" + ], + "psr-4": { + "Symfony\\Component\\String\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", + "homepage": "https://symfony.com", + "keywords": [ + "grapheme", + "i18n", + "string", + "unicode", + "utf-8", + "utf8" + ], + "support": { + "source": "https://github.com/symfony/string/tree/v7.3.2" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-07-10T08:47:49+00:00" + }, + { + "name": "symfony/translation", + "version": "v7.3.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/translation.git", + "reference": "81b48f4daa96272efcce9c7a6c4b58e629df3c90" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/translation/zipball/81b48f4daa96272efcce9c7a6c4b58e629df3c90", + "reference": "81b48f4daa96272efcce9c7a6c4b58e629df3c90", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-mbstring": "~1.0", + "symfony/translation-contracts": "^2.5|^3.0" + }, + "conflict": { + "nikic/php-parser": "<5.0", + "symfony/config": "<6.4", + "symfony/console": "<6.4", + "symfony/dependency-injection": "<6.4", + "symfony/http-client-contracts": "<2.5", + "symfony/http-kernel": "<6.4", + "symfony/service-contracts": "<2.5", + "symfony/twig-bundle": "<6.4", + "symfony/yaml": "<6.4" + }, + "provide": { + "symfony/translation-implementation": "2.3|3.0" + }, + "require-dev": { + "nikic/php-parser": "^5.0", + "psr/log": "^1|^2|^3", + "symfony/config": "^6.4|^7.0", + "symfony/console": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/finder": "^6.4|^7.0", + "symfony/http-client-contracts": "^2.5|^3.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/intl": "^6.4|^7.0", + "symfony/polyfill-intl-icu": "^1.21", + "symfony/routing": "^6.4|^7.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/yaml": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/functions.php" + ], + "psr-4": { + "Symfony\\Component\\Translation\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides tools to internationalize your application", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/translation/tree/v7.3.2" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-07-30T17:31:46+00:00" + }, + { + "name": "symfony/translation-contracts", + "version": "v3.6.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/translation-contracts.git", + "reference": "df210c7a2573f1913b2d17cc95f90f53a73d8f7d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/df210c7a2573f1913b2d17cc95f90f53a73d8f7d", + "reference": "df210c7a2573f1913b2d17cc95f90f53a73d8f7d", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.6-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Translation\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to translation", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/translation-contracts/tree/v3.6.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-27T08:32:26+00:00" + }, + { + "name": "symfony/uid", + "version": "v7.3.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/uid.git", + "reference": "a69f69f3159b852651a6bf45a9fdd149520525bb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/uid/zipball/a69f69f3159b852651a6bf45a9fdd149520525bb", + "reference": "a69f69f3159b852651a6bf45a9fdd149520525bb", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/polyfill-uuid": "^1.15" + }, + "require-dev": { + "symfony/console": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Uid\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "GrĆ©goire Pineau", + "email": "lyrixx@lyrixx.info" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an object-oriented API to generate and represent UIDs", + "homepage": "https://symfony.com", + "keywords": [ + "UID", + "ulid", + "uuid" + ], + "support": { + "source": "https://github.com/symfony/uid/tree/v7.3.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-06-27T19:55:54+00:00" + }, + { + "name": "symfony/var-dumper", + "version": "v7.3.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/var-dumper.git", + "reference": "53205bea27450dc5c65377518b3275e126d45e75" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/53205bea27450dc5c65377518b3275e126d45e75", + "reference": "53205bea27450dc5c65377518b3275e126d45e75", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/console": "<6.4" + }, + "require-dev": { + "symfony/console": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/uid": "^6.4|^7.0", + "twig/twig": "^3.12" + }, + "bin": [ + "Resources/bin/var-dump-server" + ], + "type": "library", + "autoload": { + "files": [ + "Resources/functions/dump.php" + ], + "psr-4": { + "Symfony\\Component\\VarDumper\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides mechanisms for walking through any arbitrary PHP variable", + "homepage": "https://symfony.com", + "keywords": [ + "debug", + "dump" + ], + "support": { + "source": "https://github.com/symfony/var-dumper/tree/v7.3.2" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-07-29T20:02:46+00:00" + }, + { + "name": "tijsverkoyen/css-to-inline-styles", + "version": "v2.3.0", + "source": { + "type": "git", + "url": "https://github.com/tijsverkoyen/CssToInlineStyles.git", + "reference": "0d72ac1c00084279c1816675284073c5a337c20d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/tijsverkoyen/CssToInlineStyles/zipball/0d72ac1c00084279c1816675284073c5a337c20d", + "reference": "0d72ac1c00084279c1816675284073c5a337c20d", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "php": "^7.4 || ^8.0", + "symfony/css-selector": "^5.4 || ^6.0 || ^7.0" + }, + "require-dev": { + "phpstan/phpstan": "^2.0", + "phpstan/phpstan-phpunit": "^2.0", + "phpunit/phpunit": "^8.5.21 || ^9.5.10" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "TijsVerkoyen\\CssToInlineStyles\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Tijs Verkoyen", + "email": "css_to_inline_styles@verkoyen.eu", + "role": "Developer" + } + ], + "description": "CssToInlineStyles is a class that enables you to convert HTML-pages/files into HTML-pages/files with inline styles. This is very useful when you're sending emails.", + "homepage": "https://github.com/tijsverkoyen/CssToInlineStyles", + "support": { + "issues": "https://github.com/tijsverkoyen/CssToInlineStyles/issues", + "source": "https://github.com/tijsverkoyen/CssToInlineStyles/tree/v2.3.0" + }, + "time": "2024-12-21T16:25:41+00:00" + }, + { + "name": "vlucas/phpdotenv", + "version": "v5.6.2", + "source": { + "type": "git", + "url": "https://github.com/vlucas/phpdotenv.git", + "reference": "24ac4c74f91ee2c193fa1aaa5c249cb0822809af" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/24ac4c74f91ee2c193fa1aaa5c249cb0822809af", + "reference": "24ac4c74f91ee2c193fa1aaa5c249cb0822809af", + "shasum": "" + }, + "require": { + "ext-pcre": "*", + "graham-campbell/result-type": "^1.1.3", + "php": "^7.2.5 || ^8.0", + "phpoption/phpoption": "^1.9.3", + "symfony/polyfill-ctype": "^1.24", + "symfony/polyfill-mbstring": "^1.24", + "symfony/polyfill-php80": "^1.24" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "ext-filter": "*", + "phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2" + }, + "suggest": { + "ext-filter": "Required to use the boolean validator." + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + }, + "branch-alias": { + "dev-master": "5.6-dev" + } + }, + "autoload": { + "psr-4": { + "Dotenv\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Vance Lucas", + "email": "vance@vancelucas.com", + "homepage": "https://github.com/vlucas" + } + ], + "description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.", + "keywords": [ + "dotenv", + "env", + "environment" + ], + "support": { + "issues": "https://github.com/vlucas/phpdotenv/issues", + "source": "https://github.com/vlucas/phpdotenv/tree/v5.6.2" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/vlucas/phpdotenv", + "type": "tidelift" + } + ], + "time": "2025-04-30T23:37:27+00:00" + }, + { + "name": "voku/portable-ascii", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/voku/portable-ascii.git", + "reference": "b1d923f88091c6bf09699efcd7c8a1b1bfd7351d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/voku/portable-ascii/zipball/b1d923f88091c6bf09699efcd7c8a1b1bfd7351d", + "reference": "b1d923f88091c6bf09699efcd7c8a1b1bfd7351d", + "shasum": "" + }, + "require": { + "php": ">=7.0.0" + }, + "require-dev": { + "phpunit/phpunit": "~6.0 || ~7.0 || ~9.0" + }, + "suggest": { + "ext-intl": "Use Intl for transliterator_transliterate() support" + }, + "type": "library", + "autoload": { + "psr-4": { + "voku\\": "src/voku/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Lars Moelleken", + "homepage": "https://www.moelleken.org/" + } + ], + "description": "Portable ASCII library - performance optimized (ascii) string functions for php.", + "homepage": "https://github.com/voku/portable-ascii", + "keywords": [ + "ascii", + "clean", + "php" + ], + "support": { + "issues": "https://github.com/voku/portable-ascii/issues", + "source": "https://github.com/voku/portable-ascii/tree/2.0.3" + }, + "funding": [ + { + "url": "https://www.paypal.me/moelleken", + "type": "custom" + }, + { + "url": "https://github.com/voku", + "type": "github" + }, + { + "url": "https://opencollective.com/portable-ascii", + "type": "open_collective" + }, + { + "url": "https://www.patreon.com/voku", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/voku/portable-ascii", + "type": "tidelift" + } + ], + "time": "2024-11-21T01:49:47+00:00" + }, + { + "name": "webmozart/assert", + "version": "1.11.0", + "source": { + "type": "git", + "url": "https://github.com/webmozarts/assert.git", + "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991", + "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "php": "^7.2 || ^8.0" + }, + "conflict": { + "phpstan/phpstan": "<0.12.20", + "vimeo/psalm": "<4.6.1 || 4.6.2" + }, + "require-dev": { + "phpunit/phpunit": "^8.5.13" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.10-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "support": { + "issues": "https://github.com/webmozarts/assert/issues", + "source": "https://github.com/webmozarts/assert/tree/1.11.0" + }, + "time": "2022-06-03T18:03:27+00:00" + } + ], + "packages-dev": [ + { + "name": "fakerphp/faker", + "version": "v1.24.1", + "source": { + "type": "git", + "url": "https://github.com/FakerPHP/Faker.git", + "reference": "e0ee18eb1e6dc3cda3ce9fd97e5a0689a88a64b5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/FakerPHP/Faker/zipball/e0ee18eb1e6dc3cda3ce9fd97e5a0689a88a64b5", + "reference": "e0ee18eb1e6dc3cda3ce9fd97e5a0689a88a64b5", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0", + "psr/container": "^1.0 || ^2.0", + "symfony/deprecation-contracts": "^2.2 || ^3.0" + }, + "conflict": { + "fzaninotto/faker": "*" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.4.1", + "doctrine/persistence": "^1.3 || ^2.0", + "ext-intl": "*", + "phpunit/phpunit": "^9.5.26", + "symfony/phpunit-bridge": "^5.4.16" + }, + "suggest": { + "doctrine/orm": "Required to use Faker\\ORM\\Doctrine", + "ext-curl": "Required by Faker\\Provider\\Image to download images.", + "ext-dom": "Required by Faker\\Provider\\HtmlLorem for generating random HTML.", + "ext-iconv": "Required by Faker\\Provider\\ru_RU\\Text::realText() for generating real Russian text.", + "ext-mbstring": "Required for multibyte Unicode string functionality." + }, + "type": "library", + "autoload": { + "psr-4": { + "Faker\\": "src/Faker/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "FranƧois Zaninotto" + } + ], + "description": "Faker is a PHP library that generates fake data for you.", + "keywords": [ + "data", + "faker", + "fixtures" + ], + "support": { + "issues": "https://github.com/FakerPHP/Faker/issues", + "source": "https://github.com/FakerPHP/Faker/tree/v1.24.1" + }, + "time": "2024-11-21T13:46:39+00:00" + }, + { + "name": "filp/whoops", + "version": "2.18.3", + "source": { + "type": "git", + "url": "https://github.com/filp/whoops.git", + "reference": "59a123a3d459c5a23055802237cb317f609867e5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/filp/whoops/zipball/59a123a3d459c5a23055802237cb317f609867e5", + "reference": "59a123a3d459c5a23055802237cb317f609867e5", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0", + "psr/log": "^1.0.1 || ^2.0 || ^3.0" + }, + "require-dev": { + "mockery/mockery": "^1.0", + "phpunit/phpunit": "^7.5.20 || ^8.5.8 || ^9.3.3", + "symfony/var-dumper": "^4.0 || ^5.0" + }, + "suggest": { + "symfony/var-dumper": "Pretty print complex values better with var-dumper available", + "whoops/soap": "Formats errors as SOAP responses" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "autoload": { + "psr-4": { + "Whoops\\": "src/Whoops/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Filipe Dobreira", + "homepage": "https://github.com/filp", + "role": "Developer" + } + ], + "description": "php error handling for cool kids", + "homepage": "https://filp.github.io/whoops/", + "keywords": [ + "error", + "exception", + "handling", + "library", + "throwable", + "whoops" + ], + "support": { + "issues": "https://github.com/filp/whoops/issues", + "source": "https://github.com/filp/whoops/tree/2.18.3" + }, + "funding": [ + { + "url": "https://github.com/denis-sokolov", + "type": "github" + } + ], + "time": "2025-06-16T00:02:10+00:00" + }, + { + "name": "hamcrest/hamcrest-php", + "version": "v2.1.1", + "source": { + "type": "git", + "url": "https://github.com/hamcrest/hamcrest-php.git", + "reference": "f8b1c0173b22fa6ec77a81fe63e5b01eba7e6487" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/f8b1c0173b22fa6ec77a81fe63e5b01eba7e6487", + "reference": "f8b1c0173b22fa6ec77a81fe63e5b01eba7e6487", + "shasum": "" + }, + "require": { + "php": "^7.4|^8.0" + }, + "replace": { + "cordoval/hamcrest-php": "*", + "davedevelopment/hamcrest-php": "*", + "kodova/hamcrest-php": "*" + }, + "require-dev": { + "phpunit/php-file-iterator": "^1.4 || ^2.0 || ^3.0", + "phpunit/phpunit": "^4.8.36 || ^5.7 || ^6.5 || ^7.0 || ^8.0 || ^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.1-dev" + } + }, + "autoload": { + "classmap": [ + "hamcrest" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "This is the PHP port of Hamcrest Matchers", + "keywords": [ + "test" + ], + "support": { + "issues": "https://github.com/hamcrest/hamcrest-php/issues", + "source": "https://github.com/hamcrest/hamcrest-php/tree/v2.1.1" + }, + "time": "2025-04-30T06:54:44+00:00" + }, + { + "name": "laravel/pail", + "version": "v1.2.3", + "source": { + "type": "git", + "url": "https://github.com/laravel/pail.git", + "reference": "8cc3d575c1f0e57eeb923f366a37528c50d2385a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/pail/zipball/8cc3d575c1f0e57eeb923f366a37528c50d2385a", + "reference": "8cc3d575c1f0e57eeb923f366a37528c50d2385a", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "illuminate/console": "^10.24|^11.0|^12.0", + "illuminate/contracts": "^10.24|^11.0|^12.0", + "illuminate/log": "^10.24|^11.0|^12.0", + "illuminate/process": "^10.24|^11.0|^12.0", + "illuminate/support": "^10.24|^11.0|^12.0", + "nunomaduro/termwind": "^1.15|^2.0", + "php": "^8.2", + "symfony/console": "^6.0|^7.0" + }, + "require-dev": { + "laravel/framework": "^10.24|^11.0|^12.0", + "laravel/pint": "^1.13", + "orchestra/testbench-core": "^8.13|^9.0|^10.0", + "pestphp/pest": "^2.20|^3.0", + "pestphp/pest-plugin-type-coverage": "^2.3|^3.0", + "phpstan/phpstan": "^1.12.27", + "symfony/var-dumper": "^6.3|^7.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Laravel\\Pail\\PailServiceProvider" + ] + }, + "branch-alias": { + "dev-main": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Laravel\\Pail\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + }, + { + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" + } + ], + "description": "Easily delve into your Laravel application's log files directly from the command line.", + "homepage": "https://github.com/laravel/pail", + "keywords": [ + "dev", + "laravel", + "logs", + "php", + "tail" + ], + "support": { + "issues": "https://github.com/laravel/pail/issues", + "source": "https://github.com/laravel/pail" + }, + "time": "2025-06-05T13:55:57+00:00" + }, + { + "name": "laravel/pint", + "version": "v1.24.0", + "source": { + "type": "git", + "url": "https://github.com/laravel/pint.git", + "reference": "0345f3b05f136801af8c339f9d16ef29e6b4df8a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/pint/zipball/0345f3b05f136801af8c339f9d16ef29e6b4df8a", + "reference": "0345f3b05f136801af8c339f9d16ef29e6b4df8a", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-mbstring": "*", + "ext-tokenizer": "*", + "ext-xml": "*", + "php": "^8.2.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.82.2", + "illuminate/view": "^11.45.1", + "larastan/larastan": "^3.5.0", + "laravel-zero/framework": "^11.45.0", + "mockery/mockery": "^1.6.12", + "nunomaduro/termwind": "^2.3.1", + "pestphp/pest": "^2.36.0" + }, + "bin": [ + "builds/pint" + ], + "type": "project", + "autoload": { + "files": [ + "overrides/Runner/Parallel/ProcessFactory.php" + ], + "psr-4": { + "App\\": "app/", + "Database\\Seeders\\": "database/seeders/", + "Database\\Factories\\": "database/factories/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" + } + ], + "description": "An opinionated code formatter for PHP.", + "homepage": "https://laravel.com", + "keywords": [ + "format", + "formatter", + "lint", + "linter", + "php" + ], + "support": { + "issues": "https://github.com/laravel/pint/issues", + "source": "https://github.com/laravel/pint" + }, + "time": "2025-07-10T18:09:32+00:00" + }, + { + "name": "laravel/sail", + "version": "v1.44.0", + "source": { + "type": "git", + "url": "https://github.com/laravel/sail.git", + "reference": "a09097bd2a8a38e23ac472fa6a6cf5b0d1c1d3fe" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/sail/zipball/a09097bd2a8a38e23ac472fa6a6cf5b0d1c1d3fe", + "reference": "a09097bd2a8a38e23ac472fa6a6cf5b0d1c1d3fe", + "shasum": "" + }, + "require": { + "illuminate/console": "^9.52.16|^10.0|^11.0|^12.0", + "illuminate/contracts": "^9.52.16|^10.0|^11.0|^12.0", + "illuminate/support": "^9.52.16|^10.0|^11.0|^12.0", + "php": "^8.0", + "symfony/console": "^6.0|^7.0", + "symfony/yaml": "^6.0|^7.0" + }, + "require-dev": { + "orchestra/testbench": "^7.0|^8.0|^9.0|^10.0", + "phpstan/phpstan": "^1.10" + }, + "bin": [ + "bin/sail" + ], + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Laravel\\Sail\\SailServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Laravel\\Sail\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "Docker files for running a basic Laravel application.", + "keywords": [ + "docker", + "laravel" + ], + "support": { + "issues": "https://github.com/laravel/sail/issues", + "source": "https://github.com/laravel/sail" + }, + "time": "2025-07-04T16:17:06+00:00" + }, + { + "name": "mockery/mockery", + "version": "1.6.12", + "source": { + "type": "git", + "url": "https://github.com/mockery/mockery.git", + "reference": "1f4efdd7d3beafe9807b08156dfcb176d18f1699" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mockery/mockery/zipball/1f4efdd7d3beafe9807b08156dfcb176d18f1699", + "reference": "1f4efdd7d3beafe9807b08156dfcb176d18f1699", + "shasum": "" + }, + "require": { + "hamcrest/hamcrest-php": "^2.0.1", + "lib-pcre": ">=7.0", + "php": ">=7.3" + }, + "conflict": { + "phpunit/phpunit": "<8.0" + }, + "require-dev": { + "phpunit/phpunit": "^8.5 || ^9.6.17", + "symplify/easy-coding-standard": "^12.1.14" + }, + "type": "library", + "autoload": { + "files": [ + "library/helpers.php", + "library/Mockery.php" + ], + "psr-4": { + "Mockery\\": "library/Mockery" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "PĆ”draic Brady", + "email": "padraic.brady@gmail.com", + "homepage": "https://github.com/padraic", + "role": "Author" + }, + { + "name": "Dave Marshall", + "email": "dave.marshall@atstsolutions.co.uk", + "homepage": "https://davedevelopment.co.uk", + "role": "Developer" + }, + { + "name": "Nathanael Esayeas", + "email": "nathanael.esayeas@protonmail.com", + "homepage": "https://github.com/ghostwriter", + "role": "Lead Developer" + } + ], + "description": "Mockery is a simple yet flexible PHP mock object framework", + "homepage": "https://github.com/mockery/mockery", + "keywords": [ + "BDD", + "TDD", + "library", + "mock", + "mock objects", + "mockery", + "stub", + "test", + "test double", + "testing" + ], + "support": { + "docs": "https://docs.mockery.io/", + "issues": "https://github.com/mockery/mockery/issues", + "rss": "https://github.com/mockery/mockery/releases.atom", + "security": "https://github.com/mockery/mockery/security/advisories", + "source": "https://github.com/mockery/mockery" + }, + "time": "2024-05-16T03:13:13+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.13.4", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/07d290f0c47959fd5eed98c95ee5602db07e0b6a", + "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "conflict": { + "doctrine/collections": "<1.6.8", + "doctrine/common": "<2.13.3 || >=3 <3.2.2" + }, + "require-dev": { + "doctrine/collections": "^1.6.8", + "doctrine/common": "^2.13.3 || ^3.2.2", + "phpspec/prophecy": "^1.10", + "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" + }, + "type": "library", + "autoload": { + "files": [ + "src/DeepCopy/deep_copy.php" + ], + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "support": { + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.13.4" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2025-08-01T08:46:24+00:00" + }, + { + "name": "nunomaduro/collision", + "version": "v8.8.2", + "source": { + "type": "git", + "url": "https://github.com/nunomaduro/collision.git", + "reference": "60207965f9b7b7a4ce15a0f75d57f9dadb105bdb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nunomaduro/collision/zipball/60207965f9b7b7a4ce15a0f75d57f9dadb105bdb", + "reference": "60207965f9b7b7a4ce15a0f75d57f9dadb105bdb", + "shasum": "" + }, + "require": { + "filp/whoops": "^2.18.1", + "nunomaduro/termwind": "^2.3.1", + "php": "^8.2.0", + "symfony/console": "^7.3.0" + }, + "conflict": { + "laravel/framework": "<11.44.2 || >=13.0.0", + "phpunit/phpunit": "<11.5.15 || >=13.0.0" + }, + "require-dev": { + "brianium/paratest": "^7.8.3", + "larastan/larastan": "^3.4.2", + "laravel/framework": "^11.44.2 || ^12.18", + "laravel/pint": "^1.22.1", + "laravel/sail": "^1.43.1", + "laravel/sanctum": "^4.1.1", + "laravel/tinker": "^2.10.1", + "orchestra/testbench-core": "^9.12.0 || ^10.4", + "pestphp/pest": "^3.8.2", + "sebastian/environment": "^7.2.1 || ^8.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "NunoMaduro\\Collision\\Adapters\\Laravel\\CollisionServiceProvider" + ] + }, + "branch-alias": { + "dev-8.x": "8.x-dev" + } + }, + "autoload": { + "files": [ + "./src/Adapters/Phpunit/Autoload.php" + ], + "psr-4": { + "NunoMaduro\\Collision\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" + } + ], + "description": "Cli error handling for console/command-line PHP applications.", + "keywords": [ + "artisan", + "cli", + "command-line", + "console", + "dev", + "error", + "handling", + "laravel", + "laravel-zero", + "php", + "symfony" + ], + "support": { + "issues": "https://github.com/nunomaduro/collision/issues", + "source": "https://github.com/nunomaduro/collision" + }, + "funding": [ + { + "url": "https://www.paypal.com/paypalme/enunomaduro", + "type": "custom" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + }, + { + "url": "https://www.patreon.com/nunomaduro", + "type": "patreon" + } + ], + "time": "2025-06-25T02:12:12+00:00" + }, + { + "name": "phar-io/manifest", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "54750ef60c58e43759730615a392c31c80e23176" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176", + "reference": "54750ef60c58e43759730615a392c31c80e23176", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-phar": "*", + "ext-xmlwriter": "*", + "phar-io/version": "^3.0.1", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "support": { + "issues": "https://github.com/phar-io/manifest/issues", + "source": "https://github.com/phar-io/manifest/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2024-03-03T12:33:53+00:00" + }, + { + "name": "phar-io/version", + "version": "3.2.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints", + "support": { + "issues": "https://github.com/phar-io/version/issues", + "source": "https://github.com/phar-io/version/tree/3.2.1" + }, + "time": "2022-02-21T01:04:05+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "11.0.10", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "1a800a7446add2d79cc6b3c01c45381810367d76" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/1a800a7446add2d79cc6b3c01c45381810367d76", + "reference": "1a800a7446add2d79cc6b3c01c45381810367d76", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-xmlwriter": "*", + "nikic/php-parser": "^5.4.0", + "php": ">=8.2", + "phpunit/php-file-iterator": "^5.1.0", + "phpunit/php-text-template": "^4.0.1", + "sebastian/code-unit-reverse-lookup": "^4.0.1", + "sebastian/complexity": "^4.0.1", + "sebastian/environment": "^7.2.0", + "sebastian/lines-of-code": "^3.0.1", + "sebastian/version": "^5.0.2", + "theseer/tokenizer": "^1.2.3" + }, + "require-dev": { + "phpunit/phpunit": "^11.5.2" + }, + "suggest": { + "ext-pcov": "PHP extension that provides line coverage", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "11.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/show" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/php-code-coverage", + "type": "tidelift" + } + ], + "time": "2025-06-18T08:56:18+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "5.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "118cfaaa8bc5aef3287bf315b6060b1174754af6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/118cfaaa8bc5aef3287bf315b6060b1174754af6", + "reference": "118cfaaa8bc5aef3287bf315b6060b1174754af6", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", + "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/5.1.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-08-27T05:02:59+00:00" + }, + { + "name": "phpunit/php-invoker", + "version": "5.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-invoker.git", + "reference": "c1ca3814734c07492b3d4c5f794f4b0995333da2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/c1ca3814734c07492b3d4c5f794f4b0995333da2", + "reference": "c1ca3814734c07492b3d4c5f794f4b0995333da2", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "ext-pcntl": "*", + "phpunit/phpunit": "^11.0" + }, + "suggest": { + "ext-pcntl": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Invoke callables with a timeout", + "homepage": "https://github.com/sebastianbergmann/php-invoker/", + "keywords": [ + "process" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-invoker/issues", + "security": "https://github.com/sebastianbergmann/php-invoker/security/policy", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/5.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T05:07:44+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "4.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "3e0404dc6b300e6bf56415467ebcb3fe4f33e964" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/3e0404dc6b300e6bf56415467ebcb3fe4f33e964", + "reference": "3e0404dc6b300e6bf56415467ebcb3fe4f33e964", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "security": "https://github.com/sebastianbergmann/php-text-template/security/policy", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/4.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T05:08:43+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "7.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "3b415def83fbcb41f991d9ebf16ae4ad8b7837b3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3b415def83fbcb41f991d9ebf16ae4ad8b7837b3", + "reference": "3b415def83fbcb41f991d9ebf16ae4ad8b7837b3", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "7.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "security": "https://github.com/sebastianbergmann/php-timer/security/policy", + "source": "https://github.com/sebastianbergmann/php-timer/tree/7.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T05:09:35+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "11.5.28", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "93f30aa3889e785ac63493d4976df0ae9fdecb60" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/93f30aa3889e785ac63493d4976df0ae9fdecb60", + "reference": "93f30aa3889e785ac63493d4976df0ae9fdecb60", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.13.3", + "phar-io/manifest": "^2.0.4", + "phar-io/version": "^3.2.1", + "php": ">=8.2", + "phpunit/php-code-coverage": "^11.0.10", + "phpunit/php-file-iterator": "^5.1.0", + "phpunit/php-invoker": "^5.0.1", + "phpunit/php-text-template": "^4.0.1", + "phpunit/php-timer": "^7.0.1", + "sebastian/cli-parser": "^3.0.2", + "sebastian/code-unit": "^3.0.3", + "sebastian/comparator": "^6.3.1", + "sebastian/diff": "^6.0.2", + "sebastian/environment": "^7.2.1", + "sebastian/exporter": "^6.3.0", + "sebastian/global-state": "^7.0.2", + "sebastian/object-enumerator": "^6.0.1", + "sebastian/type": "^5.1.2", + "sebastian/version": "^5.0.2", + "staabm/side-effects-detector": "^1.0.5" + }, + "suggest": { + "ext-soap": "To be able to generate mocks based on WSDL files" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "11.5-dev" + } + }, + "autoload": { + "files": [ + "src/Framework/Assert/Functions.php" + ], + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "security": "https://github.com/sebastianbergmann/phpunit/security/policy", + "source": "https://github.com/sebastianbergmann/phpunit/tree/11.5.28" + }, + "funding": [ + { + "url": "https://phpunit.de/sponsors.html", + "type": "custom" + }, + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", + "type": "tidelift" + } + ], + "time": "2025-07-31T07:10:28+00:00" + }, + { + "name": "sebastian/cli-parser", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "15c5dd40dc4f38794d383bb95465193f5e0ae180" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/15c5dd40dc4f38794d383bb95465193f5e0ae180", + "reference": "15c5dd40dc4f38794d383bb95465193f5e0ae180", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for parsing CLI options", + "homepage": "https://github.com/sebastianbergmann/cli-parser", + "support": { + "issues": "https://github.com/sebastianbergmann/cli-parser/issues", + "security": "https://github.com/sebastianbergmann/cli-parser/security/policy", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/3.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:41:36+00:00" + }, + { + "name": "sebastian/code-unit", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit.git", + "reference": "54391c61e4af8078e5b276ab082b6d3c54c9ad64" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/54391c61e4af8078e5b276ab082b6d3c54c9ad64", + "reference": "54391c61e4af8078e5b276ab082b6d3c54c9ad64", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the PHP code units", + "homepage": "https://github.com/sebastianbergmann/code-unit", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit/issues", + "security": "https://github.com/sebastianbergmann/code-unit/security/policy", + "source": "https://github.com/sebastianbergmann/code-unit/tree/3.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2025-03-19T07:56:08+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "4.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "183a9b2632194febd219bb9246eee421dad8d45e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/183a9b2632194febd219bb9246eee421dad8d45e", + "reference": "183a9b2632194febd219bb9246eee421dad8d45e", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", + "security": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/security/policy", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/4.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:45:54+00:00" + }, + { + "name": "sebastian/comparator", + "version": "6.3.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "24b8fbc2c8e201bb1308e7b05148d6ab393b6959" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/24b8fbc2c8e201bb1308e7b05148d6ab393b6959", + "reference": "24b8fbc2c8e201bb1308e7b05148d6ab393b6959", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-mbstring": "*", + "php": ">=8.2", + "sebastian/diff": "^6.0", + "sebastian/exporter": "^6.0" + }, + "require-dev": { + "phpunit/phpunit": "^11.4" + }, + "suggest": { + "ext-bcmath": "For comparing BcMath\\Number objects" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.3-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/comparator/issues", + "security": "https://github.com/sebastianbergmann/comparator/security/policy", + "source": "https://github.com/sebastianbergmann/comparator/tree/6.3.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2025-03-07T06:57:01+00:00" + }, + { + "name": "sebastian/complexity", + "version": "4.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/complexity.git", + "reference": "ee41d384ab1906c68852636b6de493846e13e5a0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/ee41d384ab1906c68852636b6de493846e13e5a0", + "reference": "ee41d384ab1906c68852636b6de493846e13e5a0", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^5.0", + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for calculating the complexity of PHP code units", + "homepage": "https://github.com/sebastianbergmann/complexity", + "support": { + "issues": "https://github.com/sebastianbergmann/complexity/issues", + "security": "https://github.com/sebastianbergmann/complexity/security/policy", + "source": "https://github.com/sebastianbergmann/complexity/tree/4.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:49:50+00:00" + }, + { + "name": "sebastian/diff", + "version": "6.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/b4ccd857127db5d41a5b676f24b51371d76d8544", + "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0", + "symfony/process": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "security": "https://github.com/sebastianbergmann/diff/security/policy", + "source": "https://github.com/sebastianbergmann/diff/tree/6.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:53:05+00:00" + }, + { + "name": "sebastian/environment", + "version": "7.2.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "a5c75038693ad2e8d4b6c15ba2403532647830c4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/a5c75038693ad2e8d4b6c15ba2403532647830c4", + "reference": "a5c75038693ad2e8d4b6c15ba2403532647830c4", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.3" + }, + "suggest": { + "ext-posix": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "7.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "https://github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "security": "https://github.com/sebastianbergmann/environment/security/policy", + "source": "https://github.com/sebastianbergmann/environment/tree/7.2.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/environment", + "type": "tidelift" + } + ], + "time": "2025-05-21T11:55:47+00:00" + }, + { + "name": "sebastian/exporter", + "version": "6.3.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "3473f61172093b2da7de1fb5782e1f24cc036dc3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/3473f61172093b2da7de1fb5782e1f24cc036dc3", + "reference": "3473f61172093b2da7de1fb5782e1f24cc036dc3", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": ">=8.2", + "sebastian/recursion-context": "^6.0" + }, + "require-dev": { + "phpunit/phpunit": "^11.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "https://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/exporter/issues", + "security": "https://github.com/sebastianbergmann/exporter/security/policy", + "source": "https://github.com/sebastianbergmann/exporter/tree/6.3.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-12-05T09:17:50+00:00" + }, + { + "name": "sebastian/global-state", + "version": "7.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "3be331570a721f9a4b5917f4209773de17f747d7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/3be331570a721f9a4b5917f4209773de17f747d7", + "reference": "3be331570a721f9a4b5917f4209773de17f747d7", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "sebastian/object-reflector": "^4.0", + "sebastian/recursion-context": "^6.0" + }, + "require-dev": { + "ext-dom": "*", + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "7.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "https://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "security": "https://github.com/sebastianbergmann/global-state/security/policy", + "source": "https://github.com/sebastianbergmann/global-state/tree/7.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:57:36+00:00" + }, + { + "name": "sebastian/lines-of-code", + "version": "3.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/lines-of-code.git", + "reference": "d36ad0d782e5756913e42ad87cb2890f4ffe467a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/d36ad0d782e5756913e42ad87cb2890f4ffe467a", + "reference": "d36ad0d782e5756913e42ad87cb2890f4ffe467a", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^5.0", + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for counting the lines of code in PHP source code", + "homepage": "https://github.com/sebastianbergmann/lines-of-code", + "support": { + "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", + "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/3.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:58:38+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "6.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "f5b498e631a74204185071eb41f33f38d64608aa" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/f5b498e631a74204185071eb41f33f38d64608aa", + "reference": "f5b498e631a74204185071eb41f33f38d64608aa", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "sebastian/object-reflector": "^4.0", + "sebastian/recursion-context": "^6.0" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", + "security": "https://github.com/sebastianbergmann/object-enumerator/security/policy", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/6.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T05:00:13+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "4.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "6e1a43b411b2ad34146dee7524cb13a068bb35f9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/6e1a43b411b2ad34146dee7524cb13a068bb35f9", + "reference": "6e1a43b411b2ad34146dee7524cb13a068bb35f9", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-reflector/issues", + "security": "https://github.com/sebastianbergmann/object-reflector/security/policy", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/4.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T05:01:32+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "6.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "694d156164372abbd149a4b85ccda2e4670c0e16" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/694d156164372abbd149a4b85ccda2e4670c0e16", + "reference": "694d156164372abbd149a4b85ccda2e4670c0e16", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "https://github.com/sebastianbergmann/recursion-context", + "support": { + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "security": "https://github.com/sebastianbergmann/recursion-context/security/policy", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/6.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T05:10:34+00:00" + }, + { + "name": "sebastian/type", + "version": "5.1.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "a8a7e30534b0eb0c77cd9d07e82de1a114389f5e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/a8a7e30534b0eb0c77cd9d07e82de1a114389f5e", + "reference": "a8a7e30534b0eb0c77cd9d07e82de1a114389f5e", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the types of the PHP type system", + "homepage": "https://github.com/sebastianbergmann/type", + "support": { + "issues": "https://github.com/sebastianbergmann/type/issues", + "security": "https://github.com/sebastianbergmann/type/security/policy", + "source": "https://github.com/sebastianbergmann/type/tree/5.1.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2025-03-18T13:35:50+00:00" + }, + { + "name": "sebastian/version", + "version": "5.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "c687e3387b99f5b03b6caa64c74b63e2936ff874" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c687e3387b99f5b03b6caa64c74b63e2936ff874", + "reference": "c687e3387b99f5b03b6caa64c74b63e2936ff874", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "support": { + "issues": "https://github.com/sebastianbergmann/version/issues", + "security": "https://github.com/sebastianbergmann/version/security/policy", + "source": "https://github.com/sebastianbergmann/version/tree/5.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-10-09T05:16:32+00:00" + }, + { + "name": "staabm/side-effects-detector", + "version": "1.0.5", + "source": { + "type": "git", + "url": "https://github.com/staabm/side-effects-detector.git", + "reference": "d8334211a140ce329c13726d4a715adbddd0a163" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/staabm/side-effects-detector/zipball/d8334211a140ce329c13726d4a715adbddd0a163", + "reference": "d8334211a140ce329c13726d4a715adbddd0a163", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phpstan/extension-installer": "^1.4.3", + "phpstan/phpstan": "^1.12.6", + "phpunit/phpunit": "^9.6.21", + "symfony/var-dumper": "^5.4.43", + "tomasvotruba/type-coverage": "1.0.0", + "tomasvotruba/unused-public": "1.0.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "lib/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A static analysis tool to detect side effects in PHP code", + "keywords": [ + "static analysis" + ], + "support": { + "issues": "https://github.com/staabm/side-effects-detector/issues", + "source": "https://github.com/staabm/side-effects-detector/tree/1.0.5" + }, + "funding": [ + { + "url": "https://github.com/staabm", + "type": "github" + } + ], + "time": "2024-10-20T05:08:20+00:00" + }, + { + "name": "symfony/yaml", + "version": "v7.3.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "b8d7d868da9eb0919e99c8830431ea087d6aae30" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/b8d7d868da9eb0919e99c8830431ea087d6aae30", + "reference": "b8d7d868da9eb0919e99c8830431ea087d6aae30", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3.0", + "symfony/polyfill-ctype": "^1.8" + }, + "conflict": { + "symfony/console": "<6.4" + }, + "require-dev": { + "symfony/console": "^6.4|^7.0" + }, + "bin": [ + "Resources/bin/yaml-lint" + ], + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Yaml\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Loads and dumps YAML files", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/yaml/tree/v7.3.2" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-07-10T08:47:49+00:00" + }, + { + "name": "theseer/tokenizer", + "version": "1.2.3", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", + "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + } + ], + "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "support": { + "issues": "https://github.com/theseer/tokenizer/issues", + "source": "https://github.com/theseer/tokenizer/tree/1.2.3" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2024-03-03T12:36:25+00:00" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": true, + "prefer-lowest": false, + "platform": { + "php": "^8.2" + }, + "platform-dev": [], + "plugin-api-version": "2.6.0" +} diff --git a/config/app.php b/config/app.php new file mode 100644 index 0000000..423eed5 --- /dev/null +++ b/config/app.php @@ -0,0 +1,126 @@ + env('APP_NAME', 'Laravel'), + + /* + |-------------------------------------------------------------------------- + | Application Environment + |-------------------------------------------------------------------------- + | + | This value determines the "environment" your application is currently + | running in. This may determine how you prefer to configure various + | services the application utilizes. Set this in your ".env" file. + | + */ + + 'env' => env('APP_ENV', 'production'), + + /* + |-------------------------------------------------------------------------- + | Application Debug Mode + |-------------------------------------------------------------------------- + | + | When your application is in debug mode, detailed error messages with + | stack traces will be shown on every error that occurs within your + | application. If disabled, a simple generic error page is shown. + | + */ + + 'debug' => (bool) env('APP_DEBUG', false), + + /* + |-------------------------------------------------------------------------- + | Application URL + |-------------------------------------------------------------------------- + | + | This URL is used by the console to properly generate URLs when using + | the Artisan command line tool. You should set this to the root of + | the application so that it's available within Artisan commands. + | + */ + + 'url' => env('APP_URL', 'http://localhost'), + + /* + |-------------------------------------------------------------------------- + | Application Timezone + |-------------------------------------------------------------------------- + | + | Here you may specify the default timezone for your application, which + | will be used by the PHP date and date-time functions. The timezone + | is set to "UTC" by default as it is suitable for most use cases. + | + */ + + 'timezone' => 'UTC', + + /* + |-------------------------------------------------------------------------- + | Application Locale Configuration + |-------------------------------------------------------------------------- + | + | The application locale determines the default locale that will be used + | by Laravel's translation / localization methods. This option can be + | set to any locale for which you plan to have translation strings. + | + */ + + 'locale' => env('APP_LOCALE', 'en'), + + 'fallback_locale' => env('APP_FALLBACK_LOCALE', 'en'), + + 'faker_locale' => env('APP_FAKER_LOCALE', 'en_US'), + + /* + |-------------------------------------------------------------------------- + | Encryption Key + |-------------------------------------------------------------------------- + | + | This key is utilized by Laravel's encryption services and should be set + | to a random, 32 character string to ensure that all encrypted values + | are secure. You should do this prior to deploying the application. + | + */ + + 'cipher' => 'AES-256-CBC', + + 'key' => env('APP_KEY'), + + 'previous_keys' => [ + ...array_filter( + explode(',', (string) env('APP_PREVIOUS_KEYS', '')) + ), + ], + + /* + |-------------------------------------------------------------------------- + | Maintenance Mode Driver + |-------------------------------------------------------------------------- + | + | These configuration options determine the driver used to determine and + | manage Laravel's "maintenance mode" status. The "cache" driver will + | allow maintenance mode to be controlled across multiple machines. + | + | Supported drivers: "file", "cache" + | + */ + + 'maintenance' => [ + 'driver' => env('APP_MAINTENANCE_DRIVER', 'file'), + 'store' => env('APP_MAINTENANCE_STORE', 'database'), + ], + +]; diff --git a/config/auth.php b/config/auth.php new file mode 100644 index 0000000..fc8b76c --- /dev/null +++ b/config/auth.php @@ -0,0 +1,118 @@ + [ + 'guard' => env('AUTH_GUARD', 'web'), + 'passwords' => env('AUTH_PASSWORD_BROKER', 'users'), + ], + + /* + |-------------------------------------------------------------------------- + | Authentication Guards + |-------------------------------------------------------------------------- + | + | Next, you may define every authentication guard for your application. + | Of course, a great default configuration has been defined for you + | which utilizes session storage plus the Eloquent user provider. + | + | All authentication guards have a user provider, which defines how the + | users are actually retrieved out of your database or other storage + | system used by the application. Typically, Eloquent is utilized. + | + | Supported: "session" + | + */ + + 'guards' => [ + 'web' => [ + 'driver' => 'session', + 'provider' => 'users', + ], + 'admin' => [ + 'driver' => 'session', + 'provider' => 'admins', + ], + ], + + /* + |-------------------------------------------------------------------------- + | User Providers + |-------------------------------------------------------------------------- + | + | All authentication guards have a user provider, which defines how the + | users are actually retrieved out of your database or other storage + | system used by the application. Typically, Eloquent is utilized. + | + | If you have multiple user tables or models you may configure multiple + | providers to represent the model / table. These providers may then + | be assigned to any extra authentication guards you have defined. + | + | Supported: "database", "eloquent" + | + */ + + 'providers' => [ + 'users' => [ + 'driver' => 'eloquent', + 'model' => env('AUTH_MODEL', App\Models\User::class), + ], + 'admins' => [ + 'driver' => 'eloquent', + 'model' => App\Models\Admin::class, + ], + ], + + /* + |-------------------------------------------------------------------------- + | Resetting Passwords + |-------------------------------------------------------------------------- + | + | These configuration options specify the behavior of Laravel's password + | reset functionality, including the table utilized for token storage + | and the user provider that is invoked to actually retrieve users. + | + | The expiry time is the number of minutes that each reset token will be + | considered valid. This security feature keeps tokens short-lived so + | they have less time to be guessed. You may change this as needed. + | + | The throttle setting is the number of seconds a user must wait before + | generating more password reset tokens. This prevents the user from + | quickly generating a very large amount of password reset tokens. + | + */ + + 'passwords' => [ + 'users' => [ + 'provider' => 'users', + 'table' => env('AUTH_PASSWORD_RESET_TOKEN_TABLE', 'password_reset_tokens'), + 'expire' => 60, + 'throttle' => 60, + ], + ], + + /* + |-------------------------------------------------------------------------- + | Password Confirmation Timeout + |-------------------------------------------------------------------------- + | + | Here you may define the number of seconds before a password confirmation + | window expires and users are asked to re-enter their password via the + | confirmation screen. By default, the timeout lasts for three hours. + | + */ + + 'password_timeout' => env('AUTH_PASSWORD_TIMEOUT', 10800), + +]; diff --git a/config/cache.php b/config/cache.php new file mode 100644 index 0000000..c2d927d --- /dev/null +++ b/config/cache.php @@ -0,0 +1,108 @@ + env('CACHE_STORE', 'database'), + + /* + |-------------------------------------------------------------------------- + | Cache Stores + |-------------------------------------------------------------------------- + | + | Here you may define all of the cache "stores" for your application as + | well as their drivers. You may even define multiple stores for the + | same cache driver to group types of items stored in your caches. + | + | Supported drivers: "array", "database", "file", "memcached", + | "redis", "dynamodb", "octane", "null" + | + */ + + 'stores' => [ + + 'array' => [ + 'driver' => 'array', + 'serialize' => false, + ], + + 'database' => [ + 'driver' => 'database', + 'connection' => env('DB_CACHE_CONNECTION'), + 'table' => env('DB_CACHE_TABLE', 'cache'), + 'lock_connection' => env('DB_CACHE_LOCK_CONNECTION'), + 'lock_table' => env('DB_CACHE_LOCK_TABLE'), + ], + + 'file' => [ + 'driver' => 'file', + 'path' => storage_path('framework/cache/data'), + 'lock_path' => storage_path('framework/cache/data'), + ], + + 'memcached' => [ + 'driver' => 'memcached', + 'persistent_id' => env('MEMCACHED_PERSISTENT_ID'), + 'sasl' => [ + env('MEMCACHED_USERNAME'), + env('MEMCACHED_PASSWORD'), + ], + 'options' => [ + // Memcached::OPT_CONNECT_TIMEOUT => 2000, + ], + 'servers' => [ + [ + 'host' => env('MEMCACHED_HOST', '127.0.0.1'), + 'port' => env('MEMCACHED_PORT', 11211), + 'weight' => 100, + ], + ], + ], + + 'redis' => [ + 'driver' => 'redis', + 'connection' => env('REDIS_CACHE_CONNECTION', 'cache'), + 'lock_connection' => env('REDIS_CACHE_LOCK_CONNECTION', 'default'), + ], + + 'dynamodb' => [ + 'driver' => 'dynamodb', + 'key' => env('AWS_ACCESS_KEY_ID'), + 'secret' => env('AWS_SECRET_ACCESS_KEY'), + 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), + 'table' => env('DYNAMODB_CACHE_TABLE', 'cache'), + 'endpoint' => env('DYNAMODB_ENDPOINT'), + ], + + 'octane' => [ + 'driver' => 'octane', + ], + + ], + + /* + |-------------------------------------------------------------------------- + | Cache Key Prefix + |-------------------------------------------------------------------------- + | + | When utilizing the APC, database, memcached, Redis, and DynamoDB cache + | stores, there might be other applications using the same cache. For + | that reason, you may prefix every cache key to avoid collisions. + | + */ + + 'prefix' => env('CACHE_PREFIX', Str::slug((string) env('APP_NAME', 'laravel')).'-cache-'), + +]; diff --git a/config/database.php b/config/database.php new file mode 100644 index 0000000..5b318f5 --- /dev/null +++ b/config/database.php @@ -0,0 +1,174 @@ + env('DB_CONNECTION', 'sqlite'), + + /* + |-------------------------------------------------------------------------- + | Database Connections + |-------------------------------------------------------------------------- + | + | Below are all of the database connections defined for your application. + | An example configuration is provided for each database system which + | is supported by Laravel. You're free to add / remove connections. + | + */ + + 'connections' => [ + + 'sqlite' => [ + 'driver' => 'sqlite', + 'url' => env('DB_URL'), + 'database' => env('DB_DATABASE', database_path('database.sqlite')), + 'prefix' => '', + 'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true), + 'busy_timeout' => null, + 'journal_mode' => null, + 'synchronous' => null, + ], + + 'mysql' => [ + 'driver' => 'mysql', + 'url' => env('DB_URL'), + 'host' => env('DB_HOST', '127.0.0.1'), + 'port' => env('DB_PORT', '3306'), + 'database' => env('DB_DATABASE', 'laravel'), + 'username' => env('DB_USERNAME', 'root'), + 'password' => env('DB_PASSWORD', ''), + 'unix_socket' => env('DB_SOCKET', ''), + 'charset' => env('DB_CHARSET', 'utf8mb4'), + 'collation' => env('DB_COLLATION', 'utf8mb4_unicode_ci'), + 'prefix' => '', + 'prefix_indexes' => true, + 'strict' => true, + 'engine' => null, + 'options' => extension_loaded('pdo_mysql') ? array_filter([ + PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'), + ]) : [], + ], + + 'mariadb' => [ + 'driver' => 'mariadb', + 'url' => env('DB_URL'), + 'host' => env('DB_HOST', '127.0.0.1'), + 'port' => env('DB_PORT', '3306'), + 'database' => env('DB_DATABASE', 'laravel'), + 'username' => env('DB_USERNAME', 'root'), + 'password' => env('DB_PASSWORD', ''), + 'unix_socket' => env('DB_SOCKET', ''), + 'charset' => env('DB_CHARSET', 'utf8mb4'), + 'collation' => env('DB_COLLATION', 'utf8mb4_unicode_ci'), + 'prefix' => '', + 'prefix_indexes' => true, + 'strict' => true, + 'engine' => null, + 'options' => extension_loaded('pdo_mysql') ? array_filter([ + PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'), + ]) : [], + ], + + 'pgsql' => [ + 'driver' => 'pgsql', + 'url' => env('DB_URL'), + 'host' => env('DB_HOST', '127.0.0.1'), + 'port' => env('DB_PORT', '5432'), + 'database' => env('DB_DATABASE', 'laravel'), + 'username' => env('DB_USERNAME', 'root'), + 'password' => env('DB_PASSWORD', ''), + 'charset' => env('DB_CHARSET', 'utf8'), + 'prefix' => '', + 'prefix_indexes' => true, + 'search_path' => 'public', + 'sslmode' => 'prefer', + ], + + 'sqlsrv' => [ + 'driver' => 'sqlsrv', + 'url' => env('DB_URL'), + 'host' => env('DB_HOST', 'localhost'), + 'port' => env('DB_PORT', '1433'), + 'database' => env('DB_DATABASE', 'laravel'), + 'username' => env('DB_USERNAME', 'root'), + 'password' => env('DB_PASSWORD', ''), + 'charset' => env('DB_CHARSET', 'utf8'), + 'prefix' => '', + 'prefix_indexes' => true, + // 'encrypt' => env('DB_ENCRYPT', 'yes'), + // 'trust_server_certificate' => env('DB_TRUST_SERVER_CERTIFICATE', 'false'), + ], + + ], + + /* + |-------------------------------------------------------------------------- + | Migration Repository Table + |-------------------------------------------------------------------------- + | + | This table keeps track of all the migrations that have already run for + | your application. Using this information, we can determine which of + | the migrations on disk haven't actually been run on the database. + | + */ + + 'migrations' => [ + 'table' => 'migrations', + 'update_date_on_publish' => true, + ], + + /* + |-------------------------------------------------------------------------- + | Redis Databases + |-------------------------------------------------------------------------- + | + | Redis is an open source, fast, and advanced key-value store that also + | provides a richer body of commands than a typical key-value system + | such as Memcached. You may define your connection settings here. + | + */ + + 'redis' => [ + + 'client' => env('REDIS_CLIENT', 'phpredis'), + + 'options' => [ + 'cluster' => env('REDIS_CLUSTER', 'redis'), + 'prefix' => env('REDIS_PREFIX', Str::slug((string) env('APP_NAME', 'laravel')).'-database-'), + 'persistent' => env('REDIS_PERSISTENT', false), + ], + + 'default' => [ + 'url' => env('REDIS_URL'), + 'host' => env('REDIS_HOST', '127.0.0.1'), + 'username' => env('REDIS_USERNAME'), + 'password' => env('REDIS_PASSWORD'), + 'port' => env('REDIS_PORT', '6379'), + 'database' => env('REDIS_DB', '0'), + ], + + 'cache' => [ + 'url' => env('REDIS_URL'), + 'host' => env('REDIS_HOST', '127.0.0.1'), + 'username' => env('REDIS_USERNAME'), + 'password' => env('REDIS_PASSWORD'), + 'port' => env('REDIS_PORT', '6379'), + 'database' => env('REDIS_CACHE_DB', '1'), + ], + + ], + +]; diff --git a/config/filesystems.php b/config/filesystems.php new file mode 100644 index 0000000..3d671bd --- /dev/null +++ b/config/filesystems.php @@ -0,0 +1,80 @@ + env('FILESYSTEM_DISK', 'local'), + + /* + |-------------------------------------------------------------------------- + | Filesystem Disks + |-------------------------------------------------------------------------- + | + | Below you may configure as many filesystem disks as necessary, and you + | may even configure multiple disks for the same driver. Examples for + | most supported storage drivers are configured here for reference. + | + | Supported drivers: "local", "ftp", "sftp", "s3" + | + */ + + 'disks' => [ + + 'local' => [ + 'driver' => 'local', + 'root' => storage_path('app/private'), + 'serve' => true, + 'throw' => false, + 'report' => false, + ], + + 'public' => [ + 'driver' => 'local', + 'root' => storage_path('app/public'), + 'url' => env('APP_URL').'/storage', + 'visibility' => 'public', + 'throw' => false, + 'report' => false, + ], + + 's3' => [ + 'driver' => 's3', + 'key' => env('AWS_ACCESS_KEY_ID'), + 'secret' => env('AWS_SECRET_ACCESS_KEY'), + 'region' => env('AWS_DEFAULT_REGION'), + 'bucket' => env('AWS_BUCKET'), + 'url' => env('AWS_URL'), + 'endpoint' => env('AWS_ENDPOINT'), + 'use_path_style_endpoint' => env('AWS_USE_PATH_STYLE_ENDPOINT', false), + 'throw' => false, + 'report' => false, + ], + + ], + + /* + |-------------------------------------------------------------------------- + | Symbolic Links + |-------------------------------------------------------------------------- + | + | Here you may configure the symbolic links that will be created when the + | `storage:link` Artisan command is executed. The array keys should be + | the locations of the links and the values should be their targets. + | + */ + + 'links' => [ + public_path('storage') => storage_path('app/public'), + ], + +]; diff --git a/config/logging.php b/config/logging.php new file mode 100644 index 0000000..9e998a4 --- /dev/null +++ b/config/logging.php @@ -0,0 +1,132 @@ + env('LOG_CHANNEL', 'stack'), + + /* + |-------------------------------------------------------------------------- + | Deprecations Log Channel + |-------------------------------------------------------------------------- + | + | This option controls the log channel that should be used to log warnings + | regarding deprecated PHP and library features. This allows you to get + | your application ready for upcoming major versions of dependencies. + | + */ + + 'deprecations' => [ + 'channel' => env('LOG_DEPRECATIONS_CHANNEL', 'null'), + 'trace' => env('LOG_DEPRECATIONS_TRACE', false), + ], + + /* + |-------------------------------------------------------------------------- + | Log Channels + |-------------------------------------------------------------------------- + | + | Here you may configure the log channels for your application. Laravel + | utilizes the Monolog PHP logging library, which includes a variety + | of powerful log handlers and formatters that you're free to use. + | + | Available drivers: "single", "daily", "slack", "syslog", + | "errorlog", "monolog", "custom", "stack" + | + */ + + 'channels' => [ + + 'stack' => [ + 'driver' => 'stack', + 'channels' => explode(',', (string) env('LOG_STACK', 'single')), + 'ignore_exceptions' => false, + ], + + 'single' => [ + 'driver' => 'single', + 'path' => storage_path('logs/laravel.log'), + 'level' => env('LOG_LEVEL', 'debug'), + 'replace_placeholders' => true, + ], + + 'daily' => [ + 'driver' => 'daily', + 'path' => storage_path('logs/laravel.log'), + 'level' => env('LOG_LEVEL', 'debug'), + 'days' => env('LOG_DAILY_DAYS', 14), + 'replace_placeholders' => true, + ], + + 'slack' => [ + 'driver' => 'slack', + 'url' => env('LOG_SLACK_WEBHOOK_URL'), + 'username' => env('LOG_SLACK_USERNAME', 'Laravel Log'), + 'emoji' => env('LOG_SLACK_EMOJI', ':boom:'), + 'level' => env('LOG_LEVEL', 'critical'), + 'replace_placeholders' => true, + ], + + 'papertrail' => [ + 'driver' => 'monolog', + 'level' => env('LOG_LEVEL', 'debug'), + 'handler' => env('LOG_PAPERTRAIL_HANDLER', SyslogUdpHandler::class), + 'handler_with' => [ + 'host' => env('PAPERTRAIL_URL'), + 'port' => env('PAPERTRAIL_PORT'), + 'connectionString' => 'tls://'.env('PAPERTRAIL_URL').':'.env('PAPERTRAIL_PORT'), + ], + 'processors' => [PsrLogMessageProcessor::class], + ], + + 'stderr' => [ + 'driver' => 'monolog', + 'level' => env('LOG_LEVEL', 'debug'), + 'handler' => StreamHandler::class, + 'handler_with' => [ + 'stream' => 'php://stderr', + ], + 'formatter' => env('LOG_STDERR_FORMATTER'), + 'processors' => [PsrLogMessageProcessor::class], + ], + + 'syslog' => [ + 'driver' => 'syslog', + 'level' => env('LOG_LEVEL', 'debug'), + 'facility' => env('LOG_SYSLOG_FACILITY', LOG_USER), + 'replace_placeholders' => true, + ], + + 'errorlog' => [ + 'driver' => 'errorlog', + 'level' => env('LOG_LEVEL', 'debug'), + 'replace_placeholders' => true, + ], + + 'null' => [ + 'driver' => 'monolog', + 'handler' => NullHandler::class, + ], + + 'emergency' => [ + 'path' => storage_path('logs/laravel.log'), + ], + + ], + +]; diff --git a/config/mail.php b/config/mail.php new file mode 100644 index 0000000..522b284 --- /dev/null +++ b/config/mail.php @@ -0,0 +1,118 @@ + env('MAIL_MAILER', 'log'), + + /* + |-------------------------------------------------------------------------- + | Mailer Configurations + |-------------------------------------------------------------------------- + | + | Here you may configure all of the mailers used by your application plus + | their respective settings. Several examples have been configured for + | you and you are free to add your own as your application requires. + | + | Laravel supports a variety of mail "transport" drivers that can be used + | when delivering an email. You may specify which one you're using for + | your mailers below. You may also add additional mailers if needed. + | + | Supported: "smtp", "sendmail", "mailgun", "ses", "ses-v2", + | "postmark", "resend", "log", "array", + | "failover", "roundrobin" + | + */ + + 'mailers' => [ + + 'smtp' => [ + 'transport' => 'smtp', + 'scheme' => env('MAIL_SCHEME'), + 'url' => env('MAIL_URL'), + 'host' => env('MAIL_HOST', '127.0.0.1'), + 'port' => env('MAIL_PORT', 2525), + 'username' => env('MAIL_USERNAME'), + 'password' => env('MAIL_PASSWORD'), + 'timeout' => null, + 'local_domain' => env('MAIL_EHLO_DOMAIN', parse_url((string) env('APP_URL', 'http://localhost'), PHP_URL_HOST)), + ], + + 'ses' => [ + 'transport' => 'ses', + ], + + 'postmark' => [ + 'transport' => 'postmark', + // 'message_stream_id' => env('POSTMARK_MESSAGE_STREAM_ID'), + // 'client' => [ + // 'timeout' => 5, + // ], + ], + + 'resend' => [ + 'transport' => 'resend', + ], + + 'sendmail' => [ + 'transport' => 'sendmail', + 'path' => env('MAIL_SENDMAIL_PATH', '/usr/sbin/sendmail -bs -i'), + ], + + 'log' => [ + 'transport' => 'log', + 'channel' => env('MAIL_LOG_CHANNEL'), + ], + + 'array' => [ + 'transport' => 'array', + ], + + 'failover' => [ + 'transport' => 'failover', + 'mailers' => [ + 'smtp', + 'log', + ], + 'retry_after' => 60, + ], + + 'roundrobin' => [ + 'transport' => 'roundrobin', + 'mailers' => [ + 'ses', + 'postmark', + ], + 'retry_after' => 60, + ], + + ], + + /* + |-------------------------------------------------------------------------- + | Global "From" Address + |-------------------------------------------------------------------------- + | + | You may wish for all emails sent by your application to be sent from + | the same address. Here you may specify a name and address that is + | used globally for all emails that are sent by your application. + | + */ + + 'from' => [ + 'address' => env('MAIL_FROM_ADDRESS', 'hello@example.com'), + 'name' => env('MAIL_FROM_NAME', 'Example'), + ], + +]; diff --git a/config/queue.php b/config/queue.php new file mode 100644 index 0000000..116bd8d --- /dev/null +++ b/config/queue.php @@ -0,0 +1,112 @@ + env('QUEUE_CONNECTION', 'database'), + + /* + |-------------------------------------------------------------------------- + | Queue Connections + |-------------------------------------------------------------------------- + | + | Here you may configure the connection options for every queue backend + | used by your application. An example configuration is provided for + | each backend supported by Laravel. You're also free to add more. + | + | Drivers: "sync", "database", "beanstalkd", "sqs", "redis", "null" + | + */ + + 'connections' => [ + + 'sync' => [ + 'driver' => 'sync', + ], + + 'database' => [ + 'driver' => 'database', + 'connection' => env('DB_QUEUE_CONNECTION'), + 'table' => env('DB_QUEUE_TABLE', 'jobs'), + 'queue' => env('DB_QUEUE', 'default'), + 'retry_after' => (int) env('DB_QUEUE_RETRY_AFTER', 90), + 'after_commit' => false, + ], + + 'beanstalkd' => [ + 'driver' => 'beanstalkd', + 'host' => env('BEANSTALKD_QUEUE_HOST', 'localhost'), + 'queue' => env('BEANSTALKD_QUEUE', 'default'), + 'retry_after' => (int) env('BEANSTALKD_QUEUE_RETRY_AFTER', 90), + 'block_for' => 0, + 'after_commit' => false, + ], + + 'sqs' => [ + 'driver' => 'sqs', + 'key' => env('AWS_ACCESS_KEY_ID'), + 'secret' => env('AWS_SECRET_ACCESS_KEY'), + 'prefix' => env('SQS_PREFIX', 'https://sqs.us-east-1.amazonaws.com/your-account-id'), + 'queue' => env('SQS_QUEUE', 'default'), + 'suffix' => env('SQS_SUFFIX'), + 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), + 'after_commit' => false, + ], + + 'redis' => [ + 'driver' => 'redis', + 'connection' => env('REDIS_QUEUE_CONNECTION', 'default'), + 'queue' => env('REDIS_QUEUE', 'default'), + 'retry_after' => (int) env('REDIS_QUEUE_RETRY_AFTER', 90), + 'block_for' => null, + 'after_commit' => false, + ], + + ], + + /* + |-------------------------------------------------------------------------- + | Job Batching + |-------------------------------------------------------------------------- + | + | The following options configure the database and table that store job + | batching information. These options can be updated to any database + | connection and table which has been defined by your application. + | + */ + + 'batching' => [ + 'database' => env('DB_CONNECTION', 'sqlite'), + 'table' => 'job_batches', + ], + + /* + |-------------------------------------------------------------------------- + | Failed Queue Jobs + |-------------------------------------------------------------------------- + | + | These options configure the behavior of failed queue job logging so you + | can control how and where failed jobs are stored. Laravel ships with + | support for storing failed jobs in a simple file or in a database. + | + | Supported drivers: "database-uuids", "dynamodb", "file", "null" + | + */ + + 'failed' => [ + 'driver' => env('QUEUE_FAILED_DRIVER', 'database-uuids'), + 'database' => env('DB_CONNECTION', 'sqlite'), + 'table' => 'failed_jobs', + ], + +]; diff --git a/config/sanctum.php b/config/sanctum.php new file mode 100644 index 0000000..44527d6 --- /dev/null +++ b/config/sanctum.php @@ -0,0 +1,84 @@ + explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf( + '%s%s', + 'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1', + Sanctum::currentApplicationUrlWithPort(), + // Sanctum::currentRequestHost(), + ))), + + /* + |-------------------------------------------------------------------------- + | Sanctum Guards + |-------------------------------------------------------------------------- + | + | This array contains the authentication guards that will be checked when + | Sanctum is trying to authenticate a request. If none of these guards + | are able to authenticate the request, Sanctum will use the bearer + | token that's present on an incoming request for authentication. + | + */ + + 'guard' => ['web'], + + /* + |-------------------------------------------------------------------------- + | Expiration Minutes + |-------------------------------------------------------------------------- + | + | This value controls the number of minutes until an issued token will be + | considered expired. This will override any values set in the token's + | "expires_at" attribute, but first-party sessions are not affected. + | + */ + + 'expiration' => null, + + /* + |-------------------------------------------------------------------------- + | Token Prefix + |-------------------------------------------------------------------------- + | + | Sanctum can prefix new tokens in order to take advantage of numerous + | security scanning initiatives maintained by open source platforms + | that notify developers if they commit tokens into repositories. + | + | See: https://docs.github.com/en/code-security/secret-scanning/about-secret-scanning + | + */ + + 'token_prefix' => env('SANCTUM_TOKEN_PREFIX', ''), + + /* + |-------------------------------------------------------------------------- + | Sanctum Middleware + |-------------------------------------------------------------------------- + | + | When authenticating your first-party SPA with Sanctum you may need to + | customize some of the middleware Sanctum uses while processing the + | request. You may change the middleware listed below as required. + | + */ + + 'middleware' => [ + 'authenticate_session' => Laravel\Sanctum\Http\Middleware\AuthenticateSession::class, + 'encrypt_cookies' => Illuminate\Cookie\Middleware\EncryptCookies::class, + 'validate_csrf_token' => Illuminate\Foundation\Http\Middleware\ValidateCsrfToken::class, + ], + +]; diff --git a/config/services.php b/config/services.php new file mode 100644 index 0000000..adaaab2 --- /dev/null +++ b/config/services.php @@ -0,0 +1,42 @@ + [ + 'token' => env('POSTMARK_TOKEN'), + ], + + 'resend' => [ + 'key' => env('RESEND_KEY'), + ], + + 'ses' => [ + 'key' => env('AWS_ACCESS_KEY_ID'), + 'secret' => env('AWS_SECRET_ACCESS_KEY'), + 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), + ], + + 'slack' => [ + 'notifications' => [ + 'bot_user_oauth_token' => env('SLACK_BOT_USER_OAUTH_TOKEN'), + 'channel' => env('SLACK_BOT_USER_DEFAULT_CHANNEL'), + ], + ], + + 'google' => [ + 'tts_api_key' => env('GOOGLE_TTS_API_KEY'), + ], + +]; diff --git a/config/session.php b/config/session.php new file mode 100644 index 0000000..f715097 --- /dev/null +++ b/config/session.php @@ -0,0 +1,217 @@ + env('SESSION_DRIVER', 'database'), + + /* + |-------------------------------------------------------------------------- + | Session Lifetime + |-------------------------------------------------------------------------- + | + | Here you may specify the number of minutes that you wish the session + | to be allowed to remain idle before it expires. If you want them + | to expire immediately when the browser is closed then you may + | indicate that via the expire_on_close configuration option. + | + */ + + 'lifetime' => (int) env('SESSION_LIFETIME', 120), + + 'expire_on_close' => env('SESSION_EXPIRE_ON_CLOSE', false), + + /* + |-------------------------------------------------------------------------- + | Session Encryption + |-------------------------------------------------------------------------- + | + | This option allows you to easily specify that all of your session data + | should be encrypted before it's stored. All encryption is performed + | automatically by Laravel and you may use the session like normal. + | + */ + + 'encrypt' => env('SESSION_ENCRYPT', false), + + /* + |-------------------------------------------------------------------------- + | Session File Location + |-------------------------------------------------------------------------- + | + | When utilizing the "file" session driver, the session files are placed + | on disk. The default storage location is defined here; however, you + | are free to provide another location where they should be stored. + | + */ + + 'files' => storage_path('framework/sessions'), + + /* + |-------------------------------------------------------------------------- + | Session Database Connection + |-------------------------------------------------------------------------- + | + | When using the "database" or "redis" session drivers, you may specify a + | connection that should be used to manage these sessions. This should + | correspond to a connection in your database configuration options. + | + */ + + 'connection' => env('SESSION_CONNECTION'), + + /* + |-------------------------------------------------------------------------- + | Session Database Table + |-------------------------------------------------------------------------- + | + | When using the "database" session driver, you may specify the table to + | be used to store sessions. Of course, a sensible default is defined + | for you; however, you're welcome to change this to another table. + | + */ + + 'table' => env('SESSION_TABLE', 'sessions'), + + /* + |-------------------------------------------------------------------------- + | Session Cache Store + |-------------------------------------------------------------------------- + | + | When using one of the framework's cache driven session backends, you may + | define the cache store which should be used to store the session data + | between requests. This must match one of your defined cache stores. + | + | Affects: "dynamodb", "memcached", "redis" + | + */ + + 'store' => env('SESSION_STORE'), + + /* + |-------------------------------------------------------------------------- + | Session Sweeping Lottery + |-------------------------------------------------------------------------- + | + | Some session drivers must manually sweep their storage location to get + | rid of old sessions from storage. Here are the chances that it will + | happen on a given request. By default, the odds are 2 out of 100. + | + */ + + 'lottery' => [2, 100], + + /* + |-------------------------------------------------------------------------- + | Session Cookie Name + |-------------------------------------------------------------------------- + | + | Here you may change the name of the session cookie that is created by + | the framework. Typically, you should not need to change this value + | since doing so does not grant a meaningful security improvement. + | + */ + + 'cookie' => env( + 'SESSION_COOKIE', + Str::slug(env('APP_NAME', 'laravel')).'-session' + ), + + /* + |-------------------------------------------------------------------------- + | Session Cookie Path + |-------------------------------------------------------------------------- + | + | The session cookie path determines the path for which the cookie will + | be regarded as available. Typically, this will be the root path of + | your application, but you're free to change this when necessary. + | + */ + + 'path' => env('SESSION_PATH', '/'), + + /* + |-------------------------------------------------------------------------- + | Session Cookie Domain + |-------------------------------------------------------------------------- + | + | This value determines the domain and subdomains the session cookie is + | available to. By default, the cookie will be available to the root + | domain and all subdomains. Typically, this shouldn't be changed. + | + */ + + 'domain' => env('SESSION_DOMAIN'), + + /* + |-------------------------------------------------------------------------- + | HTTPS Only Cookies + |-------------------------------------------------------------------------- + | + | By setting this option to true, session cookies will only be sent back + | to the server if the browser has a HTTPS connection. This will keep + | the cookie from being sent to you when it can't be done securely. + | + */ + + 'secure' => env('SESSION_SECURE_COOKIE'), + + /* + |-------------------------------------------------------------------------- + | HTTP Access Only + |-------------------------------------------------------------------------- + | + | Setting this value to true will prevent JavaScript from accessing the + | value of the cookie and the cookie will only be accessible through + | the HTTP protocol. It's unlikely you should disable this option. + | + */ + + 'http_only' => env('SESSION_HTTP_ONLY', true), + + /* + |-------------------------------------------------------------------------- + | Same-Site Cookies + |-------------------------------------------------------------------------- + | + | This option determines how your cookies behave when cross-site requests + | take place, and can be used to mitigate CSRF attacks. By default, we + | will set this value to "lax" to permit secure cross-site requests. + | + | See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#samesitesamesite-value + | + | Supported: "lax", "strict", "none", null + | + */ + + 'same_site' => env('SESSION_SAME_SITE', 'lax'), + + /* + |-------------------------------------------------------------------------- + | Partitioned Cookies + |-------------------------------------------------------------------------- + | + | Setting this value to true will tie the cookie to the top-level site for + | a cross-site context. Partitioned cookies are accepted by the browser + | when flagged "secure" and the Same-Site attribute is set to "none". + | + */ + + 'partitioned' => env('SESSION_PARTITIONED_COOKIE', false), + +]; diff --git a/database/.gitignore b/database/.gitignore new file mode 100644 index 0000000..9b19b93 --- /dev/null +++ b/database/.gitignore @@ -0,0 +1 @@ +*.sqlite* diff --git a/database/factories/UserFactory.php b/database/factories/UserFactory.php new file mode 100644 index 0000000..584104c --- /dev/null +++ b/database/factories/UserFactory.php @@ -0,0 +1,44 @@ + + */ +class UserFactory extends Factory +{ + /** + * The current password being used by the factory. + */ + protected static ?string $password; + + /** + * Define the model's default state. + * + * @return array + */ + public function definition(): array + { + return [ + 'name' => fake()->name(), + 'email' => fake()->unique()->safeEmail(), + 'email_verified_at' => now(), + 'password' => static::$password ??= Hash::make('password'), + 'remember_token' => Str::random(10), + ]; + } + + /** + * Indicate that the model's email address should be unverified. + */ + public function unverified(): static + { + return $this->state(fn (array $attributes) => [ + 'email_verified_at' => null, + ]); + } +} diff --git a/database/migrations/0001_01_01_000000_create_users_table.php b/database/migrations/0001_01_01_000000_create_users_table.php new file mode 100644 index 0000000..9d1b81f --- /dev/null +++ b/database/migrations/0001_01_01_000000_create_users_table.php @@ -0,0 +1,38 @@ +id(); + $table->string('name'); + $table->string('email')->unique(); + $table->timestamp('email_verified_at')->nullable(); + $table->string('password'); + $table->rememberToken(); + $table->timestamps(); + }); + + Schema::create('password_reset_tokens', function (Blueprint $table) { + $table->string('email')->primary(); + $table->string('token'); + $table->timestamp('created_at')->nullable(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('users'); + Schema::dropIfExists('password_reset_tokens'); + } +}; diff --git a/database/migrations/0001_01_01_000001_create_cache_table.php b/database/migrations/0001_01_01_000001_create_cache_table.php new file mode 100644 index 0000000..1d3e5b4 --- /dev/null +++ b/database/migrations/0001_01_01_000001_create_cache_table.php @@ -0,0 +1,34 @@ +string('key')->primary(); + $table->mediumText('value'); + $table->integer('expiration'); + }); + + Schema::create('cache_locks', function (Blueprint $table) { + $table->string('key')->primary(); + $table->string('owner'); + $table->integer('expiration'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('cache'); + Schema::dropIfExists('cache_locks'); + } +}; diff --git a/database/migrations/2024_01_01_000001_create_admins_table.php b/database/migrations/2024_01_01_000001_create_admins_table.php new file mode 100644 index 0000000..e129efa --- /dev/null +++ b/database/migrations/2024_01_01_000001_create_admins_table.php @@ -0,0 +1,28 @@ +id(); + $table->string('username')->unique(); + $table->string('password'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('admins'); + } +}; diff --git a/database/migrations/2024_01_01_000002_create_polis_table.php b/database/migrations/2024_01_01_000002_create_polis_table.php new file mode 100644 index 0000000..01266e4 --- /dev/null +++ b/database/migrations/2024_01_01_000002_create_polis_table.php @@ -0,0 +1,27 @@ +id(); + $table->string('nama_poli', 100); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('polis'); + } +}; diff --git a/database/migrations/2024_01_01_000003_create_lokets_table.php b/database/migrations/2024_01_01_000003_create_lokets_table.php new file mode 100644 index 0000000..29da2f8 --- /dev/null +++ b/database/migrations/2024_01_01_000003_create_lokets_table.php @@ -0,0 +1,27 @@ +id(); + $table->string('nama_loket', 100); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('lokets'); + } +}; diff --git a/database/migrations/2024_01_01_000004_recreate_users_table.php b/database/migrations/2024_01_01_000004_recreate_users_table.php new file mode 100644 index 0000000..d68ff3d --- /dev/null +++ b/database/migrations/2024_01_01_000004_recreate_users_table.php @@ -0,0 +1,51 @@ +id(); + $table->string('nama'); + $table->text('alamat'); + $table->enum('jenis_kelamin', ['laki-laki', 'perempuan']); + $table->string('no_hp', 20); + $table->string('no_ktp', 50)->unique(); + $table->foreignId('poli_id')->constrained('polis')->onDelete('cascade'); + $table->string('pekerjaan', 100); + $table->string('password'); + $table->rememberToken(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + // Drop the new users table + Schema::dropIfExists('users'); + + // Recreate the original users table + Schema::create('users', function (Blueprint $table) { + $table->id(); + $table->string('name'); + $table->string('email')->unique(); + $table->timestamp('email_verified_at')->nullable(); + $table->string('password'); + $table->rememberToken(); + $table->timestamps(); + }); + } +}; diff --git a/database/migrations/2024_01_01_000005_create_antrians_table.php b/database/migrations/2024_01_01_000005_create_antrians_table.php new file mode 100644 index 0000000..2ecbc99 --- /dev/null +++ b/database/migrations/2024_01_01_000005_create_antrians_table.php @@ -0,0 +1,33 @@ +id(); + $table->foreignId('user_id')->constrained('users')->onDelete('cascade'); + $table->string('no_antrian', 20); + $table->date('tanggal_antrian'); + $table->boolean('is_call')->default(false); + $table->enum('status', ['menunggu', 'dipanggil', 'selesai', 'batal'])->default('menunggu'); + $table->timestamp('waktu_panggil')->nullable(); + $table->foreignId('loket_id')->nullable()->constrained('lokets')->onDelete('set null'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('antrians'); + } +}; diff --git a/database/migrations/2024_01_01_000006_create_riwayat_panggilan_table.php b/database/migrations/2024_01_01_000006_create_riwayat_panggilan_table.php new file mode 100644 index 0000000..449ffc3 --- /dev/null +++ b/database/migrations/2024_01_01_000006_create_riwayat_panggilan_table.php @@ -0,0 +1,28 @@ +id(); + $table->foreignId('antrian_id')->constrained('antrians')->onDelete('cascade'); + $table->timestamp('waktu_panggilan')->useCurrent(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('riwayat_panggilan'); + } +}; diff --git a/database/migrations/2024_01_01_000007_add_remember_token_to_admins_table.php b/database/migrations/2024_01_01_000007_add_remember_token_to_admins_table.php new file mode 100644 index 0000000..9287a2a --- /dev/null +++ b/database/migrations/2024_01_01_000007_add_remember_token_to_admins_table.php @@ -0,0 +1,33 @@ +rememberToken()->nullable(); + } + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('admins', function (Blueprint $table) { + if (Schema::hasColumn('admins', 'remember_token')) { + $table->dropColumn('remember_token'); + } + }); + } +}; + + diff --git a/database/migrations/2024_01_01_000008_add_poli_id_to_antrians_table.php b/database/migrations/2024_01_01_000008_add_poli_id_to_antrians_table.php new file mode 100644 index 0000000..a867cee --- /dev/null +++ b/database/migrations/2024_01_01_000008_add_poli_id_to_antrians_table.php @@ -0,0 +1,37 @@ +foreignId('poli_id')->after('user_id')->nullable()->constrained('polis')->onDelete('cascade'); + }); + + // Update existing records to have poli_id based on user's poli + DB::statement('UPDATE antrians SET poli_id = (SELECT poli_id FROM users WHERE users.id = antrians.user_id)'); + + // Make poli_id not nullable after updating existing data + Schema::table('antrians', function (Blueprint $table) { + $table->foreignId('poli_id')->nullable(false)->change(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('antrians', function (Blueprint $table) { + $table->dropForeign(['poli_id']); + $table->dropColumn('poli_id'); + }); + } +}; diff --git a/database/migrations/2024_01_01_000009_remove_poli_id_from_users_table.php b/database/migrations/2024_01_01_000009_remove_poli_id_from_users_table.php new file mode 100644 index 0000000..7d2b8b8 --- /dev/null +++ b/database/migrations/2024_01_01_000009_remove_poli_id_from_users_table.php @@ -0,0 +1,28 @@ +dropForeign(['poli_id']); + $table->dropColumn('poli_id'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('users', function (Blueprint $table) { + $table->foreignId('poli_id')->constrained('polis')->onDelete('cascade'); + }); + } +}; diff --git a/database/migrations/2025_08_08_092603_create_personal_access_tokens_table.php b/database/migrations/2025_08_08_092603_create_personal_access_tokens_table.php new file mode 100644 index 0000000..4279a2e --- /dev/null +++ b/database/migrations/2025_08_08_092603_create_personal_access_tokens_table.php @@ -0,0 +1,32 @@ +id(); + $table->morphs('tokenable'); + $table->text('name'); + $table->string('token', 64)->unique(); + $table->text('abilities')->nullable(); + $table->timestamp('last_used_at')->nullable(); + $table->timestamp('expires_at')->nullable()->index(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('personal_access_tokens'); + } +}; diff --git a/database/migrations/2025_08_08_125912_create_sessions_table.php b/database/migrations/2025_08_08_125912_create_sessions_table.php new file mode 100644 index 0000000..f2251ee --- /dev/null +++ b/database/migrations/2025_08_08_125912_create_sessions_table.php @@ -0,0 +1,30 @@ +string('id')->primary(); + $table->foreignId('user_id')->nullable()->index(); + $table->string('ip_address', 45)->nullable(); + $table->text('user_agent')->nullable(); + $table->longText('payload'); + $table->integer('last_activity')->index(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('sessions'); + } +}; diff --git a/database/seeders/AdminSeeder.php b/database/seeders/AdminSeeder.php new file mode 100644 index 0000000..98b1209 --- /dev/null +++ b/database/seeders/AdminSeeder.php @@ -0,0 +1,29 @@ + 'admin'], + ['password' => Hash::make('admin123')] + ); + + // Optional additional admin (email style username) + Admin::updateOrCreate( + ['username' => 'admin@puskesmas.com'], + ['password' => Hash::make('admin123')] + ); + } +} diff --git a/database/seeders/AntrianPuskesmasSeeder.php b/database/seeders/AntrianPuskesmasSeeder.php new file mode 100644 index 0000000..42407ab --- /dev/null +++ b/database/seeders/AntrianPuskesmasSeeder.php @@ -0,0 +1,122 @@ + 1, 'nama_poli' => 'umum'], + ['id' => 2, 'nama_poli' => 'gigi'], + ['id' => 3, 'nama_poli' => 'kesehatan jiwa'], + ['id' => 4, 'nama_poli' => 'kesehatan tradisional'], + ]; + foreach ($polis as $poli) { + DB::table('polis')->updateOrInsert( + ['id' => $poli['id']], + ['nama_poli' => $poli['nama_poli'], 'updated_at' => now()] + ); + } + + // Seed lokets table with upsert + $lokets = [ + ['id' => 1, 'nama_loket' => 'Loket 1'], + ['id' => 2, 'nama_loket' => 'Loket 2'], + ]; + foreach ($lokets as $loket) { + DB::table('lokets')->updateOrInsert( + ['id' => $loket['id']], + ['nama_loket' => $loket['nama_loket'], 'updated_at' => now()] + ); + } + + // Seed users table with upsert + DB::table('users')->updateOrInsert( + ['id' => 1], + [ + 'nama' => 'Budi Santoso', + 'alamat' => 'Jl. Merdeka No.1', + 'jenis_kelamin' => 'laki-laki', + 'no_hp' => '08123456789', + 'no_ktp' => '1234567890123456', + 'pekerjaan' => 'Petani', + 'password' => Hash::make('password'), + 'updated_at' => now(), + ] + ); + + // Seed antrians table with upsert + DB::table('antrians')->updateOrInsert( + ['id' => 1], + [ + 'user_id' => 1, + 'poli_id' => 1, + 'no_antrian' => 'U1', + 'tanggal_antrian' => now()->toDateString(), + 'is_call' => 0, + 'status' => 'menunggu', + 'waktu_panggil' => null, + 'loket_id' => 1, + 'updated_at' => now(), + ] + ); + + // Add more antrian data for testing + DB::table('antrians')->updateOrInsert( + ['id' => 2], + [ + 'user_id' => 1, + 'poli_id' => 2, + 'no_antrian' => 'G1', + 'tanggal_antrian' => now()->toDateString(), + 'is_call' => 0, + 'status' => 'menunggu', + 'waktu_panggil' => null, + 'loket_id' => 1, + 'updated_at' => now(), + ] + ); + + DB::table('antrians')->updateOrInsert( + ['id' => 3], + [ + 'user_id' => 1, + 'poli_id' => 3, + 'no_antrian' => 'J1', + 'tanggal_antrian' => now()->toDateString(), + 'is_call' => 0, + 'status' => 'dipanggil', + 'waktu_panggil' => now(), + 'loket_id' => 1, + 'updated_at' => now(), + ] + ); + + DB::table('antrians')->updateOrInsert( + ['id' => 4], + [ + 'user_id' => 1, + 'poli_id' => 4, + 'no_antrian' => 'T1', + 'tanggal_antrian' => now()->toDateString(), + 'is_call' => 0, + 'status' => 'menunggu', + 'waktu_panggil' => null, + 'loket_id' => 1, + 'updated_at' => now(), + ] + ); + } +} diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php new file mode 100644 index 0000000..b7f39e5 --- /dev/null +++ b/database/seeders/DatabaseSeeder.php @@ -0,0 +1,21 @@ +call([ + AntrianPuskesmasSeeder::class, + AdminSeeder::class, + ]); + } +} diff --git a/database/seeders/LoketSeeder.php b/database/seeders/LoketSeeder.php new file mode 100644 index 0000000..defc0fc --- /dev/null +++ b/database/seeders/LoketSeeder.php @@ -0,0 +1,22 @@ + 'Loket 1'], + ['nama_loket' => 'Loket 2'], + ['nama_loket' => 'Loket 3'], + ]; + + foreach ($lokets as $loket) { + Loket::create($loket); + } + } +} diff --git a/database/seeders/PoliSeeder.php b/database/seeders/PoliSeeder.php new file mode 100644 index 0000000..cd9c00a --- /dev/null +++ b/database/seeders/PoliSeeder.php @@ -0,0 +1,23 @@ + 'Poli Umum'], + ['nama_poli' => 'Poli Gigi'], + ['nama_poli' => 'Poli Jiwa'], + ['nama_poli' => 'Poli Tradisional'], + ]; + + foreach ($polis as $poli) { + Poli::create($poli); + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..a5707d8 --- /dev/null +++ b/package.json @@ -0,0 +1,17 @@ +{ + "$schema": "https://json.schemastore.org/package.json", + "private": true, + "type": "module", + "scripts": { + "build": "vite build", + "dev": "vite" + }, + "devDependencies": { + "@tailwindcss/vite": "^4.0.0", + "axios": "^1.11.0", + "concurrently": "^9.0.1", + "laravel-vite-plugin": "^2.0.0", + "tailwindcss": "^4.0.0", + "vite": "^7.0.4" + } +} diff --git a/phpunit.xml b/phpunit.xml new file mode 100644 index 0000000..5fd5bcf --- /dev/null +++ b/phpunit.xml @@ -0,0 +1,34 @@ + + + + + tests/Unit + + + tests/Feature + + + + + app + + + + + + + + + + + + + + + + + diff --git a/public/.htaccess b/public/.htaccess new file mode 100644 index 0000000..b574a59 --- /dev/null +++ b/public/.htaccess @@ -0,0 +1,25 @@ + + + Options -MultiViews -Indexes + + + RewriteEngine On + + # Handle Authorization Header + RewriteCond %{HTTP:Authorization} . + RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] + + # Handle X-XSRF-Token Header + RewriteCond %{HTTP:x-xsrf-token} . + RewriteRule .* - [E=HTTP_X_XSRF_TOKEN:%{HTTP:X-XSRF-Token}] + + # Redirect Trailing Slashes If Not A Folder... + RewriteCond %{REQUEST_FILENAME} !-d + RewriteCond %{REQUEST_URI} (.+)/$ + RewriteRule ^ %1 [L,R=301] + + # Send Requests To Front Controller... + RewriteCond %{REQUEST_FILENAME} !-d + RewriteCond %{REQUEST_FILENAME} !-f + RewriteRule ^ index.php [L] + diff --git a/public/assets/music/call-to-attention-123107.mp3 b/public/assets/music/call-to-attention-123107.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..c625d3e27edd44f3e9588da44f056c4c57267cf3 GIT binary patch literal 137926 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 literal 0 HcmV?d00001 diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000..e69de29 diff --git a/public/index.php b/public/index.php new file mode 100644 index 0000000..ee8f07e --- /dev/null +++ b/public/index.php @@ -0,0 +1,20 @@ +handleRequest(Request::capture()); diff --git a/public/robots.txt b/public/robots.txt new file mode 100644 index 0000000..eb05362 --- /dev/null +++ b/public/robots.txt @@ -0,0 +1,2 @@ +User-agent: * +Disallow: diff --git a/puskesmas b/puskesmas new file mode 100644 index 0000000000000000000000000000000000000000..316238e15b2e025239d754972a15e545869d987f GIT binary patch literal 118784 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

    (_*CG~aAB%ruy#nY08E9PG3ow1C0XTG1hV@ce6 ze3fh69L<^=8~Vv5i6UNoxWf5EH>9&7-XF@CSFh@yL`D(K6#=KPDjoxpx5EkPPh~EN+4maN zq-dvS&C8edlNs4&)hk6|DCk}dC0eq(8L_#=0ZSFX?;~HQdMa1Bxaf`bj(GmhWglwB z&!+!ndVA{cC;xk5Y5bRCpHdQDAOHd&00JNY0NiKu`W_tp=DMHazC{+eJNO<*?ZuQ+Knpvr6l~cX7>1Y@8}RCHGF- z886vBeR2DeT#Wzhu|ySDh=0G81QRE}7LU`*^p2dg45vNncH5~-C;D<_sYE*`oibuw zs@A8C^8%~TN;mZUV_LH<<-1$p9gK@Bv`uaYAq$(`#{w(fUysw}#(I2$BlgvcUfXcQ zO+dTP0h9afw4P%Xb+5hKky71G=(($98j0LcR?UOb(ih*avU?umO + + + + + + Nomor Antrian - {{ $antrian->no_antrian }} + + + + +

    +
    +
    šŸ„ PUSKESMAS
    +
    Sistem Antrian Digital
    +
    + +
    +
    {{ $antrian->no_antrian }}
    +
    NOMOR ANTRIAN
    +
    + +
    +
    + Nama: + {{ $antrian->user->nama }} +
    +
    + Poli: + {{ $antrian->poli->nama_poli }} +
    +
    + Status: + {{ ucfirst($antrian->status) }} +
    +
    + Tanggal: + {{ $antrian->created_at->format('d/m/Y') }} +
    +
    + Waktu: + {{ $antrian->created_at->format('H:i') }} +
    +
    + + + +
    + Dicetak pada: {{ now()->format('d/m/Y H:i:s') }} +
    +
    + + + + + diff --git a/resources/views/admin/dashboard.blade.php b/resources/views/admin/dashboard.blade.php new file mode 100644 index 0000000..08d0560 --- /dev/null +++ b/resources/views/admin/dashboard.blade.php @@ -0,0 +1,411 @@ +@extends('layouts.app') + +@section('title', 'Admin Dashboard - Sistem Antrian Puskesmas') + +@section('content') +
    + + + +
    + + + + + + + +
    +
    + +
    +

    Admin Dashboard

    +

    Kelola sistem antrian Puskesmas

    +
    + + +
    +
    +
    +
    + + + +
    +
    +

    Poli Umum

    +

    {{ $poliUmumCount ?? 0 }}

    +

    Antrian menunggu

    +
    +
    +
    + +
    +
    +
    + + + +
    +
    +

    Poli Gigi

    +

    {{ $poliGigiCount ?? 0 }}

    +

    Antrian menunggu

    +
    +
    +
    + +
    +
    +
    + + + +
    +
    +

    Poli Jiwa

    +

    {{ $poliJiwaCount ?? 0 }}

    +

    Antrian menunggu

    +
    +
    +
    + +
    +
    +
    + + + +
    +
    +

    Poli Tradisional

    +

    {{ $poliTradisionalCount ?? 0 }}

    +

    Antrian menunggu

    +
    +
    +
    +
    + + +
    +
    +

    Antrian Terbaru

    +
    +
    + + + + + + + + + + + + @forelse($antrianTerbaru ?? [] as $antrian) + + + + + + + + @empty + + + + @endforelse + +
    + No. Antrian + Nama + Poli + Status + Waktu
    + {{ $antrian->no_antrian ?? 'N/A' }} + +
    + {{ $antrian->user?->nama ?? 'N/A' }} +
    +
    {{ $antrian->user?->no_hp ?? 'N/A' }} +
    +
    + + {{ $antrian->poli->nama_poli ?? 'N/A' }} + + + @if (($antrian->status ?? '') == 'menunggu') + + Menunggu + + @elseif(($antrian->status ?? '') == 'dipanggil') + + Dipanggil + + @elseif(($antrian->status ?? '') == 'selesai') + + Selesai + + @else + + Batal + + @endif + + {{ $antrian->created_at?->format('H:i') ?? 'N/A' }} +
    + + + + +

    Belum ada antrian hari ini

    +

    Antrian akan muncul di sini setelah ada + pendaftaran

    +
    +
    +
    +
    +
    +
    +
    + + @push('scripts') + + @endpush +@endsection diff --git a/resources/views/admin/laporan/index.blade.php b/resources/views/admin/laporan/index.blade.php new file mode 100644 index 0000000..d4cebde --- /dev/null +++ b/resources/views/admin/laporan/index.blade.php @@ -0,0 +1,497 @@ +@extends('layouts.app') + +@section('title', 'Laporan Antrian - Admin Dashboard') + +@section('content') +
    + + + +
    + + + + + + + +
    +
    + +
    +

    Laporan Antrian

    +

    Kelola dan ekspor data antrian

    +
    + + + + + +
    +

    Filter Laporan

    +
    + +
    + + +
    + + +
    + + +
    + + +
    + + +
    + + +
    + + +
    + + +
    + + +
    + + +
    + + + Reset + +
    +
    +
    + + +
    +
    +
    +
    +
    + + + + +
    +
    +
    +

    Total Antrian

    +

    {{ $totalAntrian }}

    +
    +
    +
    + +
    +
    +
    +
    + + + +
    +
    +
    +

    Menunggu

    +

    {{ $antrianMenunggu }}

    +
    +
    +
    + +
    +
    +
    +
    + + + +
    +
    +
    +

    Selesai

    +

    {{ $antrianSelesai }}

    +
    +
    +
    + +
    +
    +
    +
    + + + +
    +
    +
    +

    Sedang

    +

    {{ $antrianSedang }}

    +
    +
    +
    +
    + + +
    +
    +

    Data Antrian

    +
    +
    + + + + + + + + + + + + + + @forelse($antrian as $item) + + + + + + + + + + @empty + + + + @endforelse + +
    + No Antrian + Nama Pasien + Poli + Status + Tanggal + Waktu Daftar + Waktu Panggil
    + + {{ $item->no_antrian }} + + +
    +
    {{ $item->user->nama }}
    +
    {{ $item->user->no_ktp }}
    +
    +
    + + {{ $item->poli->nama_poli }} + + + @if ($item->status == 'menunggu') + + Menunggu + + @elseif($item->status == 'sedang') + + Sedang + + @elseif($item->status == 'selesai') + + Selesai + + @else + + Batal + + @endif + + {{ $item->created_at ? $item->created_at->format('d/m/Y') : '-' }} + + {{ $item->created_at ? $item->created_at->format('H:i') : '-' }} + + {{ $item->waktu_panggil ? $item->waktu_panggil->format('H:i') : '-' }} +
    + Tidak ada data antrian yang ditemukan +
    +
    +
    +
    +
    +
    +
    + + @push('scripts') + + @endpush +@endsection diff --git a/resources/views/admin/laporan/pdf.blade.php b/resources/views/admin/laporan/pdf.blade.php new file mode 100644 index 0000000..21815e6 --- /dev/null +++ b/resources/views/admin/laporan/pdf.blade.php @@ -0,0 +1,143 @@ + + + + + + Laporan Antrian Puskesmas + + + + +
    +

    LAPORAN ANTRIAN PUSKESMAS

    +

    Tanggal Cetak: {{ date('d/m/Y H:i') }}

    +

    Total Data: {{ $antrian->count() }} antrian

    +
    + + + + + + + + + + + + + + + + + @forelse($antrian as $index => $item) + + + + + + + + + + + + @empty + + + + @endforelse + +
    NoNo AntrianNama PasienNo KTPPoliStatusTanggalWaktu DaftarWaktu Panggil
    {{ $index + 1 }}{{ $item->no_antrian }}{{ $item->user->nama }}{{ $item->user->no_ktp }}{{ $item->poli->nama_poli }} + {{ ucfirst($item->status) }} + {{ $item->created_at ? $item->created_at->format('d/m/Y') : '-' }}{{ $item->created_at ? $item->created_at->format('H:i') : '-' }}{{ $item->waktu_panggil ? $item->waktu_panggil->format('H:i') : '-' }}
    Tidak ada data antrian
    + +
    +

    Ringkasan Statistik:

    +

    Total Antrian: {{ $antrian->count() }}

    +

    Menunggu: {{ $antrian->where('status', 'menunggu')->count() }}

    +

    Sedang: {{ $antrian->where('status', 'sedang')->count() }}

    +

    Selesai: {{ $antrian->where('status', 'selesai')->count() }}

    +

    Batal: {{ $antrian->where('status', 'batal')->count() }}

    +
    + + + diff --git a/resources/views/admin/poli/index.blade.php b/resources/views/admin/poli/index.blade.php new file mode 100644 index 0000000..854dd01 --- /dev/null +++ b/resources/views/admin/poli/index.blade.php @@ -0,0 +1,486 @@ +@extends('layouts.app') + +@section('title', $title) + +@section('content') +
    + + + +
    + + + + + + + +
    +
    + +
    +

    {{ $title }}

    +

    Kelola antrian untuk {{ $title }}

    +
    + + +
    +
    + + + + + + + + + + + + + + + @forelse($antrians as $antrian) + + + + + + + + + + + @empty + + + + @endforelse + +
    + No Antrian + Nama + Alamat + Jenis Kelamin + Nomor HP + Nomor KTP + Status + Aksi
    + {{ $antrian->no_antrian }} + {{ $antrian->user?->nama }}{{ $antrian->user?->alamat }} + {{ $antrian->user?->jenis_kelamin }} + {{ $antrian->user?->no_hp }} + {{ $antrian->user?->no_ktp }} + @if ($antrian->status == 'menunggu') + + Menunggu + + @elseif($antrian->status == 'dipanggil') + + Dipanggil + + @elseif($antrian->status == 'selesai') + + Selesai + + @else + + Batal + + @endif + + @if ($antrian->status == 'menunggu') + + @elseif($antrian->status == 'dipanggil') +
    + + +
    + @else + - + @endif +
    + + + + +

    Belum ada antrian

    +

    Antrian akan muncul di sini setelah ada + pendaftaran

    +
    +
    +
    +
    +
    +
    +
    + + @push('scripts') + + @endpush +@endsection diff --git a/resources/views/admin/users/index.blade.php b/resources/views/admin/users/index.blade.php new file mode 100644 index 0000000..b2b7685 --- /dev/null +++ b/resources/views/admin/users/index.blade.php @@ -0,0 +1,534 @@ +@extends('layouts.app') + +@section('title', 'Kelola User - Admin Dashboard') + +@section('content') +
    + + + +
    + + + + + + + +
    +
    + +
    +

    Kelola Data User

    +

    Kelola data pengguna sistem antrian Puskesmas

    +
    + + +
    +
    +
    + +
    + +
    + + + +
    +
    +
    +
    + + + Reset + +
    +
    +
    + + +
    +
    +

    Daftar User

    +
    +
    + + + + + + + + + + + + + @forelse($users as $user) + + + + + + + + + @empty + + + + @endforelse + +
    + Nama & Alamat + No. KTP + No. HP + Jenis Kelamin + Pekerjaan + Aksi
    +
    {{ $user->nama }}
    +
    + {{ Str::limit($user->alamat, 50) }} + @if (strlen($user->alamat) > 50) + ... + @endif +
    +
    + {{ $user->no_ktp }} + + {{ $user->no_hp }} + + + {{ $user->jenis_kelamin == 'laki-laki' ? 'Laki-laki' : 'Perempuan' }} + + + {{ $user->pekerjaan }} + + + +
    + + + + +

    Belum ada user

    +

    Tidak ada data user yang tersedia

    +
    +
    +
    +
    +
    + + + + + + + + @push('scripts') + + @endpush + @endsection diff --git a/resources/views/admin/users/show.blade.php b/resources/views/admin/users/show.blade.php new file mode 100644 index 0000000..23eb85b --- /dev/null +++ b/resources/views/admin/users/show.blade.php @@ -0,0 +1,255 @@ +
    + +
    +

    Informasi User

    +
    +
    + +
    + {{ $user->nama }} +
    +
    + +
    + +
    + {{ $user->no_ktp }} +
    +
    + +
    + +
    + {{ $user->no_hp }} +
    +
    + +
    + +
    + {{ $user->jenis_kelamin == 'laki-laki' ? 'Laki-laki' : 'Perempuan' }} +
    +
    + +
    + +
    + {{ $user->pekerjaan }} +
    +
    + +
    + +
    + {{ $user->created_at ? $user->created_at->format('d/m/Y H:i') : 'N/A' }} +
    +
    +
    + +
    + +
    + {{ $user->alamat }} +
    +
    +
    + + +
    +

    Edit Data User

    +
    + @csrf + @method('PUT') + +
    +
    + + +
    + +
    + + +
    + +
    + + +
    + +
    + + +
    + +
    + + +
    + +
    + + +
    +
    + +
    + + +
    +
    +
    + + +
    +

    Statistik Antrian User

    +
    +
    +
    + {{ $user->antrians->where('status', 'menunggu')->count() }}
    +
    Antrian Menunggu
    +
    +
    +
    + {{ $user->antrians->where('status', 'selesai')->count() }}
    +
    Antrian Selesai
    +
    +
    +
    {{ $user->antrians->where('status', 'batal')->count() }} +
    +
    Antrian Batal
    +
    +
    +
    {{ $user->antrians->count() }}
    +
    Total Antrian
    +
    +
    +
    + + + @if ($user->antrians->count() > 0) +
    +

    Riwayat Antrian Terbaru

    +
    + + + + + + + + + + + @foreach ($user->antrians->take(5) as $antrian) + + + + + + + @endforeach + +
    + No. Antrian + Poli + Status + Tanggal
    + {{ $antrian->no_antrian }} + + + {{ $antrian->poli->nama_poli ?? 'N/A' }} + + + @if ($antrian->status == 'menunggu') + + Menunggu + + @elseif($antrian->status == 'dipanggil') + + Dipanggil + + @elseif($antrian->status == 'selesai') + + Selesai + + @else + + Batal + + @endif + + {{ $antrian->created_at ? $antrian->created_at->format('d/m/Y H:i') : 'N/A' }} +
    +
    +
    + @endif +
    + + diff --git a/resources/views/auth/forgot-password.blade.php b/resources/views/auth/forgot-password.blade.php new file mode 100644 index 0000000..01b2f19 --- /dev/null +++ b/resources/views/auth/forgot-password.blade.php @@ -0,0 +1,180 @@ +@extends('layouts.app') + +@section('title', 'Lupa Password - Sistem Antrian Puskesmas') + +@section('content') +
    +
    + +
    +
    + šŸ” +
    +

    Lupa Password

    +

    Verifikasi data diri untuk reset password

    +
    + + +
    +
    + @csrf + + +
    + +
    +
    + + + +
    + +
    +
    + + +
    + +
    +
    + + + +
    + +
    +
    + + +
    + +
    + + +
    +

    + Ingat password? + + Login di sini + +

    +
    +
    +
    + + + +
    +
    + + @push('scripts') + + @endpush +@endsection diff --git a/resources/views/auth/login.blade.php b/resources/views/auth/login.blade.php new file mode 100644 index 0000000..c5cec9b --- /dev/null +++ b/resources/views/auth/login.blade.php @@ -0,0 +1,227 @@ +@extends('layouts.app') + +@section('title', 'Login - Sistem Antrian Puskesmas') + +@section('content') +
    +
    + +
    +
    + šŸ„ +
    +

    Login

    +

    Masuk ke sistem antrian Puskesmas

    +
    + + +
    +
    + @csrf + + +
    + +
    +
    + + + +
    + +
    +
    + + +
    + +
    +
    + + + + +
    + +
    +
    + + +
    + + +
    + + +
    + +
    + + +
    +

    + Belum punya akun? + + Daftar di sini + +

    +
    + + +
    +

    + Lupa password? + + Reset password di sini + +

    +
    +
    +
    + + + +
    +
    + + @push('scripts') + + @endpush +@endsection diff --git a/resources/views/auth/register.blade.php b/resources/views/auth/register.blade.php new file mode 100644 index 0000000..104dfb1 --- /dev/null +++ b/resources/views/auth/register.blade.php @@ -0,0 +1,350 @@ +@extends('layouts.app') + +@section('title', 'Daftar - Sistem Antrian Puskesmas') + +@section('content') +
    +
    + +
    +
    + šŸ„ +
    +

    Daftar

    +

    Buat akun untuk mengakses sistem antrian

    +
    + + +
    +
    + @csrf + + +
    + +
    +
    + + + +
    + +
    +
    + + +
    + + +
    + + +
    + +
    +
    + + + +
    + +
    + + + +
    +
    +
    + + +
    + +
    +
    + + + + +
    + +
    +
    + + +
    + +
    +
    + + + + +
    + +
    +

    NIK harus tepat 16 digit angka

    +
    + + +
    + +
    +
    + + + + +
    + +
    +
    + + +
    + +
    +
    + + + + +
    + +
    +
    + + +
    + +
    +
    + + + + +
    + +
    +
    + + +
    + +
    + + +
    +

    + Sudah punya akun? + + Login di sini + +

    +
    +
    +
    + + + +
    +
    + + @push('scripts') + + @endpush +@endsection diff --git a/resources/views/auth/reset-password.blade.php b/resources/views/auth/reset-password.blade.php new file mode 100644 index 0000000..ca724dd --- /dev/null +++ b/resources/views/auth/reset-password.blade.php @@ -0,0 +1,207 @@ +@extends('layouts.app') + +@section('title', 'Reset Password - Sistem Antrian Puskesmas') + +@section('content') +
    +
    + +
    +
    + šŸ”‘ +
    +

    Reset Password

    +

    Masukkan password baru Anda

    +
    + + +
    +
    + @csrf + + + +
    + +
    +
    + + + + +
    + +
    +
    + + +
    + +
    +
    + + + + +
    + +
    +
    + + +
    + +
    + + +
    +

    + Ingat password lama? + + Login di sini + +

    +
    +
    +
    + + + +
    +
    + + @push('scripts') + + @endpush +@endsection diff --git a/resources/views/dashboard/index.blade.php b/resources/views/dashboard/index.blade.php new file mode 100644 index 0000000..e7d4df5 --- /dev/null +++ b/resources/views/dashboard/index.blade.php @@ -0,0 +1,560 @@ +@extends('layouts.app') + +@section('title', 'Dashboard - Sistem Antrian Puskesmas') + +@section('content') +
    + + + +
    + +
    +

    Dashboard

    +

    Kelola sistem antrian Puskesmas

    +
    + + +
    +
    +
    +

    Data Diri

    +

    Informasi pribadi Anda

    +
    +
    +
    + + + +
    + +
    +
    + +
    +
    + +
    + {{ auth()->user()->nama ?? 'N/A' }} +
    +
    + +
    + +
    + {{ auth()->user()->no_hp ?? 'N/A' }} +
    +
    + +
    + +
    + {{ auth()->user()->no_ktp ?? 'N/A' }} +
    +
    + +
    + +
    + {{ auth()->user()->jenis_kelamin == 'laki-laki' ? 'Laki-laki' : 'Perempuan' }} +
    +
    + +
    + +
    + {{ auth()->user()->alamat ?? 'N/A' }} +
    +
    + +
    + +
    + {{ auth()->user()->pekerjaan ?? 'N/A' }} +
    +
    +
    +
    + + +
    +
    +
    +

    Ambil Antrian

    +

    Pilih poli untuk mengambil antrian baru

    +
    +
    + + + +
    +
    + +
    + @csrf +
    +
    + + +
    +
    + +
    + +
    +
    +
    + + +
    +
    +

    Antrian Saya

    +
    +
    + + + + + + + + + + + + + @forelse($antrianSaya ?? [] as $antrian) + + + + + + + + + @empty + + + + @endforelse + +
    + No. Antrian + Nama + Poli + Status + Waktu + Aksi
    + {{ $antrian->no_antrian ?? 'N/A' }} + +
    {{ $antrian->user->nama ?? 'N/A' }} +
    +
    {{ $antrian->user->no_hp ?? 'N/A' }}
    +
    + + {{ $antrian->poli->nama_poli ?? 'N/A' }} + + + @if (($antrian->status ?? '') == 'menunggu') + + Menunggu + + @elseif(($antrian->status ?? '') == 'dipanggil') + + Dipanggil + + @elseif(($antrian->status ?? '') == 'selesai') + + Selesai + + @else + + Batal + + @endif + + {{ $antrian->created_at ? $antrian->created_at->format('H:i') : 'N/A' }} + +
    + @if($antrian->status == 'menunggu') + + @endif + @if($antrian->status == 'menunggu') + + + + + Cetak + + @else + + + + + Cetak + + @endif +
    +
    + + + + +

    Belum ada antrian

    +

    Silakan ambil antrian baru di atas

    +
    +
    +
    +
    +
    + + + + + @push('scripts') + + @endpush +@endsection diff --git a/resources/views/display/index.blade.php b/resources/views/display/index.blade.php new file mode 100644 index 0000000..a6161ad --- /dev/null +++ b/resources/views/display/index.blade.php @@ -0,0 +1,435 @@ +@extends('layouts.app') + +@section('title', 'Display Antrian - Puskesmas') + +@section('content') +
    +
    + +
    +

    šŸ„ PUSKESMAS

    +

    Sistem Antrian Digital

    +
    +
    + + +
    + +
    +
    +

    Poli Umum

    +
    +
    + +
    +
    + {{ $poliUmumCurrent?->no_antrian ?? '---' }} +
    +

    Sedang Dipanggil

    +
    + +
    +

    Antrian Berikutnya:

    +
    + @forelse($poliUmumNext ?? [] as $antrian) +
    + {{ $antrian->no_antrian }} +
    + @empty +
    + + + + +

    Tidak ada antrian

    +
    + @endforelse +
    +
    +
    + + +
    +
    +

    Poli Gigi

    +
    +
    + +
    +
    + {{ $poliGigiCurrent?->no_antrian ?? '---' }} +
    +

    Sedang Dipanggil

    +
    + +
    +

    Antrian Berikutnya:

    +
    + @forelse($poliGigiNext ?? [] as $antrian) +
    + {{ $antrian->no_antrian }} +
    + @empty +
    + + + + +

    Tidak ada antrian

    +
    + @endforelse +
    +
    +
    + + +
    +
    +

    Poli Jiwa

    +
    +
    + +
    +
    + {{ $poliJiwaCurrent?->no_antrian ?? '---' }} +
    +

    Sedang Dipanggil

    +
    + +
    +

    Antrian Berikutnya:

    +
    + @forelse($poliJiwaNext ?? [] as $antrian) +
    + {{ $antrian->no_antrian }} +
    + @empty +
    + + + + +

    Tidak ada antrian

    +
    + @endforelse +
    +
    +
    + + +
    +
    +

    Poli Tradisional

    +
    +
    + +
    +
    + {{ $poliTradisionalCurrent?->no_antrian ?? '---' }} +
    +

    Sedang Dipanggil

    +
    + +
    +

    Antrian Berikutnya:

    +
    + @forelse($poliTradisionalNext ?? [] as $antrian) +
    + {{ $antrian->no_antrian }} +
    + @empty +
    + + + +

    Tidak ada antrian

    +
    + @endforelse +
    +
    +
    +
    + + +
    +
    +

    + + + + {{ now()->format('d F Y H:i:s') }} +

    +
    +
    +
    +
    + + @push('scripts') + + @endpush +@endsection diff --git a/resources/views/landing.blade.php b/resources/views/landing.blade.php new file mode 100644 index 0000000..3ae9fe7 --- /dev/null +++ b/resources/views/landing.blade.php @@ -0,0 +1,336 @@ +@extends('layouts.app') + +@section('title', 'Sistem Antrian Puskesmas - Beranda') + +@section('content') + @if (session('success')) +
    + {{ session('success') }} +
    + @endif + + + + + +
    +
    +
    +

    + Sistem Antrian Puskesmas +

    +

    + Antrian digital yang memudahkan pelayanan kesehatan masyarakat +

    + +
    +
    +
    + + +
    +
    +
    +

    Layanan Kami

    +

    Berbagai layanan kesehatan yang tersedia

    +
    + +
    +
    +
    šŸ‘Øā€āš•ļø
    +

    Poli Umum

    +

    Layanan pemeriksaan kesehatan umum untuk semua usia

    +
    + +
    +
    šŸ‘¶
    +

    Poli Anak

    +

    Layanan kesehatan khusus untuk anak-anak

    +
    + +
    +
    🤰
    +

    Poli Ibu Hamil

    +

    Layanan kesehatan untuk ibu hamil dan keluarga berencana +

    +
    +
    +
    +
    + + +
    +
    +
    +

    Cara Kerja

    +

    Langkah-langkah menggunakan sistem antrian + digital

    +
    + +
    +
    +
    + 1
    +

    Daftar Online

    +

    Isi formulir pendaftaran dengan data lengkap

    +
    + +
    +
    + 2
    +

    Dapatkan Nomor

    +

    Sistem akan memberikan nomor antrian

    +
    + +
    +
    + 3
    +

    Tunggu Panggilan

    +

    Monitor layar atau tunggu panggilan

    +
    + +
    +
    + 4
    +

    Layanan

    +

    Dapatkan pelayanan kesehatan

    +
    +
    +
    +
    + + +
    +
    +
    +
    +

    Tentang Kami

    +

    + Puskesmas kami berkomitmen untuk memberikan pelayanan kesehatan yang berkualitas + kepada masyarakat dengan sistem antrian digital yang modern dan efisien. +

    +

    + Dengan teknologi terkini, kami memastikan proses antrian berjalan lancar + dan mengurangi waktu tunggu pasien. +

    +
    +
    +
    + Pelayanan 24/7 +
    +
    +
    + Sistem Antrian Digital +
    +
    +
    + Tim Medis Profesional +
    +
    +
    +
    +
    +
    šŸ„
    +

    Puskesmas Modern

    +

    Melayani dengan teknologi terkini

    +
    +
    +
    +
    +
    + + +
    +
    +
    +
    +

    šŸ„ Puskesmas

    +

    Sistem antrian digital untuk pelayanan kesehatan yang + lebih baik.

    +
    +
    +

    Layanan

    +
      +
    • Poli Umum
    • +
    • Poli Anak
    • +
    • Poli Ibu Hamil
    • +
    +
    +
    +

    Kontak

    +
      +
    • šŸ“ž (021) 1234-5678
    • +
    • šŸ“§ info@puskesmas.com
    • +
    • šŸ“ Jl. Kesehatan No. 123
    • +
    +
    +
    +

    Jam Operasional

    +
      +
    • Senin - Jumat: 08:00 - 16:00
    • +
    • Sabtu: 08:00 - 12:00
    • +
    • Minggu: Tutup
    • +
    +
    +
    +
    +

    © 2024 Sistem Antrian Puskesmas. All rights reserved.

    +
    +
    +
    + + @push('scripts') + + @endpush +@endsection diff --git a/resources/views/layouts/app.blade.php b/resources/views/layouts/app.blade.php new file mode 100644 index 0000000..ab35098 --- /dev/null +++ b/resources/views/layouts/app.blade.php @@ -0,0 +1,125 @@ + + + + + + + + @yield('title', 'Sistem Antrian Puskesmas') + + + + + + + + + + + + @stack('styles') + + + + @yield('content') + + @stack('scripts') + + + diff --git a/resources/views/user/antrian/print.blade.php b/resources/views/user/antrian/print.blade.php new file mode 100644 index 0000000..57ea901 --- /dev/null +++ b/resources/views/user/antrian/print.blade.php @@ -0,0 +1,167 @@ + + + + + + + Nomor Antrian - {{ $antrian->no_antrian }} + + + + +
    +
    +
    šŸ„ PUSKESMAS
    +
    Sistem Antrian Digital
    +
    + +
    +
    {{ $antrian->no_antrian }}
    +
    NOMOR ANTRIAN
    +
    + +
    +
    + Nama: + {{ $antrian->user->nama }} +
    +
    + Poli: + {{ $antrian->poli->nama_poli }} +
    +
    + Status: + {{ ucfirst($antrian->status) }} +
    +
    + Tanggal: + {{ $antrian->created_at->format('d/m/Y') }} +
    +
    + Waktu: + {{ $antrian->created_at->format('H:i') }} +
    +
    + + + +
    + Dicetak pada: {{ now()->format('d/m/Y H:i:s') }} +
    +
    + + + + + diff --git a/resources/views/welcome.blade.php b/resources/views/welcome.blade.php new file mode 100644 index 0000000..fa3ed6f --- /dev/null +++ b/resources/views/welcome.blade.php @@ -0,0 +1,83 @@ +@extends('layouts.app') + +@section('title', 'Sistem Antrian Puskesmas') + +@section('content') +
    +
    +
    +
    šŸ„
    +

    Sistem Antrian Puskesmas

    +

    Memudahkan pelayanan kesehatan masyarakat

    +
    + + + +
    +

    Mengalihkan ke beranda dalam 3 detik...

    +
    +
    +
    + + @push('scripts') + + @endpush +@endsection diff --git a/routes/console.php b/routes/console.php new file mode 100644 index 0000000..3c9adf1 --- /dev/null +++ b/routes/console.php @@ -0,0 +1,8 @@ +comment(Inspiring::quote()); +})->purpose('Display an inspiring quote'); diff --git a/routes/web.php b/routes/web.php new file mode 100644 index 0000000..b8a90e5 --- /dev/null +++ b/routes/web.php @@ -0,0 +1,90 @@ +name('landing'); + +// Display Page (Public) +Route::get('/display', [DisplayController::class, 'index'])->name('display'); + +// Authentication Routes +Route::get('/login', [AuthController::class, 'showLogin'])->name('login'); +Route::post('/login', [AuthController::class, 'login']); +Route::get('/register', [AuthController::class, 'showRegister'])->name('register'); +Route::post('/register', [AuthController::class, 'register']); +Route::post('/logout', [AuthController::class, 'logout'])->name('logout'); + +// Forgot Password Routes +Route::get('/forgot-password', [AuthController::class, 'showForgotPassword'])->name('forgot-password'); +Route::post('/forgot-password', [AuthController::class, 'forgotPassword']); +Route::get('/reset-password', [AuthController::class, 'showResetPassword'])->name('reset-password'); +Route::post('/reset-password', [AuthController::class, 'resetPassword']); + +// Protected Routes (User) +Route::middleware('auth')->group(function () { + Route::get('/dashboard', [DashboardController::class, 'index'])->name('dashboard'); + Route::post('/dashboard/add-queue', [DashboardController::class, 'addQueue'])->name('dashboard.add-queue'); + Route::put('/dashboard/update-profile', [DashboardController::class, 'updateProfile'])->name('dashboard.update-profile'); + + // User Antrian Routes + Route::post('/user/antrian/batal', [DashboardController::class, 'batalAntrian'])->name('user.batal-antrian'); + Route::get('/user/antrian/{antrian}/cetak', [DashboardController::class, 'cetakAntrian'])->name('user.antrian.cetak'); + + // Placeholder routes for future features + Route::get('/antrian/create', function () { + return redirect('/dashboard'); + })->name('antrian.create'); + Route::get('/antrian', function () { + return redirect('/dashboard'); + })->name('antrian.index'); + Route::get('/panggilan', function () { + return redirect('/dashboard'); + })->name('panggilan.index'); + Route::get('/laporan', function () { + return redirect('/dashboard'); + })->name('laporan.index'); +}); + +// Protected Routes (Admin) +Route::middleware('auth:admin')->group(function () { + Route::get('/admin/dashboard', [AdminController::class, 'dashboard'])->name('admin.dashboard'); + // Per-poli pages + Route::get('/admin/poli/umum', [AdminController::class, 'poliUmum'])->name('admin.poli.umum'); + Route::get('/admin/poli/gigi', [AdminController::class, 'poliGigi'])->name('admin.poli.gigi'); + Route::get('/admin/poli/jiwa', [AdminController::class, 'poliJiwa'])->name('admin.poli.jiwa'); + Route::get('/admin/poli/tradisional', [AdminController::class, 'poliTradisional'])->name('admin.poli.tradisional'); + Route::post('/admin/panggil-antrian', [AdminController::class, 'panggilAntrian'])->name('admin.panggil-antrian'); + Route::post('/admin/selesai-antrian', [AdminController::class, 'selesaiAntrian'])->name('admin.selesai-antrian'); + Route::post('/admin/antrian/batal', [AdminController::class, 'batalAntrian'])->name('admin.batal-antrian'); + Route::post('/admin/panggil-antrian/{antrian}', [AdminController::class, 'panggilAntrianById'])->name('admin.panggil-antrian-id'); + + // User Management Routes + Route::get('/admin/users', [AdminController::class, 'manageUsers'])->name('admin.users.index'); + Route::get('/admin/users/{user}', [AdminController::class, 'showUser'])->name('admin.users.show'); + Route::put('/admin/users/{user}', [AdminController::class, 'updateUser'])->name('admin.users.update'); + Route::post('/admin/users/{user}/reset-password', [AdminController::class, 'resetUserPassword'])->name('admin.users.reset-password'); + + // Laporan Routes + Route::get('/admin/laporan', [AdminController::class, 'laporan'])->name('admin.laporan.index'); + Route::get('/admin/laporan/export-pdf', [AdminController::class, 'exportPDF'])->name('admin.laporan.export-pdf'); + Route::get('/admin/laporan/export-excel', [AdminController::class, 'exportExcel'])->name('admin.laporan.export-excel'); + + // Antrian Routes + Route::get('/admin/antrian/{antrian}/cetak', [AdminController::class, 'cetakAntrian'])->name('admin.antrian.cetak'); + + // TTS Routes + Route::post('/admin/tts/generate', [TTSController::class, 'generateQueueCall'])->name('admin.tts.generate'); + Route::post('/admin/tts/audio-sequence', [TTSController::class, 'getAudioSequence'])->name('admin.tts.audio-sequence'); + Route::post('/admin/tts/play-sequence', [TTSController::class, 'playAudioSequence'])->name('admin.tts.play-sequence'); +}); + +// Public TTS Routes (for display) +Route::post('/tts/play-sequence', [TTSController::class, 'playAudioSequence'])->name('tts.play-sequence'); + diff --git a/storage/app/.gitignore b/storage/app/.gitignore new file mode 100644 index 0000000..fedb287 --- /dev/null +++ b/storage/app/.gitignore @@ -0,0 +1,4 @@ +* +!private/ +!public/ +!.gitignore diff --git a/storage/app/private/.gitignore b/storage/app/private/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/storage/app/private/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/storage/app/public/.gitignore b/storage/app/public/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/storage/app/public/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/storage/framework/.gitignore b/storage/framework/.gitignore new file mode 100644 index 0000000..05c4471 --- /dev/null +++ b/storage/framework/.gitignore @@ -0,0 +1,9 @@ +compiled.php +config.php +down +events.scanned.php +maintenance.php +routes.php +routes.scanned.php +schedule-* +services.json diff --git a/storage/framework/cache/.gitignore b/storage/framework/cache/.gitignore new file mode 100644 index 0000000..01e4a6c --- /dev/null +++ b/storage/framework/cache/.gitignore @@ -0,0 +1,3 @@ +* +!data/ +!.gitignore diff --git a/storage/framework/cache/data/.gitignore b/storage/framework/cache/data/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/storage/framework/cache/data/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/storage/framework/sessions/.gitignore b/storage/framework/sessions/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/storage/framework/sessions/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/storage/framework/testing/.gitignore b/storage/framework/testing/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/storage/framework/testing/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/storage/framework/views/.gitignore b/storage/framework/views/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/storage/framework/views/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/storage/logs/.gitignore b/storage/logs/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/storage/logs/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/test_riwayat.php b/test_riwayat.php new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/test_riwayat.php @@ -0,0 +1 @@ + diff --git a/test_tts.php b/test_tts.php new file mode 100644 index 0000000..d23f6ea --- /dev/null +++ b/test_tts.php @@ -0,0 +1,35 @@ +generateQueueCall('Poli Umum', 'A001'); + echo "Result: " . json_encode($result, JSON_PRETTY_PRINT) . "\n\n"; + + echo "2. Testing createCompleteAudioSequence...\n"; + $sequence = $ttsService->createCompleteAudioSequence('Poli Umum', 'A001'); + echo "Sequence: " . json_encode($sequence, JSON_PRETTY_PRINT) . "\n\n"; + + echo "3. Testing dengan poli berbeda...\n"; + $sequence2 = $ttsService->createCompleteAudioSequence('Poli Gigi', 'B002'); + echo "Sequence 2: " . json_encode($sequence2, JSON_PRETTY_PRINT) . "\n\n"; + + echo "āœ… TTS Service berfungsi dengan baik!\n"; + +} catch (Exception $e) { + echo "āŒ Error: " . $e->getMessage() . "\n"; + echo "Stack trace: " . $e->getTraceAsString() . "\n"; +} + +echo "\n=== Test Selesai ===\n"; diff --git a/test_tts_simple.php b/test_tts_simple.php new file mode 100644 index 0000000..9cc0d43 --- /dev/null +++ b/test_tts_simple.php @@ -0,0 +1,53 @@ + diff --git a/tests/Feature/ExampleTest.php b/tests/Feature/ExampleTest.php new file mode 100644 index 0000000..8364a84 --- /dev/null +++ b/tests/Feature/ExampleTest.php @@ -0,0 +1,19 @@ +get('/'); + + $response->assertStatus(200); + } +} diff --git a/tests/TestCase.php b/tests/TestCase.php new file mode 100644 index 0000000..fe1ffc2 --- /dev/null +++ b/tests/TestCase.php @@ -0,0 +1,10 @@ +assertTrue(true); + } +} diff --git a/vite.config.js b/vite.config.js new file mode 100644 index 0000000..29fbfe9 --- /dev/null +++ b/vite.config.js @@ -0,0 +1,13 @@ +import { defineConfig } from 'vite'; +import laravel from 'laravel-vite-plugin'; +import tailwindcss from '@tailwindcss/vite'; + +export default defineConfig({ + plugins: [ + laravel({ + input: ['resources/css/app.css', 'resources/js/app.js'], + refresh: true, + }), + tailwindcss(), + ], +});