From 1da87856b1acb0d9b3c4bf41d89f2c3646290e12 Mon Sep 17 00:00:00 2001 From: Martin Vach Date: Thu, 8 Jan 2026 19:45:42 +0100 Subject: [PATCH 001/103] 2: Adding domain manager --- app/Providers/MultiDomainServiceProvider.php | 60 +++++++++++++++++++ app/Services/DomainManagerService.php | 51 ++++++++++++++++ bootstrap/providers.php | 2 +- resources/views/default/home.blade.php | 34 +++++++++++ .../views/sites/myprompties/home.blade.php | 34 +++++++++++ routes/default.php | 8 +++ routes/myprompties.php | 8 +++ routes/web.php | 17 ++++-- 8 files changed, 208 insertions(+), 6 deletions(-) create mode 100644 app/Providers/MultiDomainServiceProvider.php create mode 100644 app/Services/DomainManagerService.php create mode 100644 resources/views/default/home.blade.php create mode 100644 resources/views/sites/myprompties/home.blade.php create mode 100644 routes/default.php create mode 100644 routes/myprompties.php diff --git a/app/Providers/MultiDomainServiceProvider.php b/app/Providers/MultiDomainServiceProvider.php new file mode 100644 index 0000000..05d1060 --- /dev/null +++ b/app/Providers/MultiDomainServiceProvider.php @@ -0,0 +1,60 @@ +app->singleton(DomainManagerService::class, function ($app) { + return new DomainManagerService($app->request); + }); + } + + public function boot(DomainManagerService $domainManager): void + { + $slug = $domainManager->getSlug(); + + // 1. View System Cascade + // Look in sites/{slug} first, then default/, then standard resources/views + $siteViewPath = resource_path("views/sites/{$slug}"); + $defaultViewPath = resource_path("views/default"); + + if (is_dir($siteViewPath)) { + View::getFinder()->prependLocation($siteViewPath); + } + if (is_dir($defaultViewPath)) { + View::getFinder()->addLocation($defaultViewPath); + } + + // 2. Vite Build Directory + // Assets are served from the domain's specific build folder + Vite::useBuildDirectory('build'); + + // 3. Routing + // Prevent double-loading of routes + /*if (!app()->has('routes_loaded_by_multidomain')) { + $this->registerRoutes($slug); + app()->instance('routes_loaded_by_multidomain', true); + }*/ + } + //TODO: Does not work as expected, routes are loaded twice causing route conflicts + protected function registerRoutes(string $slug): void + { + $routeFile = base_path("routes/{$slug}.php"); + + if (file_exists($routeFile)) { + ds("Loading domain route file: {$routeFile}"); + Route::middleware('web')->group($routeFile); + } else { + ds("Loading fallback route file: routes/web.php"); + Route::middleware('web')->group(base_path('routes/web.php')); + } + } +} diff --git a/app/Services/DomainManagerService.php b/app/Services/DomainManagerService.php new file mode 100644 index 0000000..0a9723b --- /dev/null +++ b/app/Services/DomainManagerService.php @@ -0,0 +1,51 @@ +currentHost = $request->getHost(); + $this->detectSlug(); + $this->resolveProjectId(); + } + + protected function detectSlug(): void + { + // 1. Remove www. + $host = Str::replace('www.', '', $this->currentHost); + + // 2. Explode by dot and take the first part (ivnbg.com -> ivnbg) + $parts = explode('.', $host); + $this->slug = $parts[0] ?? 'default'; + } + + protected function resolveProjectId(): void + { + // Cache the lookup forever to avoid DB queries on every request. + // Run 'php artisan cache:clear' if you manually change IDs in DB. + $this->projectId = Cache::rememberForever("project_id_map_{$this->slug}", function () { + return Project::where('slug', $this->slug)->value('id'); + }); + } + + public function getSlug(): string + { + return $this->slug; + } + + public function getProjectId(): ?int + { + return $this->projectId; + } +} diff --git a/bootstrap/providers.php b/bootstrap/providers.php index 3ad94e3..00e1942 100644 --- a/bootstrap/providers.php +++ b/bootstrap/providers.php @@ -2,7 +2,7 @@ return [ App\Providers\AppServiceProvider::class, - App\Providers\FortifyServiceProvider::class, + App\Providers\MultiDomainServiceProvider::class, App\Providers\TelescopeServiceProvider::class, App\Providers\VoltServiceProvider::class, ]; diff --git a/resources/views/default/home.blade.php b/resources/views/default/home.blade.php new file mode 100644 index 0000000..39bd7b9 --- /dev/null +++ b/resources/views/default/home.blade.php @@ -0,0 +1,34 @@ + + + + + + Martin Vach Photography | Coming Soon + + + + + + + +
+
+

+ laravel-core.test +

+
+
+ + +
+ content here +
+ + + diff --git a/resources/views/sites/myprompties/home.blade.php b/resources/views/sites/myprompties/home.blade.php new file mode 100644 index 0000000..3e837c4 --- /dev/null +++ b/resources/views/sites/myprompties/home.blade.php @@ -0,0 +1,34 @@ + + + + + + Martin Vach Photography | Coming Soon + + + + + + + +
+
+

+ MyPrompties.com +

+
+
+ + +
+ content here +
+ + + diff --git a/routes/default.php b/routes/default.php new file mode 100644 index 0000000..b90d64f --- /dev/null +++ b/routes/default.php @@ -0,0 +1,8 @@ +name('home'); diff --git a/routes/myprompties.php b/routes/myprompties.php new file mode 100644 index 0000000..b90d64f --- /dev/null +++ b/routes/myprompties.php @@ -0,0 +1,8 @@ +name('home'); diff --git a/routes/web.php b/routes/web.php index 59be49a..aa790c5 100644 --- a/routes/web.php +++ b/routes/web.php @@ -1,8 +1,15 @@ getSlug()}.php"); + +if (file_exists($routeFile)) { + ds("Loading domain route file: {$routeFile}"); + require_once $routeFile; +} else { + ds("Loading fallback route file: routes/default.php"); + require_once base_path('routes/default.php'); +} -Route::get('/', function () { - ds('Welcome to Livewire Volt!'); - return view('welcome'); -})->name('home'); From 7dbe0b1dbd4702931d21937bcd9148c23256a51b Mon Sep 17 00:00:00 2001 From: Martin Vach Date: Fri, 9 Jan 2026 11:21:38 +0100 Subject: [PATCH 002/103] 2: Configuring vite for multidomain --- app/Models/Category.php | 2 + app/Models/Content.php | 2 + app/Models/Inquiry.php | 2 + app/Models/Tag.php | 2 + app/Traits/FilterByProject.php | 37 +++++++++ package-lock.json | 91 ++++++++++++++++++++++ package.json | 8 +- resources/views/sites/vades/home.blade.php | 34 ++++++++ routes/vades.php | 8 ++ vite.config.js | 49 ++++++++---- 10 files changed, 221 insertions(+), 14 deletions(-) create mode 100644 app/Traits/FilterByProject.php create mode 100644 resources/views/sites/vades/home.blade.php create mode 100644 routes/vades.php diff --git a/app/Models/Category.php b/app/Models/Category.php index 6a27116..675d258 100644 --- a/app/Models/Category.php +++ b/app/Models/Category.php @@ -2,6 +2,7 @@ namespace App\Models; +use App\Traits\FilterByProject; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; @@ -34,6 +35,7 @@ class Category extends Model { use HasFactory; use SoftDeletes; + use FilterByProject; /** * The attributes that are mass assignable. diff --git a/app/Models/Content.php b/app/Models/Content.php index 4b663a8..d9b5899 100644 --- a/app/Models/Content.php +++ b/app/Models/Content.php @@ -2,6 +2,7 @@ namespace App\Models; +use App\Traits\FilterByProject; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; @@ -42,6 +43,7 @@ class Content extends Model { use HasFactory; use SoftDeletes; + use FilterByProject; /** * The attributes that are mass assignable. diff --git a/app/Models/Inquiry.php b/app/Models/Inquiry.php index 074c590..392f699 100644 --- a/app/Models/Inquiry.php +++ b/app/Models/Inquiry.php @@ -2,6 +2,7 @@ namespace App\Models; +use App\Traits\FilterByProject; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\SoftDeletes; @@ -32,6 +33,7 @@ class Inquiry extends Model { use SoftDeletes; + use FilterByProject; /** * The attributes that are mass assignable. diff --git a/app/Models/Tag.php b/app/Models/Tag.php index a390a5f..1b282f6 100644 --- a/app/Models/Tag.php +++ b/app/Models/Tag.php @@ -2,6 +2,7 @@ namespace App\Models; +use App\Traits\FilterByProject; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\SoftDeletes; @@ -25,6 +26,7 @@ class Tag extends Model { use SoftDeletes; + use FilterByProject; /** * The attributes that are mass assignable. diff --git a/app/Traits/FilterByProject.php b/app/Traits/FilterByProject.php new file mode 100644 index 0000000..4d7d269 --- /dev/null +++ b/app/Traits/FilterByProject.php @@ -0,0 +1,37 @@ +getProjectId(); + + if ($projectId) { + $builder->where('project_id', $projectId); + } else { + // Safety: If no project identified, return no results + $builder->whereRaw('1 = 0'); + } + }); + + // 2. Auto-assign ID on Create + static::creating(function (Model $model) { + $manager = app(DomainManagerService::class); + if (!$model->project_id && $manager->getProjectId()) { + $model->project_id = $manager->getProjectId(); + } + }); + } +} diff --git a/package-lock.json b/package-lock.json index 9cf7ab2..934402b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,9 @@ "tailwindcss": "^4.0.7", "vite": "^7.0.4" }, + "devDependencies": { + "cross-env": "^10.1.0" + }, "optionalDependencies": { "@rollup/rollup-linux-x64-gnu": "4.9.5", "@tailwindcss/oxide-linux-x64-gnu": "^4.0.1", @@ -32,6 +35,12 @@ "node": ">=6.0.0" } }, + "node_modules/@epic-web/invariant": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@epic-web/invariant/-/invariant-1.0.0.tgz", + "integrity": "sha512-lrTPqgvfFQtR/eY/qkIzp98OGdNJu0m5ji3q/nJI8v3SXkRKEnWiOxMmbvcSoAIzv/cGiuvRy57k4suKQSAdwA==", + "dev": true + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.25.8", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.8.tgz", @@ -1272,6 +1281,37 @@ "url": "https://github.com/open-cli-tools/concurrently?sponsor=1" } }, + "node_modules/cross-env": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-10.1.0.tgz", + "integrity": "sha512-GsYosgnACZTADcmEyJctkJIoqAhHjttw7RsFrVoJNXbsWWqaq6Ym+7kZjq6mS45O0jij6vtiReppKQEtqWy6Dw==", + "dev": true, + "dependencies": { + "@epic-web/invariant": "^1.0.0", + "cross-spawn": "^7.0.6" + }, + "bin": { + "cross-env": "dist/bin/cross-env.js", + "cross-env-shell": "dist/bin/cross-env-shell.js" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -1634,6 +1674,12 @@ "node": ">=8" } }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, "node_modules/jiti": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.5.1.tgz", @@ -2004,6 +2050,15 @@ "node": ">=0.10.0" } }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -2132,6 +2187,27 @@ "tslib": "^2.1.0" } }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/shell-quote": { "version": "1.8.3", "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz", @@ -2383,6 +2459,21 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", diff --git a/package.json b/package.json index 688bea8..203f620 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,10 @@ "type": "module", "scripts": { "build": "vite build", - "dev": "vite" + "dev": "vite", + "build:vades": "cross-env SITE=vades.dev vite build", + "build:myprompties": "cross-env SITE=mypromties.com vite build", + "build:all": "npm run build:vades && npm run build:myprompties" }, "dependencies": { "@tailwindcss/vite": "^4.1.11", @@ -19,5 +22,8 @@ "@rollup/rollup-linux-x64-gnu": "4.9.5", "@tailwindcss/oxide-linux-x64-gnu": "^4.0.1", "lightningcss-linux-x64-gnu": "^1.29.1" + }, + "devDependencies": { + "cross-env": "^10.1.0" } } diff --git a/resources/views/sites/vades/home.blade.php b/resources/views/sites/vades/home.blade.php new file mode 100644 index 0000000..8a963a7 --- /dev/null +++ b/resources/views/sites/vades/home.blade.php @@ -0,0 +1,34 @@ + + + + + + Martin Vach Photography | Coming Soon + + + + + + + +
+
+

+ vades.dev +

+
+
+ + +
+ content here +
+ + + diff --git a/routes/vades.php b/routes/vades.php new file mode 100644 index 0000000..b90d64f --- /dev/null +++ b/routes/vades.php @@ -0,0 +1,8 @@ +name('home'); diff --git a/vite.config.js b/vite.config.js index f65249e..533c20f 100644 --- a/vite.config.js +++ b/vite.config.js @@ -3,19 +3,42 @@ import { } from 'vite'; import laravel from 'laravel-vite-plugin'; import tailwindcss from "@tailwindcss/vite"; +import path from 'path'; -export default defineConfig({ - plugins: [ - laravel({ - input: ['resources/css/app.css', 'resources/js/app.js'], - refresh: true, - }), - tailwindcss(), - ], - server: { - cors: true, - watch: { - ignored: ['**/storage/framework/views/**'], +export default defineConfig(() => { + // Check if SITE is defined + const site = process.env.SITE; + + // Determine the public root + // If SITE exists, resolve to external domain. If not, use default 'public'. + const publicDir = site + ? path.resolve(__dirname, '..', 'domains', site, 'public_html') + : 'public'; + + return { + plugins: [ + laravel({ + input: ['resources/css/app.css', 'resources/js/app.js'], + refresh: true, + + // Pass the dynamic directory here + publicDirectory: publicDir, + + // Keep this as 'build'. It will be appended to whichever publicDir is active. + buildDirectory: 'build', + }), + tailwindcss(), + ], + build: { + // Important: Allow Vite to empty a directory that is outside + // the root of the current project + emptyOutDir: true, + }, + server: { + cors: true, + watch: { + ignored: ['**/storage/framework/views/**'], + }, }, - }, + }; }); From d9c69456c6f141d5184802ce3a30e4369104707e Mon Sep 17 00:00:00 2001 From: Martin Vach Date: Fri, 16 Jan 2026 14:55:29 +0100 Subject: [PATCH 003/103] Merge pull request #7 * #6: Adding DB seeders * #6: Adding tag seeder * #6: Adding inquiry seeder * #6: Updaitng inquiry seeder * #6: Adding Content seeder * #6: Adding Content Category/Tag seeders * #6: Updating content seeder * #6: Updating seeders * #6: Updating seeders * #6: Adding basic Enums * #6: Finalyzing seeders --- README.md | 83 +--------- app/Enums/AccountType.php | 9 ++ app/Enums/AppProject.php | 13 ++ app/Enums/ContentContentType.php | 12 ++ app/Enums/ContentStatus.php | 10 ++ app/Enums/ContentVisibility.php | 11 ++ app/Enums/Language.php | 21 +++ app/Enums/UserRole.php | 12 ++ app/Models/Category.php | 7 +- app/Models/Content.php | 12 +- app/Models/Inquiry.php | 5 +- app/Models/Project.php | 2 +- app/Models/Tag.php | 8 +- app/Models/User.php | 11 +- composer.lock | 142 +++++++++--------- database/data/ivnbg-categories.csv | 23 +++ database/factories/CategoryFactory.php | 87 +++++++++++ database/factories/ContentFactory.php | 51 +++++++ database/factories/InquiryFactory.php | 41 +++++ database/factories/ProjectFactory.php | 54 +++++++ database/factories/TagFactory.php | 34 +++++ database/factories/UserFactory.php | 52 +++++-- ...5_184613_add_project_id_to_users_table.php | 1 + .../2026_01_05_185832_create_tags_table.php | 5 +- database/seeders/CategoryContentSeeder.php | 33 ++++ database/seeders/CategorySeeder.php | 33 ++++ database/seeders/CategorySeederProject.php | 44 ++++++ database/seeders/ContentSeeder.php | 28 ++++ database/seeders/ContentTagSeeder.php | 31 ++++ database/seeders/DatabaseSeeder.php | 75 +++------ database/seeders/InquirySeeder.php | 20 +++ database/seeders/ProjectSeeder.php | 63 ++++++++ database/seeders/TagSeeder.php | 23 +++ database/seeders/UserSeeder.php | 40 +++++ 34 files changed, 860 insertions(+), 236 deletions(-) create mode 100644 app/Enums/AccountType.php create mode 100644 app/Enums/AppProject.php create mode 100644 app/Enums/ContentContentType.php create mode 100644 app/Enums/ContentStatus.php create mode 100644 app/Enums/ContentVisibility.php create mode 100644 app/Enums/Language.php create mode 100644 app/Enums/UserRole.php create mode 100644 database/data/ivnbg-categories.csv create mode 100644 database/factories/CategoryFactory.php create mode 100644 database/factories/ContentFactory.php create mode 100644 database/factories/InquiryFactory.php create mode 100644 database/factories/ProjectFactory.php create mode 100644 database/factories/TagFactory.php create mode 100644 database/seeders/CategoryContentSeeder.php create mode 100644 database/seeders/CategorySeeder.php create mode 100644 database/seeders/CategorySeederProject.php create mode 100644 database/seeders/ContentSeeder.php create mode 100644 database/seeders/ContentTagSeeder.php create mode 100644 database/seeders/InquirySeeder.php create mode 100644 database/seeders/ProjectSeeder.php create mode 100644 database/seeders/TagSeeder.php create mode 100644 database/seeders/UserSeeder.php diff --git a/README.md b/README.md index b8e26ad..d8df5e6 100644 --- a/README.md +++ b/README.md @@ -1,82 +1 @@ -# 3rd party libraries used in the app -## laravel-google-drive-storage -This package allow to store and get data from google drive like S3 AWS in laravel -https://github.com/yaza-putu/laravel-google-drive-storage -# Run app with docker -```bash -docker compose up -d -``` -# Laravel quick commands -- `npm run dev` Running Vite -- `php artisan serve` Running Laravel -- `npm run build` Build for production -- `php artisan migrate` Run migrations -- `php artisan make:controller ControllerName` Create a new controller -- `php artisan route:list` List all routes -- `php artisan make:viewcomposer ViewComposerName` Create a new view composer -- `php artisan make:component web.features.blog --inline` Create a new component -- `php artisan make:livewire dir.component-name` Create a new Livewire component -- `php artisan make:livewire dir.component-name --inline` Create a new inline Livewire component -- `php artisan livewire:stubs` Publish Livewire stubs -- `php artisan livewire:layout` Create a new layout file -- `php artisan make:migration create_flights_table` Create a new migration file -- `php artisan make:migration add_status_to_flights_table --table=flights` Create a new migration file to modify an existing table -- `php artisan make:seeder SeederName` Create a new middleware -- `php artisan migrate:reset` -- `php artisan migrate:rollback` -- `php artisan migrate:fresh` Drop all tables and re-run all migrations -- `php artisan migrate:refresh` Rollback and re-run all migrations -- `php artisan migrate:refresh --seed --force` Rollback and re-run all migrations and seed the database -- `php artisan db:seed` -- `php artisan cache:clear` -- `php artisan view:clear` -- `php artisan config:clear` -- `php artisan route:clear` -- `composer dump-autoload` -- `php artisan tinker` -- `php artisan make:scope ProjectScope` -- `php artisan make:trait` -- `php artisan make:command CustomTask` -- `php artisan make:class CustomClass` -- `php artisan config:show myapp` -- `php artisan schedule:run` -- `php artisan schedule:work` -- `php artisan schedule:list` - -## Imports -IMPORTANT: USE `docker-compose exec larapi` php artisan app:db-test -- php artisan app:import-project --name martinvach -- php artisan app:generate-album --url https://www.ivnbg.com/storage/albums -- php artisan app:csv-to-md -- php artisan app:generate-ivnbg-sitemap -- php artisan app:generate-martinvach-sitemap -- php artisan app:sync-drive-to-local "KB/MyProjects/Larapi/imports" "app/imports" -- php artisan app:google-drive-synchronize "KB/MyProjects/Larapi/imports" "app/imports" -- php artisan app:google-drive-download-files "KB/MyProjects/ivnbg.com/content/posts/place" "app/imports/projects/ivnbg/posts/place" -- php artisan app:google-drive-synchronize "albums" "storage/albums" - -``` --c, --controller Create a new controller for the model --f, --factory Create a new factory for the model ---force Create the class even if the model already exists --m, --migration Create a new migration file for the model --s, --seed Create a new seeder file for the model --p, --pivot Indicates if the generated model should be a custom intermediate table model --r, --resource Indicates if the generated controller should be a resource controller -For More Help -php artisan make:model Todo -help -``` - -```bash -php artisan cache:clear -php artisan view:clear -php artisan config:clear -php artisan route:clear -composer dump-autoload -``` - -``` - base_path(); // '/var/www/mysite' - app_path(); // '/var/www/mysite/app' - storage_path(); // '/var/www/mysite/storage' -``` +# Laravel multi domain app \ No newline at end of file diff --git a/app/Enums/AccountType.php b/app/Enums/AccountType.php new file mode 100644 index 0000000..415f50c --- /dev/null +++ b/app/Enums/AccountType.php @@ -0,0 +1,9 @@ + 'English', + self::ES => 'Spanish', + self::FR => 'French', + self::DE => 'German', + }; + } +} \ No newline at end of file diff --git a/app/Enums/UserRole.php b/app/Enums/UserRole.php new file mode 100644 index 0000000..6bf35cd --- /dev/null +++ b/app/Enums/UserRole.php @@ -0,0 +1,12 @@ +belongsTo(Category::class, 'parent_id'); } -} + + public function contents() + { + return $this->belongsToMany(Content::class); + } +} \ No newline at end of file diff --git a/app/Models/Content.php b/app/Models/Content.php index d9b5899..44ecb7b 100644 --- a/app/Models/Content.php +++ b/app/Models/Content.php @@ -110,4 +110,14 @@ public function parent(): BelongsTo { return $this->belongsTo(Content::class, 'parent_id'); } -} + + public function categories() + { + return $this->belongsToMany(Category::class, 'category_content'); + } + + public function tags() + { + return $this->belongsToMany(Tag::class,'content_tag'); + } +} \ No newline at end of file diff --git a/app/Models/Inquiry.php b/app/Models/Inquiry.php index 392f699..92e3ed1 100644 --- a/app/Models/Inquiry.php +++ b/app/Models/Inquiry.php @@ -3,6 +3,7 @@ namespace App\Models; use App\Traits\FilterByProject; +use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\SoftDeletes; @@ -34,6 +35,7 @@ class Inquiry extends Model { use SoftDeletes; use FilterByProject; + use HasFactory; /** * The attributes that are mass assignable. @@ -85,5 +87,4 @@ public function user(): \Illuminate\Database\Eloquent\Relations\BelongsTo { return $this->belongsTo(User::class); } -} - +} \ No newline at end of file diff --git a/app/Models/Project.php b/app/Models/Project.php index 0947dc6..b6198d3 100644 --- a/app/Models/Project.php +++ b/app/Models/Project.php @@ -65,4 +65,4 @@ public function users() { return $this->hasMany(User::class); } -} +} \ No newline at end of file diff --git a/app/Models/Tag.php b/app/Models/Tag.php index 1b282f6..574f11c 100644 --- a/app/Models/Tag.php +++ b/app/Models/Tag.php @@ -3,6 +3,7 @@ namespace App\Models; use App\Traits\FilterByProject; +use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\SoftDeletes; @@ -27,6 +28,7 @@ class Tag extends Model { use SoftDeletes; use FilterByProject; + use HasFactory; /** * The attributes that are mass assignable. @@ -62,5 +64,9 @@ public function project(): \Illuminate\Database\Eloquent\Relations\BelongsTo { return $this->belongsTo(Project::class); } -} + public function contents() + { + return $this->belongsToMany(Content::class); + } +} \ No newline at end of file diff --git a/app/Models/User.php b/app/Models/User.php index 214bea4..b923c96 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -19,12 +19,20 @@ class User extends Authenticatable * * @var list */ + /** + * The attributes that are mass assignable. + * + * @var array + */ protected $fillable = [ 'name', 'email', 'password', + 'project_id', // Ensure this is here + 'role', // Ensure this is here + 'account_type', // Ensure this is here + 'metadata', // Ensure this is here ]; - /** * The attributes that should be hidden for serialization. * @@ -47,6 +55,7 @@ protected function casts(): array return [ 'email_verified_at' => 'datetime', 'password' => 'hashed', + 'metadata' => 'array', ]; } diff --git a/composer.lock b/composer.lock index 0989583..d17c40c 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "b21e8ed2057bdecd484020111ab2e3bc", + "content-hash": "80a762c02014aa2e33d1b116da198356", "packages": [ { "name": "bacon/bacon-qr-code", @@ -1270,16 +1270,16 @@ }, { "name": "laravel/framework", - "version": "v12.44.0", + "version": "v12.46.0", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "592bbf1c036042958332eb98e3e8131b29102f33" + "reference": "9dcff48d25a632c1fadb713024c952fec489c4ae" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/592bbf1c036042958332eb98e3e8131b29102f33", - "reference": "592bbf1c036042958332eb98e3e8131b29102f33", + "url": "https://api.github.com/repos/laravel/framework/zipball/9dcff48d25a632c1fadb713024c952fec489c4ae", + "reference": "9dcff48d25a632c1fadb713024c952fec489c4ae", "shasum": "" }, "require": { @@ -1488,7 +1488,7 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2025-12-23T15:29:43+00:00" + "time": "2026-01-07T23:26:53+00:00" }, { "name": "laravel/prompts", @@ -1612,16 +1612,16 @@ }, { "name": "laravel/telescope", - "version": "v5.16.0", + "version": "v5.16.1", "source": { "type": "git", "url": "https://github.com/laravel/telescope.git", - "reference": "a868e91a0912d6a44363636f7467a8578db83026" + "reference": "dc114b94f025b8c16b5eb3194b4ddc0e46d5310c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/telescope/zipball/a868e91a0912d6a44363636f7467a8578db83026", - "reference": "a868e91a0912d6a44363636f7467a8578db83026", + "url": "https://api.github.com/repos/laravel/telescope/zipball/dc114b94f025b8c16b5eb3194b4ddc0e46d5310c", + "reference": "dc114b94f025b8c16b5eb3194b4ddc0e46d5310c", "shasum": "" }, "require": { @@ -1674,22 +1674,22 @@ ], "support": { "issues": "https://github.com/laravel/telescope/issues", - "source": "https://github.com/laravel/telescope/tree/v5.16.0" + "source": "https://github.com/laravel/telescope/tree/v5.16.1" }, - "time": "2025-12-09T13:34:29+00:00" + "time": "2025-12-30T17:31:31+00:00" }, { "name": "laravel/tinker", - "version": "v2.10.2", + "version": "v2.11.0", "source": { "type": "git", "url": "https://github.com/laravel/tinker.git", - "reference": "3bcb5f62d6f837e0f093a601e26badafb127bd4c" + "reference": "3d34b97c9a1747a81a3fde90482c092bd8b66468" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/tinker/zipball/3bcb5f62d6f837e0f093a601e26badafb127bd4c", - "reference": "3bcb5f62d6f837e0f093a601e26badafb127bd4c", + "url": "https://api.github.com/repos/laravel/tinker/zipball/3d34b97c9a1747a81a3fde90482c092bd8b66468", + "reference": "3d34b97c9a1747a81a3fde90482c092bd8b66468", "shasum": "" }, "require": { @@ -1698,7 +1698,7 @@ "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" + "symfony/var-dumper": "^4.3.4|^5.0|^6.0|^7.0|^8.0" }, "require-dev": { "mockery/mockery": "~1.3.3|^1.4.2", @@ -1740,9 +1740,9 @@ ], "support": { "issues": "https://github.com/laravel/tinker/issues", - "source": "https://github.com/laravel/tinker/tree/v2.10.2" + "source": "https://github.com/laravel/tinker/tree/v2.11.0" }, - "time": "2025-11-20T16:29:12+00:00" + "time": "2025-12-19T19:16:45+00:00" }, { "name": "league/commonmark", @@ -3404,16 +3404,16 @@ }, { "name": "phpstan/phpdoc-parser", - "version": "2.3.0", + "version": "2.3.1", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "1e0cd5370df5dd2e556a36b9c62f62e555870495" + "reference": "16dbf9937da8d4528ceb2145c9c7c0bd29e26374" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/1e0cd5370df5dd2e556a36b9c62f62e555870495", - "reference": "1e0cd5370df5dd2e556a36b9c62f62e555870495", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/16dbf9937da8d4528ceb2145c9c7c0bd29e26374", + "reference": "16dbf9937da8d4528ceb2145c9c7c0bd29e26374", "shasum": "" }, "require": { @@ -3445,9 +3445,9 @@ "description": "PHPDoc parser with support for nullable, intersection and generic types", "support": { "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/2.3.0" + "source": "https://github.com/phpstan/phpdoc-parser/tree/2.3.1" }, - "time": "2025-08-30T15:50:23+00:00" + "time": "2026-01-12T11:33:04+00:00" }, { "name": "pragmarx/google2fa", @@ -4743,16 +4743,16 @@ }, { "name": "spatie/temporary-directory", - "version": "2.3.0", + "version": "2.3.1", "source": { "type": "git", "url": "https://github.com/spatie/temporary-directory.git", - "reference": "580eddfe9a0a41a902cac6eeb8f066b42e65a32b" + "reference": "662e481d6ec07ef29fd05010433428851a42cd07" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/temporary-directory/zipball/580eddfe9a0a41a902cac6eeb8f066b42e65a32b", - "reference": "580eddfe9a0a41a902cac6eeb8f066b42e65a32b", + "url": "https://api.github.com/repos/spatie/temporary-directory/zipball/662e481d6ec07ef29fd05010433428851a42cd07", + "reference": "662e481d6ec07ef29fd05010433428851a42cd07", "shasum": "" }, "require": { @@ -4788,7 +4788,7 @@ ], "support": { "issues": "https://github.com/spatie/temporary-directory/issues", - "source": "https://github.com/spatie/temporary-directory/tree/2.3.0" + "source": "https://github.com/spatie/temporary-directory/tree/2.3.1" }, "funding": [ { @@ -4800,7 +4800,7 @@ "type": "github" } ], - "time": "2025-01-13T13:04:43+00:00" + "time": "2026-01-12T07:42:22+00:00" }, { "name": "spatie/yaml-front-matter", @@ -7777,16 +7777,16 @@ "packages-dev": [ { "name": "brianium/paratest", - "version": "v7.16.0", + "version": "v7.16.1", "source": { "type": "git", "url": "https://github.com/paratestphp/paratest.git", - "reference": "a10878ed0fe0bbc2f57c980f7a08065338b970b6" + "reference": "f0fdfd8e654e0d38bc2ba756a6cabe7be287390b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/paratestphp/paratest/zipball/a10878ed0fe0bbc2f57c980f7a08065338b970b6", - "reference": "a10878ed0fe0bbc2f57c980f7a08065338b970b6", + "url": "https://api.github.com/repos/paratestphp/paratest/zipball/f0fdfd8e654e0d38bc2ba756a6cabe7be287390b", + "reference": "f0fdfd8e654e0d38bc2ba756a6cabe7be287390b", "shasum": "" }, "require": { @@ -7797,10 +7797,10 @@ "fidry/cpu-core-counter": "^1.3.0", "jean85/pretty-package-versions": "^2.1.1", "php": "~8.3.0 || ~8.4.0 || ~8.5.0", - "phpunit/php-code-coverage": "^12.5.1", + "phpunit/php-code-coverage": "^12.5.2", "phpunit/php-file-iterator": "^6", "phpunit/php-timer": "^8", - "phpunit/phpunit": "^12.5.2", + "phpunit/phpunit": "^12.5.4", "sebastian/environment": "^8.0.3", "symfony/console": "^7.3.4 || ^8.0.0", "symfony/process": "^7.3.4 || ^8.0.0" @@ -7812,7 +7812,7 @@ "ext-posix": "*", "phpstan/phpstan": "^2.1.33", "phpstan/phpstan-deprecation-rules": "^2.0.3", - "phpstan/phpstan-phpunit": "^2.0.10", + "phpstan/phpstan-phpunit": "^2.0.11", "phpstan/phpstan-strict-rules": "^2.0.7", "symfony/filesystem": "^7.3.2 || ^8.0.0" }, @@ -7854,7 +7854,7 @@ ], "support": { "issues": "https://github.com/paratestphp/paratest/issues", - "source": "https://github.com/paratestphp/paratest/tree/v7.16.0" + "source": "https://github.com/paratestphp/paratest/tree/v7.16.1" }, "funding": [ { @@ -7866,7 +7866,7 @@ "type": "paypal" } ], - "time": "2025-12-09T20:03:26+00:00" + "time": "2026-01-08T07:23:06+00:00" }, { "name": "fakerphp/faker", @@ -8317,16 +8317,16 @@ }, { "name": "laravel/boost", - "version": "v1.8.7", + "version": "v1.8.9", "source": { "type": "git", "url": "https://github.com/laravel/boost.git", - "reference": "7a5709a8134ed59d3e7f34fccbd74689830e296c" + "reference": "1f2c2d41b5216618170fb6730ec13bf894c5bffd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/boost/zipball/7a5709a8134ed59d3e7f34fccbd74689830e296c", - "reference": "7a5709a8134ed59d3e7f34fccbd74689830e296c", + "url": "https://api.github.com/repos/laravel/boost/zipball/1f2c2d41b5216618170fb6730ec13bf894c5bffd", + "reference": "1f2c2d41b5216618170fb6730ec13bf894c5bffd", "shasum": "" }, "require": { @@ -8379,20 +8379,20 @@ "issues": "https://github.com/laravel/boost/issues", "source": "https://github.com/laravel/boost" }, - "time": "2025-12-19T15:04:12+00:00" + "time": "2026-01-07T18:43:11+00:00" }, { "name": "laravel/mcp", - "version": "v0.5.1", + "version": "v0.5.2", "source": { "type": "git", "url": "https://github.com/laravel/mcp.git", - "reference": "10dedea054fa4eeaa9ef2ccbfdad6c3e1dbd17a4" + "reference": "b9bdd8d6f8b547c8733fe6826b1819341597ba3c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/mcp/zipball/10dedea054fa4eeaa9ef2ccbfdad6c3e1dbd17a4", - "reference": "10dedea054fa4eeaa9ef2ccbfdad6c3e1dbd17a4", + "url": "https://api.github.com/repos/laravel/mcp/zipball/b9bdd8d6f8b547c8733fe6826b1819341597ba3c", + "reference": "b9bdd8d6f8b547c8733fe6826b1819341597ba3c", "shasum": "" }, "require": { @@ -8452,7 +8452,7 @@ "issues": "https://github.com/laravel/mcp/issues", "source": "https://github.com/laravel/mcp" }, - "time": "2025-12-17T06:14:23+00:00" + "time": "2025-12-19T19:32:34+00:00" }, { "name": "laravel/pail", @@ -8535,16 +8535,16 @@ }, { "name": "laravel/pint", - "version": "v1.26.0", + "version": "v1.27.0", "source": { "type": "git", "url": "https://github.com/laravel/pint.git", - "reference": "69dcca060ecb15e4b564af63d1f642c81a241d6f" + "reference": "c67b4195b75491e4dfc6b00b1c78b68d86f54c90" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/pint/zipball/69dcca060ecb15e4b564af63d1f642c81a241d6f", - "reference": "69dcca060ecb15e4b564af63d1f642c81a241d6f", + "url": "https://api.github.com/repos/laravel/pint/zipball/c67b4195b75491e4dfc6b00b1c78b68d86f54c90", + "reference": "c67b4195b75491e4dfc6b00b1c78b68d86f54c90", "shasum": "" }, "require": { @@ -8555,9 +8555,9 @@ "php": "^8.2.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^3.90.0", - "illuminate/view": "^12.40.1", - "larastan/larastan": "^3.8.0", + "friendsofphp/php-cs-fixer": "^3.92.4", + "illuminate/view": "^12.44.0", + "larastan/larastan": "^3.8.1", "laravel-zero/framework": "^12.0.4", "mockery/mockery": "^1.6.12", "nunomaduro/termwind": "^2.3.3", @@ -8598,7 +8598,7 @@ "issues": "https://github.com/laravel/pint/issues", "source": "https://github.com/laravel/pint" }, - "time": "2025-11-25T21:15:52+00:00" + "time": "2026-01-05T16:49:17+00:00" }, { "name": "laravel/roster", @@ -8663,16 +8663,16 @@ }, { "name": "laravel/sail", - "version": "v1.51.0", + "version": "v1.52.0", "source": { "type": "git", "url": "https://github.com/laravel/sail.git", - "reference": "1c74357df034e869250b4365dd445c9f6ba5d068" + "reference": "64ac7d8abb2dbcf2b76e61289451bae79066b0b3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/sail/zipball/1c74357df034e869250b4365dd445c9f6ba5d068", - "reference": "1c74357df034e869250b4365dd445c9f6ba5d068", + "url": "https://api.github.com/repos/laravel/sail/zipball/64ac7d8abb2dbcf2b76e61289451bae79066b0b3", + "reference": "64ac7d8abb2dbcf2b76e61289451bae79066b0b3", "shasum": "" }, "require": { @@ -8722,7 +8722,7 @@ "issues": "https://github.com/laravel/sail/issues", "source": "https://github.com/laravel/sail" }, - "time": "2025-12-09T13:33:49+00:00" + "time": "2026-01-01T02:46:03+00:00" }, { "name": "mockery/mockery", @@ -8968,16 +8968,16 @@ }, { "name": "pestphp/pest", - "version": "v4.3.0", + "version": "v4.3.1", "source": { "type": "git", "url": "https://github.com/pestphp/pest.git", - "reference": "e86bec3e68f1874c112ca782fb9db1333f3fe7ab" + "reference": "bc57a84e77afd4544ff9643a6858f68d05aeab96" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pestphp/pest/zipball/e86bec3e68f1874c112ca782fb9db1333f3fe7ab", - "reference": "e86bec3e68f1874c112ca782fb9db1333f3fe7ab", + "url": "https://api.github.com/repos/pestphp/pest/zipball/bc57a84e77afd4544ff9643a6858f68d05aeab96", + "reference": "bc57a84e77afd4544ff9643a6858f68d05aeab96", "shasum": "" }, "require": { @@ -8990,7 +8990,7 @@ "pestphp/pest-plugin-profanity": "^4.2.1", "php": "^8.3.0", "phpunit/phpunit": "^12.5.4", - "symfony/process": "^7.4.0|^8.0.0" + "symfony/process": "^7.4.3|^8.0.0" }, "conflict": { "filp/whoops": "<2.18.3", @@ -9068,7 +9068,7 @@ ], "support": { "issues": "https://github.com/pestphp/pest/issues", - "source": "https://github.com/pestphp/pest/tree/v4.3.0" + "source": "https://github.com/pestphp/pest/tree/v4.3.1" }, "funding": [ { @@ -9080,7 +9080,7 @@ "type": "github" } ], - "time": "2025-12-30T19:48:33+00:00" + "time": "2026-01-04T16:29:59+00:00" }, { "name": "pestphp/pest-plugin", @@ -11114,7 +11114,7 @@ "prefer-stable": true, "prefer-lowest": false, "platform": { - "php": "^8.2" + "php": "^8.4" }, "platform-dev": {}, "plugin-api-version": "2.9.0" diff --git a/database/data/ivnbg-categories.csv b/database/data/ivnbg-categories.csv new file mode 100644 index 0000000..2de141f --- /dev/null +++ b/database/data/ivnbg-categories.csv @@ -0,0 +1,23 @@ +title,excerpt,slug +Accomodation,Find perfect places to stay.,accomodation +Attractions,Experience must-see attractions.,attractions +Bridges,Walk across stunning and historic bridges.,bridges +Buildings,Discover architectural landmarks.,buildings +Castles,Explore historic castles.,castles +Churches & Religious,Explore historic churches and religious sites.,churches +Culture & Art,Explore cultural and artistic landmarks.,culture +Districts,Explore Nuremberg districts.,districts +Entertainment & Sport,Enjoy fun activities and sports events.,entertainment +Events,Notable events hosted in Nuremberg.,events +Food & Drink,Indulge in delicious food and drinks.,food +Landmarks,Visit iconic landmarks and monuments.,landmarks +Museums,Explore historical and cultural museums.,museums +Nature & Outdoor,Discover nature and outdoor adventures.,nature +Parks & Gardens,Relax in beautiful parks and gardens.,parks +Places & Streets,Discover charming places and streets.,places +Shopping & Markets,Enjoy shopping at local markets and stores.,shopping +Statues & Fountains,Admire statues and iconic fountains.,statues +Surroundings,Discover the scenic surroundings.,surroundings +Towers,Visit historic and modern towers.,towers +Transportation,Explore various transport hubs and systems.,transportation +Waters & Rivers,Explore serene waters and rivers.,waters \ No newline at end of file diff --git a/database/factories/CategoryFactory.php b/database/factories/CategoryFactory.php new file mode 100644 index 0000000..6685fa8 --- /dev/null +++ b/database/factories/CategoryFactory.php @@ -0,0 +1,87 @@ + + */ +class CategoryFactory extends Factory +{ + /** + * The name of the factory's corresponding model. + * + * @var string + */ + protected $model = Category::class; + + /** + * Define the model's default state. + * + * @return array + */ + public function definition(): array + { + $projectId = Project::where('slug', AppProject::LaravelCore->value)->first()->id; + return [ + 'uuid' => $this->faker->unique()->uuid(), + + // Constraint Note: Input requested specific ID '6' for mockup. + // Standard practice: Project::factory() + 'project_id' => $projectId, + + // Self-referencing relation. Default to null to avoid infinite recursion loops. + // You can use ->state() methods to create children specifically. + 'parent_id' => null, + + 'status' => $this->faker->randomElement(array_column(ContentStatus::cases(), 'value')), + + 'visibility' => $this->faker->randomElement(array_column(ContentVisibility::cases(), 'value')), + + // Constraint Note: Input requested 'post' for mockup. + 'content_type' => $this->faker->randomElement(array_column(ContentContentType::cases(), 'value')), + + 'position' => $this->faker->numberBetween(0, 100), + + // Unique constraint on [project_id, slug, lang]. + // Since project_id is static (6), slug must be unique. + 'slug' => $this->faker->unique()->slug(), + + 'lang' => $this->faker->randomElement(array_column(Language::cases(), 'value')), + 'title' => $this->faker->sentence(4), // Generates a realistic title + + // Nullable logic: 80% chance of text, 20% chance of null + 'excerpt' => $this->faker->boolean(80) ? $this->faker->paragraph(2) : null, + + // Nullable logic: 50% chance of metadata + 'metadata' => $this->faker->boolean(50) ? [ + 'keywords' => $this->faker->words(3), + 'author' => $this->faker->name(), + 'color' => $this->faker->hexColor() + ] : null, + + 'created_at' => $this->faker->dateTimeBetween('-1 year', 'now'), + 'updated_at' => $this->faker->dateTimeBetween('-1 year', 'now'), + 'deleted_at' => null, // Soft deletes are null by default + ]; + } + + /** + * Indicate that the category is a child of another category. + */ + public function child(): static + { + return $this->state(fn (array $attributes) => [ + 'parent_id' => Category::factory(), + ]); + } +} \ No newline at end of file diff --git a/database/factories/ContentFactory.php b/database/factories/ContentFactory.php new file mode 100644 index 0000000..457485d --- /dev/null +++ b/database/factories/ContentFactory.php @@ -0,0 +1,51 @@ +faker->unique()->sentence(6, true); + $projectId = Project::where('slug', AppProject::LaravelCore->value)->first()->id; + return [ + 'uuid' => $this->faker->uuid(), + // Use lazy() or closures so these only execute if no value is provided + 'project_id' => $projectId, + 'user_id' => 1, + 'author_id' => $this->faker->boolean(80) ? 1 : null, + + 'parent_id' => $this->faker->boolean(20) ? 1: null, + + 'content_type' => $this->faker->randomElement(array_column(ContentContentType::cases(), 'value')), + 'status' => $this->faker->randomElement(array_column(ContentStatus::cases(), 'value')), + 'visibility' => $this->faker->randomElement(array_column(ContentVisibility::cases(), 'value')), + 'lang' => $this->faker->randomElement(array_column(Language::cases(), 'value')), + + 'title' => $title, + 'slug' => Str::slug($title), + 'subtitle' => $this->faker->boolean(60) ? $this->faker->sentence(8, true) : null, + 'excerpt' => $this->faker->boolean(80) ? $this->faker->paragraph() : null, + 'content' => $this->faker->boolean(90) ? $this->faker->paragraphs($this->faker->numberBetween(3, 8), true) : null, + 'metadata' => $this->faker->boolean(30) ? json_encode(['ref' => $this->faker->uuid, 'featured_image' => $this->faker->imageUrl()]) : null, + 'position' => $this->faker->numberBetween(0, 20), + 'is_featured' => $this->faker->boolean(10), + 'published_at' => $this->faker->boolean(70) ? $this->faker->dateTimeBetween('-2 years', 'now') : null, + ]; + } +} \ No newline at end of file diff --git a/database/factories/InquiryFactory.php b/database/factories/InquiryFactory.php new file mode 100644 index 0000000..62a0221 --- /dev/null +++ b/database/factories/InquiryFactory.php @@ -0,0 +1,41 @@ + + */ +class InquiryFactory extends Factory +{ + protected $model = Inquiry::class; + + /** + * @return array + */ + public function definition(): array + { + $projectId = Project::where('slug', AppProject::LaravelCore->value)->first()->id; + return [ + 'project_id' =>$projectId, + 'user_id' => $this->faker->boolean(80) ? 1 : null, + 'is_read' => $this->faker->boolean(), + 'is_spam' => $this->faker->boolean(10), + 'is_archived' => $this->faker->boolean(10), + 'name' => $this->faker->name(), + 'email' => $this->faker->unique()->safeEmail(), + 'subject' => $this->faker->boolean(85) ? $this->faker->sentence(6, true) : null, + 'message' => $this->faker->paragraphs($this->faker->numberBetween(1, 3), true), + 'ip_address' => $this->faker->boolean(90) ? $this->faker->ipv4() : null, + 'user_agent' => $this->faker->boolean(90) ? $this->faker->userAgent() : null, + 'terms_accepted_at' => $this->faker->boolean(95) ? $this->faker->dateTimeBetween('-2 years', 'now') : null, + 'metadata' => $this->faker->boolean(20) ? json_encode(['referrer' => $this->faker->url()]) : null, + // ...timestamps and softDeletes handled by Eloquent... + ]; + } +} \ No newline at end of file diff --git a/database/factories/ProjectFactory.php b/database/factories/ProjectFactory.php new file mode 100644 index 0000000..21657b6 --- /dev/null +++ b/database/factories/ProjectFactory.php @@ -0,0 +1,54 @@ + + */ +class ProjectFactory extends Factory +{ + /** + * The name of the factory's corresponding model. + * + * @var string + */ + protected $model = Project::class; + + /** + * Define the model's default state. + * + * @return array + */ + public function definition(): array + { + return [ + // Unique slug (e.g., "project-alpha" or "cool-startup") + 'slug' => $this->faker->unique()->slug(2), + + // Nullable excerpt: 80% chance of text, 20% chance of null + 'excerpt' => $this->faker->boolean(80) + ? $this->faker->paragraph(2) + : null, + + // Nullable JSON metadata: 70% chance of data + 'metadata' => $this->faker->boolean(70) ? [ + 'website' => $this->faker->url(), + 'client' => $this->faker->company(), + 'version' => $this->faker->semver(), + 'tags' => $this->faker->words(3), + ] : null, + + // Standard timestamps are handled automatically, + // but we can randomize creation time if desired + 'created_at' => $this->faker->dateTimeBetween('-1 year', 'now'), + 'updated_at' => $this->faker->dateTimeBetween('-1 year', 'now'), + + // Soft deletes default to null (active record) + 'deleted_at' => null, + ]; + } +} diff --git a/database/factories/TagFactory.php b/database/factories/TagFactory.php new file mode 100644 index 0000000..eb5a3a9 --- /dev/null +++ b/database/factories/TagFactory.php @@ -0,0 +1,34 @@ + + */ +class TagFactory extends Factory +{ + protected $model = Tag::class; + + /** + * @return array + */ + public function definition(): array + { + $projectId = Project::where('slug', AppProject::LaravelCore->value)->first()->id; + return [ + 'project_id' => $projectId, + 'content_type' => $this->faker->randomElement(array_column(ContentContentType::cases(), 'value')), + 'lang' => $this->faker->randomElement(array_column(Language::cases(), 'value')), + 'name' => $this->faker->unique()->words(2, true), + 'created_at' => $this->faker->dateTimeBetween('-1 year', 'now'), + 'updated_at' => $this->faker->dateTimeBetween('-1 year', 'now'), + ]; + } +} \ No newline at end of file diff --git a/database/factories/UserFactory.php b/database/factories/UserFactory.php index 07af023..7ce8fc1 100644 --- a/database/factories/UserFactory.php +++ b/database/factories/UserFactory.php @@ -1,7 +1,11 @@ value)->first()->id; return [ + 'uuid' => $this->faker->unique()->uuid(), 'name' => fake()->name(), 'email' => fake()->unique()->safeEmail(), 'email_verified_at' => now(), 'password' => static::$password ??= Hash::make('password'), 'remember_token' => Str::random(10), - 'two_factor_secret' => Str::random(10), - 'two_factor_recovery_codes' => Str::random(10), - 'two_factor_confirmed_at' => now(), + + // --- New Schema Fields --- + + // Automatically create a project if one isn't passed in + 'project_id' =>$projectId, + + // Match your 'role' default ('user') but allow randomness + 'role' => fake()->randomElement(['user', 'admin', 'editor']), + + // Match your 'account_type' default ('free') but allow randomness + 'account_type' => fake()->randomElement(['free', 'pro', 'enterprise']), + + // Nullable JSON metadata + 'metadata' => fake()->boolean(70) ? [ + 'theme' => fake()->randomElement(['light', 'dark']), + 'notifications' => fake()->boolean(), + 'last_login_ip' => fake()->ipv4(), + ] : null, + + // Standard timestamps + 'created_at' => now(), + 'updated_at' => now(), ]; } @@ -44,16 +76,4 @@ public function unverified(): static 'email_verified_at' => null, ]); } - - /** - * Indicate that the model does not have two-factor authentication configured. - */ - public function withoutTwoFactor(): static - { - return $this->state(fn (array $attributes) => [ - 'two_factor_secret' => null, - 'two_factor_recovery_codes' => null, - 'two_factor_confirmed_at' => null, - ]); - } -} +} \ No newline at end of file diff --git a/database/migrations/2026_01_05_184613_add_project_id_to_users_table.php b/database/migrations/2026_01_05_184613_add_project_id_to_users_table.php index b4815a3..666080d 100644 --- a/database/migrations/2026_01_05_184613_add_project_id_to_users_table.php +++ b/database/migrations/2026_01_05_184613_add_project_id_to_users_table.php @@ -9,6 +9,7 @@ public function up(): void { Schema::table('users', function (Blueprint $table) { + $table->uuid('uuid')->after('id')->unique(); // We use 'after' to position columns logically, though not strictly required by SQL $table->foreignId('project_id') //->nullable() // Nullable initially to handle existing users, remove if fresh DB diff --git a/database/migrations/2026_01_05_185832_create_tags_table.php b/database/migrations/2026_01_05_185832_create_tags_table.php index b4db1c3..a80ef0a 100644 --- a/database/migrations/2026_01_05_185832_create_tags_table.php +++ b/database/migrations/2026_01_05_185832_create_tags_table.php @@ -14,8 +14,7 @@ public function up(): void $table->string('content_type', 20); $table->string('lang', 10)->default('en'); - $table->unsignedBigInteger('views_count')->default(0); - $table->string('name', 255); + $table->string('name', 255); $table->timestamps(); $table->softDeletes(); @@ -28,4 +27,4 @@ public function down(): void { Schema::dropIfExists('tags'); } -}; +}; \ No newline at end of file diff --git a/database/seeders/CategoryContentSeeder.php b/database/seeders/CategoryContentSeeder.php new file mode 100644 index 0000000..7dc6803 --- /dev/null +++ b/database/seeders/CategoryContentSeeder.php @@ -0,0 +1,33 @@ +get(); + $contents = Content::withoutGlobalScopes()->get(); + + // 2. Quick check to see if we actually have data to work with + if ($categories->isEmpty() || $contents->isEmpty()) { + $this->command->warn("Seeding skipped: Ensure 'categories' and 'contents' tables have data first."); + return; + } + + // 3. Attach relationships + $categories->each(function ($category) use ($contents) { + // Pick a random number of items to attach (e.g., between 1 and 3) + $randomContents = $contents->random(min(rand(1, 3), $contents->count())); + + $category->contents()->attach($randomContents->pluck('id')); + }); + + $this->command->info("Successfully linked categories and content."); + } +} \ No newline at end of file diff --git a/database/seeders/CategorySeeder.php b/database/seeders/CategorySeeder.php new file mode 100644 index 0000000..b049546 --- /dev/null +++ b/database/seeders/CategorySeeder.php @@ -0,0 +1,33 @@ +value)->first()->id; + + Category::factory()->count(10)->create([ + 'project_id' => $projectId, + 'content_type' => ContentContentType::Article->value, + 'status' =>ContentStatus::Published->value, + 'visibility' =>ContentVisibility::Public->value, + 'lang' => Language::EN->value, + ]); + } +} \ No newline at end of file diff --git a/database/seeders/CategorySeederProject.php b/database/seeders/CategorySeederProject.php new file mode 100644 index 0000000..10f19b6 --- /dev/null +++ b/database/seeders/CategorySeederProject.php @@ -0,0 +1,44 @@ +first()->id; + $this->storeData('data/ivnbg-categories.csv', $ivnbgProjectId,'place'); + } + + private function storeData(string $filePath, int $projectId, string $contentType): void + { + $csvPath = database_path($filePath); + $rows = array_map('str_getcsv', file($csvPath)); + $header = array_map('trim', array_shift($rows)); + + foreach ($rows as $row) { + $data = array_combine($header, $row); + + // Set required fields not present in CSV + $data['uuid'] = (string) Str::uuid(); + $data['project_id'] = $projectId; + $data['content_type'] = $contentType; + $data['status'] = 'published'; + $data['visibility'] = 'public'; + $data['lang'] = 'en'; + + + Category::create($data); + } + } +} \ No newline at end of file diff --git a/database/seeders/ContentSeeder.php b/database/seeders/ContentSeeder.php new file mode 100644 index 0000000..3794257 --- /dev/null +++ b/database/seeders/ContentSeeder.php @@ -0,0 +1,28 @@ +where('slug', AppProject::LaravelCore->value)->value('id'); + + Content::factory()->count(50)->create([ + 'project_id' => $projectId, + 'content_type' => ContentContentType::Article->value, + 'status' =>ContentStatus::Published->value, + 'visibility' =>ContentVisibility::Public->value, + 'lang' => Language::EN->value, + ]); + } +} \ No newline at end of file diff --git a/database/seeders/ContentTagSeeder.php b/database/seeders/ContentTagSeeder.php new file mode 100644 index 0000000..89e6015 --- /dev/null +++ b/database/seeders/ContentTagSeeder.php @@ -0,0 +1,31 @@ +get(); + $tags = Tag::withoutGlobalScopes()->get(); + + if ($contents->isEmpty() || $tags->isEmpty()) { + $this->command->warn("Seeding skipped: Ensure 'contents' and 'tags' tables have data."); + return; + } + + // Loop through contents and attach 1-5 random tags to each + $contents->each(function ($content) use ($tags) { + $randomTags = $tags->random(min(rand(1, 5), $tags->count())); + + $content->tags()->attach($randomTags->pluck('id')); + }); + + $this->command->info("Successfully attached tags to content."); + } +} \ No newline at end of file diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index 1fb527e..24cd6a4 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -2,10 +2,7 @@ namespace Database\Seeders; -use App\Models\Project; -use App\Models\User; use Illuminate\Database\Seeder; -use Illuminate\Support\Facades\Hash; class DatabaseSeeder extends Seeder { @@ -14,60 +11,24 @@ class DatabaseSeeder extends Seeder */ public function run(): void { - // 1. Define the projects data - $projects = [ - [ - 'slug' => 'ivnbg', - 'excerpt' => 'ivnbg.com project', - 'metadata' => ['url' => 'www.ivnbg.com'], - ], - [ - 'slug' => 'martinvach', - 'excerpt' => 'martinvach.com project', - 'metadata' => ['url' => 'www.martinvach.com'], - ], - [ - 'slug' => 'myprompties', - 'excerpt' => 'myprompties.com project', - 'metadata' => ['url' => 'www.myprompties.com'], - ], - [ - 'slug' => 'vades', - 'excerpt' => 'vades.dev project', - 'metadata' => ['url' => 'www.vades.dev'], - ], - [ - 'slug' => 'aitomatix', - 'excerpt' => 'aitomatix.com project', - 'metadata' => ['url' => 'www.aitomatix.com'], - ], - [ - 'slug' => 'laravel-core', - 'excerpt' => 'laravel-core.test project. Only for local testing purposes.', - 'metadata' => null, - ], - ]; - // 2. Loop and use firstOrCreate for each project - foreach ($projects as $projectData) { - Project::firstOrCreate( - ['slug' => $projectData['slug']], // Search key (Unique) - [ - 'excerpt' => $projectData['excerpt'], - 'metadata' => $projectData['metadata'] ?? null, - ] - ); - } + $this->call([ + ProjectSeeder::class, + UserSeeder::class, + CategorySeederProject::class, + ]); + + if (app()->environment('local')) { + $this->call([ + CategorySeeder::class, + TagSeeder::class, + InquirySeeder::class, + ContentSeeder::class, + CategoryContentSeeder::class, + ContentTagSeeder::class, - // 3. Create the Test User - User::firstOrCreate( - ['email' => 'test@example.com'], // Search key (Unique) - [ - 'name' => 'Test User', - 'project_id' => Project::where('slug', 'laravel-core.test')->first()->id, - 'password' => Hash::make('password'), - 'email_verified_at' => now(), - ] - ); + ]); + + } } -} +} \ No newline at end of file diff --git a/database/seeders/InquirySeeder.php b/database/seeders/InquirySeeder.php new file mode 100644 index 0000000..dd02adc --- /dev/null +++ b/database/seeders/InquirySeeder.php @@ -0,0 +1,20 @@ +value)->first()->id; + + Inquiry::factory()->count(50)->create([ + 'project_id' => $projectId, + ]); + } +} \ No newline at end of file diff --git a/database/seeders/ProjectSeeder.php b/database/seeders/ProjectSeeder.php new file mode 100644 index 0000000..d3b24c7 --- /dev/null +++ b/database/seeders/ProjectSeeder.php @@ -0,0 +1,63 @@ +AppProject::Ivnbg->value, + 'excerpt' => 'ivnbg.com project', + 'metadata' => ['url' => 'www.ivnbg.com'], + ], + [ + 'slug' => 'Project::MartinVach->value', + 'excerpt' => 'martinvach.com project', + 'metadata' => ['url' => 'www.martinvach.com'], + ], + [ + 'slug' => AppProject::MyPrompties->value, + 'excerpt' => 'myprompties.com project', + 'metadata' => ['url' => 'www.myprompties.com'], + ], + [ + 'slug' => AppProject::MyPrompties->value, + 'excerpt' => 'vades.dev project', + 'metadata' => ['url' => 'www.vades.dev'], + ], + [ + 'slug' => AppProject::Aitomatix->value, + 'excerpt' => 'aitomatix.com project', + 'metadata' => ['url' => 'www.aitomatix.com'], + ], + [ + 'slug' => AppProject::LaravelCore->value, + 'excerpt' => 'laravel-core.test project. Only for local testing purposes.', + 'metadata' => null, + ], + ]; + + foreach ($projects as &$project) { + if (is_array($project['metadata']) || is_object($project['metadata'])) { + $project['metadata'] = json_encode($project['metadata']); + } + } + unset($project); + + Project::upsert( + $projects, + ['slug'], + ['excerpt', 'metadata'] + ); + } +} \ No newline at end of file diff --git a/database/seeders/TagSeeder.php b/database/seeders/TagSeeder.php new file mode 100644 index 0000000..0933eb1 --- /dev/null +++ b/database/seeders/TagSeeder.php @@ -0,0 +1,23 @@ +value)->first()->id; + Tag::factory()->count(50)->create([ + 'project_id' => $projectId, + 'content_type' => ContentContentType::Article->value, + 'lang' => Language::EN->value, + ]); + } +} \ No newline at end of file diff --git a/database/seeders/UserSeeder.php b/database/seeders/UserSeeder.php new file mode 100644 index 0000000..793503f --- /dev/null +++ b/database/seeders/UserSeeder.php @@ -0,0 +1,40 @@ + 'test@example.com'], // Search Key + [ + 'uuid' => Str::uuid()->toString(), + 'name' => 'Test User', + 'password' => Hash::make('password'), + 'email_verified_at' => now(), + + // Specific fields for your login testing + // In database/factories/UserFactory.php + 'project_id' => Project::where('slug', AppProject::LaravelCore->value)->first()->id, + 'role' =>UserRole::User->value, // Override random factory default + 'account_type' => 'pro', // Override random factory default + 'metadata' => ['is_super_admin' => true], + ] + ); + } +} \ No newline at end of file From 971bd24e10e6bdb6dd103884a16dc7ed21f60b0f Mon Sep 17 00:00:00 2001 From: Martin Vach Date: Wed, 28 Jan 2026 16:05:56 +0100 Subject: [PATCH 004/103] Merge pull request #9 * #8: Removing unused extensions * #8: Updating content model * #8: Adding ContentAnalytic model * #8: Creating Data * #8: Creating ProjectContentService * #8: Saving content * #8: Implementing content import * #8: Implementing content import * #8: Implementing content import * #8: Finallyzing content import --- app/Actions/Fortify/CreateNewUser.php | 39 - .../Fortify/PasswordValidationRules.php | 18 - app/Actions/Fortify/ResetUserPassword.php | 28 - app/Console/Commands/ImportProjectContent.php | 57 + app/Data/CategoryData.php | 46 + app/Data/ContentAnalytic.php | 33 + app/Data/ContentData.php | 59 + app/Data/InquiryData.php | 45 + app/Data/TagData.php | 28 + app/Livewire/Actions/Logout.php | 22 - app/Models/Category.php | 24 + app/Models/Content.php | 129 + app/Models/ContentAnalytic.php | 53 + app/Models/Tag.php | 4 + app/Services/DomainManagerService.php | 47 +- app/Services/Import/ProjectContentService.php | 313 + .../Import/ProjectContentService_bck.php | 276 + app/Services/Import/ProjectPostService.php | 241 + app/Traits/HasUuid.php | 16 + app/Traits/ImportProjectTrait.php | 151 + composer.json | 2 - composer.lock | 11121 ---------------- config/fortify.php | 159 - database/data/vades-article-categories.csv | 2 + database/seeders/CategorySeederProject.php | 7 +- database/seeders/ProjectSeeder.php | 4 +- 26 files changed, 1523 insertions(+), 11401 deletions(-) delete mode 100644 app/Actions/Fortify/CreateNewUser.php delete mode 100644 app/Actions/Fortify/PasswordValidationRules.php delete mode 100644 app/Actions/Fortify/ResetUserPassword.php create mode 100644 app/Console/Commands/ImportProjectContent.php create mode 100644 app/Data/CategoryData.php create mode 100644 app/Data/ContentAnalytic.php create mode 100644 app/Data/ContentData.php create mode 100644 app/Data/InquiryData.php create mode 100644 app/Data/TagData.php delete mode 100644 app/Livewire/Actions/Logout.php create mode 100644 app/Models/ContentAnalytic.php create mode 100644 app/Services/Import/ProjectContentService.php create mode 100644 app/Services/Import/ProjectContentService_bck.php create mode 100644 app/Services/Import/ProjectPostService.php create mode 100644 app/Traits/HasUuid.php create mode 100644 app/Traits/ImportProjectTrait.php delete mode 100644 composer.lock delete mode 100644 config/fortify.php create mode 100644 database/data/vades-article-categories.csv diff --git a/app/Actions/Fortify/CreateNewUser.php b/app/Actions/Fortify/CreateNewUser.php deleted file mode 100644 index aebff5e..0000000 --- a/app/Actions/Fortify/CreateNewUser.php +++ /dev/null @@ -1,39 +0,0 @@ - $input - */ - public function create(array $input): User - { - Validator::make($input, [ - 'name' => ['required', 'string', 'max:255'], - 'email' => [ - 'required', - 'string', - 'email', - 'max:255', - Rule::unique(User::class), - ], - 'password' => $this->passwordRules(), - ])->validate(); - - return User::create([ - 'name' => $input['name'], - 'email' => $input['email'], - 'password' => $input['password'], - ]); - } -} diff --git a/app/Actions/Fortify/PasswordValidationRules.php b/app/Actions/Fortify/PasswordValidationRules.php deleted file mode 100644 index 76b19d3..0000000 --- a/app/Actions/Fortify/PasswordValidationRules.php +++ /dev/null @@ -1,18 +0,0 @@ -|string> - */ - protected function passwordRules(): array - { - return ['required', 'string', Password::default(), 'confirmed']; - } -} diff --git a/app/Actions/Fortify/ResetUserPassword.php b/app/Actions/Fortify/ResetUserPassword.php deleted file mode 100644 index 688d62f..0000000 --- a/app/Actions/Fortify/ResetUserPassword.php +++ /dev/null @@ -1,28 +0,0 @@ - $input - */ - public function reset(User $user, array $input): void - { - Validator::make($input, [ - 'password' => $this->passwordRules(), - ])->validate(); - - $user->forceFill([ - 'password' => $input['password'], - ])->save(); - } -} diff --git a/app/Console/Commands/ImportProjectContent.php b/app/Console/Commands/ImportProjectContent.php new file mode 100644 index 0000000..2b9fa3e --- /dev/null +++ b/app/Console/Commands/ImportProjectContent.php @@ -0,0 +1,57 @@ +info('Starting project content import...'); + $this->newLine(); + + // Run the import logic + $service->handle(); + + // Output Successes + if (count($service->getSuccess()) > 0) { + $this->info('Successfully imported:'); + foreach ($service->getSuccess() as $message) { + $this->line("- OK: {$message}"); + } + } + + $this->newLine(); + + // Output Errors + if (count($service->getErrors()) > 0) { + $this->error('Errors encountered during import:'); + foreach ($service->getErrors() as $error) { + $this->line("- FAIL: {$error}"); + } + } + + $this->newLine(); + $this->info('Import process completed.'); + + return Command::SUCCESS; + } +} \ No newline at end of file diff --git a/app/Data/CategoryData.php b/app/Data/CategoryData.php new file mode 100644 index 0000000..511c473 --- /dev/null +++ b/app/Data/CategoryData.php @@ -0,0 +1,46 @@ +logout(); - - Session::invalidate(); - Session::regenerateToken(); - - return redirect('/'); - } -} diff --git a/app/Models/Category.php b/app/Models/Category.php index 74604fe..362758d 100644 --- a/app/Models/Category.php +++ b/app/Models/Category.php @@ -2,11 +2,17 @@ namespace App\Models; +use App\Enums\ContentContentType; +use App\Enums\ContentStatus; +use App\Enums\ContentVisibility; +use App\Enums\Language; use App\Traits\FilterByProject; +use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\SoftDeletes; +use Spatie\Sluggable\SlugOptions; /** * App\Models\Category @@ -61,6 +67,10 @@ class Category extends Model * @var array */ protected $casts = [ + 'status' => ContentStatus::class, + 'content_type' => ContentContentType::class, + 'visibility' => ContentVisibility::class, + 'lang' => Language::class, 'metadata' => 'array', 'position' => 'integer', ]; @@ -85,4 +95,18 @@ public function contents() { return $this->belongsToMany(Content::class); } + + public function scopePublishedByType(Builder $query, string|ContentContentType $contentType =ContentContentType::Article->value): void + { + $value = $contentType instanceof ContentContentType ? $contentType->value : $contentType; + $query->where('status', ContentStatus::Published->value) + ->where('content_type',$value); + } + public function getSlugOptions() : SlugOptions + { + return SlugOptions::create() + ->generateSlugsFrom('slug') + ->saveSlugsTo('slug') + ->doNotGenerateSlugsOnUpdate(); + } } \ No newline at end of file diff --git a/app/Models/Content.php b/app/Models/Content.php index 44ecb7b..c3f7098 100644 --- a/app/Models/Content.php +++ b/app/Models/Content.php @@ -2,11 +2,19 @@ namespace App\Models; +use App\Enums\ContentContentType; +use App\Enums\ContentStatus; +use App\Enums\ContentVisibility; +use App\Enums\Language; use App\Traits\FilterByProject; +use Illuminate\Database\Eloquent\Builder; +use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\SoftDeletes; +use Illuminate\Http\Request; +use Spatie\Sluggable\SlugOptions; /** * App\Models\Content @@ -52,6 +60,10 @@ class Content extends Model */ protected $fillable = [ 'uuid', + 'project_id', + 'user_id', + 'author_id', + 'parent_id', 'content_type', 'status', 'visibility', @@ -65,6 +77,7 @@ class Content extends Model 'position', 'is_featured', 'published_at', + ]; /** @@ -73,6 +86,10 @@ class Content extends Model * @var array */ protected $casts = [ + 'status' => ContentStatus::class, + 'content_type' => ContentContentType::class, + 'visibility' => ContentVisibility::class, + 'lang' => Language::class, 'metadata' => 'array', 'is_featured' => 'boolean', 'position' => 'integer', @@ -120,4 +137,116 @@ public function tags() { return $this->belongsToMany(Tag::class,'content_tag'); } + + public function getSlugOptions() : SlugOptions + { + return SlugOptions::create() + ->generateSlugsFrom('slug') + ->saveSlugsTo('slug') + ->doNotGenerateSlugsOnUpdate(); + } + /** + * Get the featured image URL from metadata. + */ + protected function imageUrl(): Attribute + { + return Attribute::make( + get: fn () => $this->metadata['featuredImage'] ?? null, + ); + } + + /** + * Get the address from metadata. + */ + protected function address(): Attribute + { + return Attribute::make( + get: fn () => $this->metadata['address'] ?? null, + ); + } + + /** + * Get the Google Map Embed URL from metadata. + */ + protected function googleMapEmbedUrl(): Attribute + { + return Attribute::make( + get: fn () => $this->metadata['googleMapEmbedUrl'] ?? null, + ); + } + + /** + * Get the Meta Title from metadata. + */ + protected function metaTitle(): Attribute + { + return Attribute::make( + get: fn () => $this->metadata['metaTitle'] ?? null, + ); + } + + /** + * Get the Meta Description from metadata. + */ + protected function metaDescription(): Attribute + { + return Attribute::make( + get: fn () => $this->metadata['metaDescription'] ?? null, + ); + } + + public function scopePublished(Builder $query): void + { + $query->where('status', ContentStatus::Published->value); + } + + public function scopePublishedByType(Builder $query, string|ContentContentType $contentType = ContentContentType::Article->value): + void + { + $value = $contentType instanceof ContentContentType ? $contentType->value : $contentType; + $query->where('status', ContentStatus::Published->value) + ->where('content_type', $value) + ; + } + public function scopeIsFeatured(Builder $query): void + { + $query->where('is_featured', 1); + } + + public function scopeNotFeatured(Builder $query): void + { + $query->where('is_featured', 0); + } + + public function scopeFilter(Builder $query, Request $request): void + { + $query->when($request->filled('category'), function ($q) use ($request) { + $q->whereHas('categories', function ($q) use ($request) { + $q->where('slug', '=', $request->input('category')); + }); + }); + $query->when($request->filled('tag'), function ($q) use ($request) { + $q->whereHas('tags', function ($q) use ($request) { + $q->where('name', '=', $request->input('tag')); + }); + }); + } + + public function nextPublishedByType(string|ContentContentType $contentType =ContentContentType::Article->value) + { + $value = $contentType instanceof ContentContentType ? $contentType->value : $contentType; + return $this->publishedByType( $value) + ->where('id', '>', $this->id) + ->orderBy('id') + ->first(); + } + + public function previousPublishedByType(string|ContentContentType $contentType = ContentContentType::Article->value) + { + $value = $contentType instanceof ContentContentType ? $contentType->value : $contentType; + return $this->publishedByType($contentType) + ->where('id', '<', $this->id) + ->orderByDesc('id') + ->first(); + } } \ No newline at end of file diff --git a/app/Models/ContentAnalytic.php b/app/Models/ContentAnalytic.php new file mode 100644 index 0000000..176967a --- /dev/null +++ b/app/Models/ContentAnalytic.php @@ -0,0 +1,53 @@ + + */ + protected $fillable = [ + 'views', + 'unique_views', + 'downloads', + 'last_viewed_at', + 'metadata', + ]; + + /** + * @var array + */ + protected $casts = [ + 'views' => 'int', + 'unique_views' => 'int', + 'downloads' => 'int', + 'last_viewed_at' => 'datetime', + 'metadata' => 'array', + ]; + + /** + * Get the content that owns the analytic. + */ + public function content(): BelongsTo + { + return $this->belongsTo(Content::class); + } +} \ No newline at end of file diff --git a/app/Models/Tag.php b/app/Models/Tag.php index 574f11c..3e772fb 100644 --- a/app/Models/Tag.php +++ b/app/Models/Tag.php @@ -2,6 +2,7 @@ namespace App\Models; +use App\Enums\Language; use App\Traits\FilterByProject; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; @@ -37,11 +38,13 @@ class Tag extends Model */ protected $fillable = [ 'uuid', + 'content_type', 'is_published', 'tag_type', 'lang', 'views_count', 'name', + 'project_id', ]; /** @@ -50,6 +53,7 @@ class Tag extends Model * @var array */ protected $casts = [ + 'lang' => Language::class, 'is_published' => 'bool', 'views_count' => 'int', 'created_at' => 'datetime', diff --git a/app/Services/DomainManagerService.php b/app/Services/DomainManagerService.php index 0a9723b..226fc12 100644 --- a/app/Services/DomainManagerService.php +++ b/app/Services/DomainManagerService.php @@ -9,31 +9,53 @@ class DomainManagerService { - protected string $currentHost; - protected string $slug; + protected ?string $currentHost = null; + protected string $slug = 'default'; protected ?int $projectId = null; public function __construct(Request $request) { + // In CLI mode, getHost() might return 'localhost' or an empty string. $this->currentHost = $request->getHost(); + + // Initial detection $this->detectSlug(); $this->resolveProjectId(); } + /** + * Manually set the slug (e.g., from an Artisan command argument). + * This will automatically re-resolve the project ID. + */ + public function setSlug(string $slug): self + { + $this->slug = $slug; + $this->resolveProjectId(); + + return $this; + } + + /** + * Detect slug from host. + * Logic: ivnbg.com -> ivnbg, www.ivnbg.com -> ivnbg + */ protected function detectSlug(): void { - // 1. Remove www. - $host = Str::replace('www.', '', $this->currentHost); + if (empty($this->currentHost) || $this->currentHost === 'localhost') { + return; + } - // 2. Explode by dot and take the first part (ivnbg.com -> ivnbg) + $host = Str::replace('www.', '', $this->currentHost); $parts = explode('.', $host); $this->slug = $parts[0] ?? 'default'; } + /** + * Resolve the project ID based on the current slug. + */ protected function resolveProjectId(): void { - // Cache the lookup forever to avoid DB queries on every request. - // Run 'php artisan cache:clear' if you manually change IDs in DB. + // We use the slug as the cache key. $this->projectId = Cache::rememberForever("project_id_map_{$this->slug}", function () { return Project::where('slug', $this->slug)->value('id'); }); @@ -48,4 +70,13 @@ public function getProjectId(): ?int { return $this->projectId; } -} + + /** + * Allows manual override of the Project ID if needed. + */ + public function setProjectId(int $projectId): self + { + $this->projectId = $projectId; + return $this; + } +} \ No newline at end of file diff --git a/app/Services/Import/ProjectContentService.php b/app/Services/Import/ProjectContentService.php new file mode 100644 index 0000000..1963f61 --- /dev/null +++ b/app/Services/Import/ProjectContentService.php @@ -0,0 +1,313 @@ + content -> type). + * - Resolves Project IDs dynamically by using the folder name as a slug via the DomainManagerService. + * - Parses YAML Front Matter reliably using Spatie\YamlFrontMatter. + * - Uses DTOs for data integrity with automatic snake_case mapping to match your database columns. + * - Handles Mass Assignment safely by ensuring the Content model's $fillable array is correctly configured. + * - Captures Metadata that doesn't fit into standard columns into a JSON blob. + */ +class ProjectContentService +{ + private string $basePath; + private array $errors = []; + private array $success = []; + + public function getErrors(): array + { + return $this->errors; + } + + public function getSuccess(): array + { + return $this->success; + } + + public function __construct(protected DomainManagerService $domainManager) + { + $this->basePath = storage_path('app/imports/projects'); + } + + /** + * Main entry point to handle the import process. + */ + public function handle(): void + { + try { + if (!File::isDirectory($this->basePath)) { + throw new Exception("Import directory not found: {$this->basePath}"); + } + + $projectDirs = File::directories($this->basePath); + + foreach ($projectDirs as $projectPath) { + $projectName = basename($projectPath); + $this->processProject($projectName, $projectPath); + } + + $this->logSummary(); + } catch (Exception $e) { + Log::error("Import failed: " . $e->getMessage()); + } + } + + /** + * Process an individual project directory. + */ + private function processProject(string $projectName, string $projectPath): void + { + $contentPath = $projectPath . DIRECTORY_SEPARATOR . 'content'; + + if (!File::isDirectory($contentPath)) { + Log::warning("Project [{$projectName}] has no 'content' subdirectory. Skipping."); + return; + } + + // Get the project ID from config based on folder name + $this->domainManager->setSlug($projectName); + $projectId = $this->domainManager->getProjectId(); + + if (!$projectId) { + $this->errors[] = "Project configuration missing for: {$projectName}"; + return; + } + + $contentTypes = File::directories($contentPath); + + foreach ($contentTypes as $typePath) { + $contentTypeStr = basename($typePath); + $this->processContentType($projectId, $contentTypeStr, $typePath); + } + } + + /** + * Process subdirectories like 'articles', 'categories', 'tags'. + */ + private function processContentType(int $projectId, string $contentTypeStr, string $path): void + { + $files = File::files($path); + + foreach ($files as $file) { + if ($file->getExtension() !== 'md') { + continue; + } + + try { + $this->importFile($projectId, $contentTypeStr, $file->getPathname()); + } catch (Exception $e) { + $this->errors[] = "File error [{$file->getFilename()}]: " . $e->getMessage(); + } + } + } + + /** + * Parse the Markdown file and store it using the appropriate DTO. + */ + private function importFile(int $projectId, string $contentTypeStr, string $filePath): void + { + $fileContent = file_get_contents($filePath); + if ($fileContent === false) { + throw new Exception("Could not read file."); + } + + $object = YamlFrontMatter::parse($fileContent); + + // Basic validation: ensure we have at least a title or slug + if (!$object->matter('title') && !$object->matter('slug')) { + throw new Exception("Missing required YAML front matter (title or slug)."); + } + + $content = $this->handleContentImport($projectId, $contentTypeStr, $object); + if(!$content) { + return; + } + if($object->matter('tags')) { + $tagIds = $this->createTag($object->matter('tags'), $content); + if (count($tagIds) > 0) { + $content->tags()->sync($tagIds); + } + $categoryIds = $this->getCategories($object->matter('categories'), $content); + if (count($categoryIds) > 0) { + $content->categories()->sync($categoryIds); + } + } + } + + /** + * Handle generic content (articles, posts, etc.) + */ + private function handleContentImport(int $projectId, string $contentTypeStr, Document $object): ?Content + { + $content = null; + try { + // Map YAML to ContentData DTO + $data = [ + 'uuid' => $object->matter('uuid') ?? (string)Str::uuid(), + 'projectId' => $projectId, + 'userId' => $object->matter('user_id') ?? 1, + 'authorId' => $object->matter('author_id'), + 'parentId' => $this->getParentId($object->matter('parent_id'), $contentTypeStr), + 'contentType' => ContentContentType::tryFrom($contentTypeStr) ?? ContentContentType::Article->value, + 'status' => ContentStatus::tryFrom($object->matter('status') ?? '') + ?? ContentStatus::Draft, + + 'visibility' => ContentVisibility::tryFrom($object->matter('visibility') ?? '') + ?? ContentVisibility::Public, + + 'lang' => Language::tryFrom($object->matter('lang') ?? '') + ?? Language::EN, + 'slug' => $object->matter('slug') ?? Str::slug($object->matter('title')), + 'title' => (string)$object->matter('title'), + 'subtitle' => $object->matter('subtitle'), + 'excerpt' => $object->matter('description') ?? $object->matter('excerpt'), + 'content' => $object->body(), + 'metadata' => $this->extractMetadata($object, ['title', 'slug', 'description', 'is_published']), + 'position' => (int)($object->matter('position') ?? 0), + 'isFeatured' => (bool)($object->matter('is_featured') ?? false), + 'publishedAt' => $object->matter('published_at') ? Carbon::parse($object->matter('published_at')) : null, + ]; + $data['metadata'] = $this->extractMetadata($object, array_keys($data), ['categories', 'tags', 'parent']); + + + $dto = ContentData::from($data); + + $content = Content::updateOrCreate( + ['slug' => $dto->slug, 'project_id' => $dto->projectId], + $dto->toArray() + ); + //dd( $createdContent ); + $this->success[] = "Imported Content: {$dto->title}"; + } catch (Exception $e) { + $this->errors[] = "Content Save Error [{$object->matter('title')}]: " . $e->getMessage(); + } + return $content; + } + + private function getParentId(string|null $parentSlug, string $contentType): ?int + { + if (empty($parentSlug)) { + return null; + } + + // Safely get the ID. If first() returns null, ?->id is null. + // If the ID is found but is 0 (unlikely for IDs), ?? 0 handles it. + return Content::where('slug', $parentSlug) + ->publishedByType($contentType) + ->value('id'); + } + + private function getCategories(string $categories, Content $content):array { + $categorySlugs = array_map('trim', explode(',', $categories)); + $categoryIds= []; + foreach ($categorySlugs as $slug) { + try { + //dd($content->content_type); + $category = Category::where('slug', $slug)->publishedByType($content->content_type)->first(); + if (!$category) { + continue; + } + $this->success[] = 'Found category slug: ' . $slug . ' | content slug "'.$content->slug; + $categoryIds[] = $category->id; + } catch (Exception $e) { + $this->errors[] = "Category Save Error: " . $e->getMessage(); + continue; + } + + + } + return $categoryIds; + } + + private function createTag(string $tags, Content $content): array + { + $tagNames = array_map('trim', explode(',', $tags)); + $tagIds = []; + foreach ($tagNames as $tagName) { + try { + $dto = TagData::from([ + 'projectId' => $content->project_id, + 'contentType' => $content->content_type, + 'lang' => $content->lang->value, + 'name' => $tagName, + ]); + + $tag = Tag::updateOrCreate( + ['name' => $dto->name, 'project_id' => $dto->projectId], + $dto->toArray() + ); + + if ($tag) { + $tagIds[] = $tag->id; + } + + $this->success[] = "Imported Tag: {$dto->name}"; + } catch (Exception $e) { + $this->errors[] = "Tag Save Error: " . $e->getMessage(); + continue; + } + } + return $tagIds; + } + + /** + * Extracts metadata from YAML front matter. + * + * @param Document $object The parsed markdown document + * @param array $excludeKeys Keys already mapped to DTO/Database columns (e.g., 'title', 'slug') + * @param array $ignoreKeys Keys that should be completely discarded (e.g., 'internal_note', 'temp_id') + * @return array + */ + private function extractMetadata(Document $object, array $excludeKeys, array $ignoreKeys = []): array + { + return array_filter($object->matter(), function ($key) use ($excludeKeys, $ignoreKeys) { + // The key is kept ONLY if it is NOT in excludeKeys AND NOT in ignoreKeys + return !in_array($key, $excludeKeys) && !in_array($key, $ignoreKeys); + }, ARRAY_FILTER_USE_KEY); + } + + /** + * Log results of the import. + */ + private function logSummary(): void + { + foreach ($this->success as $msg) { + Log::info($msg); + // Optionally print to console if running via command + // echo "SUCCESS: $msg\n"; + } + + if (!empty($this->errors)) { + Log::error("Import completed with errors:"); + foreach ($this->errors as $error) { + Log::error($error); + // echo "ERROR: $error\n"; + } + } + } +} \ No newline at end of file diff --git a/app/Services/Import/ProjectContentService_bck.php b/app/Services/Import/ProjectContentService_bck.php new file mode 100644 index 0000000..4ca6be8 --- /dev/null +++ b/app/Services/Import/ProjectContentService_bck.php @@ -0,0 +1,276 @@ +errors; + } + + public function getSuccess(): array + { + return $this->success; + } + + public function __construct() + { + $this->basePath = storage_path('app/imports/projects'); + } + + /** + * Main entry point to handle the import process. + */ + public function handle(): void + { + try { + if (!File::isDirectory($this->basePath)) { + throw new Exception("Import directory not found: {$this->basePath}"); + } + + $projectDirs = File::directories($this->basePath); + + foreach ($projectDirs as $projectPath) { + $projectName = basename($projectPath); + $this->processProject($projectName, $projectPath); + } + + $this->logSummary(); + } catch (Exception $e) { + Log::error("Import failed: " . $e->getMessage()); + } + } + + /** + * Process an individual project directory. + */ + private function processProject(string $projectName, string $projectPath): void + { + $contentPath = $projectPath . DIRECTORY_SEPARATOR . 'content'; + + if (!File::isDirectory($contentPath)) { + Log::warning("Project [{$projectName}] has no 'content' subdirectory. Skipping."); + return; + } + + // Get the project ID from config based on folder name + $projectId = config("myapp.projects.{$projectName}"); + + if (!$projectId) { + $this->errors[] = "Project configuration missing for: {$projectName}"; + return; + } + + $contentTypes = File::directories($contentPath); + + foreach ($contentTypes as $typePath) { + $contentTypeStr = basename($typePath); + $this->processContentType($projectId, $contentTypeStr, $typePath); + } + } + + /** + * Process subdirectories like 'articles', 'categories', 'tags'. + */ + private function processContentType(int $projectId, string $contentTypeStr, string $path): void + { + $files = File::files($path); + + foreach ($files as $file) { + if ($file->getExtension() !== 'md') { + continue; + } + + try { + $this->importFile($projectId, $contentTypeStr, $file->getPathname()); + } catch (Exception $e) { + $this->errors[] = "File error [{$file->getFilename()}]: " . $e->getMessage(); + } + } + } + + /** + * Parse the Markdown file and store it using the appropriate DTO. + */ + private function importFile(int $projectId, string $contentTypeStr, string $filePath): void + { + $fileContent = file_get_contents($filePath); + if ($fileContent === false) { + throw new Exception("Could not read file."); + } + + $object = YamlFrontMatter::parse($fileContent); + + // Basic validation: ensure we have at least a title or slug + if (!$object->matter('title') && !$object->matter('slug')) { + throw new Exception("Missing required YAML front matter (title or slug)."); + } + + // Determine which DTO/Model to use based on directory name + switch ($contentTypeStr) { + case 'categories': + $this->handleCategoryImport($projectId, $object); + break; + case 'tags': + $this->handleTagImport($projectId, $object); + break; + default: + $this->handleContentImport($projectId, $contentTypeStr, $object); + break; + } + } + + /** + * Handle generic content (articles, posts, etc.) + */ + private function handleContentImport(int $projectId, string $contentTypeStr, Document $object): void + { + try { + // Map YAML to ContentData DTO + $data = [ + 'uuid' => $object->matter('uuid') ?? (string) Str::uuid(), + 'projectId' => $projectId, + 'userId' => $object->matter('user_id') ?? 1, + 'authorId' => $object->matter('author_id'), + 'parentId' => $object->matter('parent_id'), + 'contentType' => ContentContentType::tryFrom($contentTypeStr) ?? ContentContentType::ARTICLE, + 'status' => $object->matter('is_published') ? ContentStatus::PUBLISHED : ContentStatus::DRAFT, + 'visibility' => ContentVisibility::tryFrom($object->matter('visibility') ?? 'public') ?? ContentVisibility::PUBLIC, + 'lang' => $object->matter('lang') ?? 'en', + 'slug' => $object->matter('slug') ?? Str::slug($object->matter('title')), + 'title' => (string) $object->matter('title'), + 'subtitle' => $object->matter('subtitle'), + 'excerpt' => $object->matter('description') ?? $object->matter('excerpt'), + 'content' => $object->body(), + 'metadata' => $this->extractMetadata($object, ['title', 'slug', 'description', 'is_published']), + 'position' => (int) ($object->matter('position') ?? 0), + 'isFeatured' => (bool) ($object->matter('is_featured') ?? false), + 'publishedAt' => $object->matter('published_at') ? Carbon::parse($object->matter('published_at')) : null, + ]; + + $dto = ContentData::from($data); + + Content::updateOrCreate( + ['slug' => $dto->slug, 'project_id' => $dto->projectId], + $dto->toArray() + ); + + $this->success[] = "Imported Content: {$dto->title}"; + } catch (Exception $e) { + $this->errors[] = "Content Save Error [{$object->matter('title')}]: " . $e->getMessage(); + } + } + + /** + * Handle Category specific import + */ + private function handleCategoryImport(int $projectId, Document $object): void + { + try { + $data = [ + 'uuid' => $object->matter('uuid') ?? (string) Str::uuid(), + 'projectId' => $projectId, + 'parentId' => $object->matter('parent_id'), + 'status' => $object->matter('is_published') ? ContentStatus::PUBLISHED : ContentStatus::DRAFT, + 'visibility' => ContentVisibility::PUBLIC, + 'contentType' => ContentContentType::CATEGORY, + 'position' => (int) ($object->matter('position') ?? 0), + 'slug' => $object->matter('slug') ?? Str::slug($object->matter('title')), + 'lang' => Language::tryFrom($object->matter('lang') ?? 'en') ?? Language::EN, + 'title' => (string) $object->matter('title'), + 'excerpt' => $object->matter('description'), + 'metadata' => $this->extractMetadata($object, ['title', 'slug']), + ]; + + $dto = CategoryData::from($data); + + Category::updateOrCreate( + ['slug' => $dto->slug, 'project_id' => $dto->projectId], + $dto->toArray() + ); + + $this->success[] = "Imported Category: {$dto->title}"; + } catch (Exception $e) { + $this->errors[] = "Category Save Error: " . $e->getMessage(); + } + } + + /** + * Handle Tag specific import + */ + private function handleTagImport(int $projectId, Document $object): void + { + try { + $dto = TagData::from([ + 'projectId' => $projectId, + 'contentType' => ContentContentType::TAG, + 'lang' => $object->matter('lang') ?? 'en', + 'name' => $object->matter('title') ?? $object->matter('name'), + ]); + + Tag::updateOrCreate( + ['name' => $dto->name, 'project_id' => $dto->projectId], + $dto->toArray() + ); + + $this->success[] = "Imported Tag: {$dto->name}"; + } catch (Exception $e) { + $this->errors[] = "Tag Save Error: " . $e->getMessage(); + } + } + + /** + * Extracts keys from YAML that aren't part of the primary DTO properties. + */ + private function extractMetadata(Document $object, array $excludeKeys): array + { + return array_filter($object->matter(), function ($key) use ($excludeKeys) { + return !in_array($key, $excludeKeys); + }, ARRAY_FILTER_USE_KEY); + } + + /** + * Log results of the import. + */ + private function logSummary(): void + { + foreach ($this->success as $msg) { + Log::info($msg); + // Optionally print to console if running via command + // echo "SUCCESS: $msg\n"; + } + + if (!empty($this->errors)) { + Log::error("Import completed with errors:"); + foreach ($this->errors as $error) { + Log::error($error); + // echo "ERROR: $error\n"; + } + } + } +} \ No newline at end of file diff --git a/app/Services/Import/ProjectPostService.php b/app/Services/Import/ProjectPostService.php new file mode 100644 index 0000000..da7f3d0 --- /dev/null +++ b/app/Services/Import/ProjectPostService.php @@ -0,0 +1,241 @@ +project = $project; + $this->pathToDir = storage_path() . '/app/imports/projects/' . $project . '/posts/'; + } + + /** + * @throws Exception + */ + public function handle(): void + { + try { + $this->parseImportDir(); + $this->parseImportFiles(); + $this->parseMarkdownFiles(); + $this->logErrors(); + $this->logSuccess(); + } catch (Exception $e) { + throw new Exception($e->getMessage()); + } + } + + private function parseMarkdown(Document $object, string $contentType): void + { + + $data = new \stdClass(); + $data->options = []; + $data->parent_id = $this->getParentId($object->parent_id,$contentType); + $data->project_id = $object->project_id ?? config('myapp.projects.' . $this->project); + $data->user_id = $object->user_id ?? 1; + $data->is_featured = $object->is_featured ?? false; + $data->post_type = $contentType; + $data->post_status = $object->post_status ?? PostStatus::DRAFT; + $data->position = $object->position ?? 0; + $data->views_count = $object->views_count ?? 0; + $data->lang = $object->lang ?? app()->getLocale(); + $data->title = str($object->title)->squish()->toString(); + $data->subtitle = str($object->subtitle)->squish()->toString() ?? ''; + $data->description = str($object->description)->squish()->toString() ?? ''; + $data->content = $object->body(); + $data->image_url = (function($url, $contentType, $project, $slug, $eventDirectory) { + if ($contentType === 'post') { + return $this->getThumbImageUrl($project . '-'.$contentType, $eventDirectory); + }elseif ($contentType === 'place') { + return $this->getThumbImageUrl($project, $slug); + }else{ + return $url; + } + + })($object->image_url ?? '', $contentType, $this->project, $object->slug, $object->eventDirectory ?? ''); + $data->tags = $object->tags ?? null; + $data->categories = $object->categories ?? null; + $data->slug = $object->slug ?? null; + $data->created_at = $object->created_at ?? null; + $data->updated_at = $object->updated_at ?? null; + $this->parseOptions($object, $data); + + $featuredImage = (function($url, $contentType, $project, $slug,$eventDirectory) { + if ($contentType === 'post') { + return $this->getFeaturedImageUrl($project . '-'.$contentType, $eventDirectory); + }elseif ($contentType === 'place') { + return $this->getFeaturedImageUrl($project, $slug); + }else{ + return $url; + } + })($object->image_url ?? '', $contentType, $this->project, $object->slug, $object->eventDirectory ?? ''); + + if(!empty($featuredImage)) { + $data->options['featuredImage'] = $featuredImage; + } + $post = null; + + try { + $validatedData = PostData::validateAndCreate((array)$data); + $post = $this->storeData($validatedData); + } catch (Exception $e) { + $this->errors[] = 'ERROR: Unable to parse post narkdown data for project: ' . $data->project_id . ' | ' . $data->title . ' | '. $data->slug; + $this->errors[] = $e->getMessage(); + } + + if (!is_null($post)) { + if (is_string($data->categories) && !empty($data->categories)) { + $categoriesIds = $this->parseCategories($data->categories, $post); + if (count($categoriesIds) > 0) { + $post->categories()->sync($categoriesIds); + } + } + + if (is_string($data->tags) && $data->tags !== '') { + $tagsIds = $this->parseTags($data->tags, $post); + if (count($tagsIds) > 0) { + $post->tags()->sync($tagsIds); + } + + } + + } + + + } + + private function storeData(PostData $data): Post|null + { + try { + $post = Post::updateOrCreate( + ['slug' => $data->slug], + [ + 'parent_id' => $data->parent_id, + 'project_id' => $data->project_id, + 'user_id' => $data->user_id, + 'slug' => $data->slug, + 'is_featured' => $data->is_featured, + 'post_type' => $data->post_type, + 'post_status' => $data->post_status->value, + 'position' => $data->position, + 'views_count' => $data->views_count, + 'lang' => $data->lang, + 'title' => $data->title, + 'subtitle' => $data->subtitle, + 'description' => $data->description, + 'content' => $data->content, + 'image_url' => $data->image_url, + 'options' => json_encode($data->options, JSON_UNESCAPED_UNICODE), + 'created_at' => $data->created_at, + 'updated_at' => $data->updated_at, + ] + ); + /* $this->success[] = 'SUCCESS: '.$data->post_type.' saved for project: ' . $data->project_id . ' | ' . + $data->title . ' | ' . + $data->slug;*/ + return $post; + } catch (Exception $e) { + $this->errors[] = 'ERROR: Unable to save '.$data->post_type.' for project: ' . $data->project_id . ' | ' . $data->title + . ' | ' . $data->slug; + $this->errors[] = $e->getMessage(); + + } + return null; + } + + + private function parseCategories(string $categories, Post $post): array + { + + $categorySlugs = array_map('trim', explode(',', $categories)); + $categories = []; + foreach ($categorySlugs as $slug) { + $category = Category::where('slug', $slug)->publishedByType($post->post_type)->first(); + if (is_null($category)) { + $backtrace = debug_backtrace(); + $caller = $backtrace[0]; + $this->errors[] = 'ERROR: Category not found: category slug = "' . $slug . '" | post slug "'.$post->slug. '" for in ' . $caller['file'] . ' on line ' . $caller['line']; + continue; + } + $categories[] = $category->id; + } + return $categories; + } + + private function getParentId(string|null $parentSlug, string $postType): int + { + if(is_null($parentSlug)) { + return 0; + } + $post = Post::where('slug', $parentSlug)->publishedByType($postType)->first(); + + if (!$post) { + return 0; + } + + return $post->id; + } + + private function parseTags(string $tags, Post $post): array + { + $tagNames = array_map('trim', explode(',', $tags)); + $tagIds = []; + + foreach ($tagNames as $tagName) { + $tag = $this->storeTag($tagName, TagData::from([ + 'project_id' => $post->project_id, + 'is_published' => true, + 'tag_type' => $post->post_type, + 'lang' => $post->lang, + 'views_count' => 0, + 'name' => $tagName, + ])); + if (!is_null($tag)) { + $tagIds[] = $tag->id; + } + } + return $tagIds; + } + + private function storeTag(string $tagName, TagData $post): Tag|null + { + try { + $tag = Tag::updateOrCreate( + ['name' => $tagName], + ['project_id' => $post->project_id, + 'is_published' => true, + 'tag_type' => $post->tag_type, + 'lang' => $post->lang, + 'views_count' => 0, + 'name' => $tagName, + + ] + ); + // $this->success[] = 'SUCCESS: Tag saved for project: ' . $post->project_id . ' | ' . $tagName; + return $tag; + } catch (Exception $e) { + $this->errors[] = 'ERROR: Unable to save tag for project: ' . $post->project_id . ' | ' . $tagName; + $this->errors[] = $e->getMessage(); + + } + return null; + } +} \ No newline at end of file diff --git a/app/Traits/HasUuid.php b/app/Traits/HasUuid.php new file mode 100644 index 0000000..d1d3a04 --- /dev/null +++ b/app/Traits/HasUuid.php @@ -0,0 +1,16 @@ +uuid = (string) Str::uuid(); + }); + } +} diff --git a/app/Traits/ImportProjectTrait.php b/app/Traits/ImportProjectTrait.php new file mode 100644 index 0000000..56ed7af --- /dev/null +++ b/app/Traits/ImportProjectTrait.php @@ -0,0 +1,151 @@ +errors; + } + + private array $success = []; + public function getSuccess(): array + { + return $this->success; + } + + + private string $pathToDir; + + private array $directories = []; + private function parseImportDir(): void + { + + if (!config()->has('myapp.projects.' . $this->project)) { + throw new Exception('No valid project name: ' . $this->project); + } + if (!is_dir($this->pathToDir)) { + throw new Exception('Failed to read files from directory: ' . $this->pathToDir); + } + + $directories = array_filter(glob($this->pathToDir . '/*'), 'is_dir'); + if (empty($directories)) { + throw new Exception('No directories found in: ' . $this->pathToDir); + } + + $this->directories = array_map('basename', $directories); + } + + private function parseImportFiles(): void + { + foreach ($this->directories as $directory) { + $path = $this->pathToDir . $directory; + $files = glob($path . '/*.md'); + if (empty($files)) { + $this->errors[] = 'WARNING: No files found in directory: ' . $path; + continue; + } + $this->files[$directory] = $files; + } + } + + private function parseMarkdownFiles(): void + { + foreach ($this->files as $contentType => $files) { + foreach ($files as $file) { + $content = file_get_contents($file); + if ($content === false) { + array_push($this->errors, 'Failed to read file: ' . $file); + continue; + } + $object = YamlFrontMatter::parse($content); + $this->parseMarkdown($object, $contentType); + + } + } + } + // Function takes all $object properties that are not listed in $data properties and creates an array that + // will be the content of options. + + private function parseOptions(Document $object, $data): void + { + $data->options = array_filter((array) $object->matter(), function ($key) use ($data) { + return !property_exists($data, $key) && strpos($key, "\x00*\x00") === false; + }, + ARRAY_FILTER_USE_KEY + ); + } + + private function getThumbImageUrl(string $album, string $event): string + { + $url = ''; + $path = config('myapp.album.dir.target') . '/' . $album . '/' . $event. '/' . config('myapp.album.cover'); + if (file_exists($path) ) { + $url = config('myapp.album.url'). '/' . $album . '/' . $event . '/' . config('myapp.album.cover'); + } + return $url; + //return Utils::urlExists($url); + } + private function getFeaturedImageUrl(string $album, string $event): string + { + $url = ''; + $path = config('myapp.album.dir.target') . '/' . $album . '/' . $event. '/' . config('myapp.album.featured'); + if (file_exists($path) ) { + $url = config('myapp.album.url'). '/' . $album . '/' . $event . '/' . config('myapp.album.featured'); + } + return $url; + //return Utils::urlExists($url); + } + + private function getPlaceImageUrl(string $album, string $event): string + { + $url = ''; + $path = config('myapp.album.dir.target') . '/' . $album . '/' . $event. '/' . config('myapp.album.cover'); + if (file_exists($path) ) { + $url = config('myapp.album.url'). '/' . $album . '/' . $event . '/' . config('myapp.album.cover'); + } + return $url; + //return Utils::urlExists($url); + } + private function getPlaceFeaturedImageUrl(string $album, string $event): string + { + $url = ''; + $path = config('myapp.album.dir.target') . '/' . $album . '/' . $event. '/' . config('myapp.album.featured'); + if (file_exists($path) ) { + $url = config('myapp.album.url'). '/' . $album . '/' . $event . '/' . config('myapp.album.featured'); + } + return $url; + //return Utils::urlExists($url); + } + + private function logErrors(): void + { + if(!empty($this->getErrors())) { + Log::error('Some errors occurred while importing data for project: ' . $this->project); + foreach ($this->getErrors() as $error) { + Log::error($error); + } + } + } + + private function logSuccess(): void + { + foreach ($this->getSuccess() as $log) { + Log::info($log); + } + } +} \ No newline at end of file diff --git a/composer.json b/composer.json index 3560456..6bf9cf3 100644 --- a/composer.json +++ b/composer.json @@ -10,7 +10,6 @@ "license": "MIT", "require": { "php": "^8.4", - "laravel/fortify": "^1.30", "laravel/framework": "^12.0", "laravel/telescope": "^5.16", "laravel/tinker": "^2.10.1", @@ -25,7 +24,6 @@ "laradumps/laradumps": "^5.0", "laradumps/laradumps-core": "^4.0", "laravel/boost": "^1.8", - "laravel/pail": "^1.2.2", "laravel/pint": "^1.24", "laravel/sail": "^1.41", "mockery/mockery": "^1.6", diff --git a/composer.lock b/composer.lock deleted file mode 100644 index d17c40c..0000000 --- a/composer.lock +++ /dev/null @@ -1,11121 +0,0 @@ -{ - "_readme": [ - "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", - "This file is @generated automatically" - ], - "content-hash": "80a762c02014aa2e33d1b116da198356", - "packages": [ - { - "name": "bacon/bacon-qr-code", - "version": "v3.0.3", - "source": { - "type": "git", - "url": "https://github.com/Bacon/BaconQrCode.git", - "reference": "36a1cb2b81493fa5b82e50bf8068bf84d1542563" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Bacon/BaconQrCode/zipball/36a1cb2b81493fa5b82e50bf8068bf84d1542563", - "reference": "36a1cb2b81493fa5b82e50bf8068bf84d1542563", - "shasum": "" - }, - "require": { - "dasprid/enum": "^1.0.3", - "ext-iconv": "*", - "php": "^8.1" - }, - "require-dev": { - "phly/keep-a-changelog": "^2.12", - "phpunit/phpunit": "^10.5.11 || ^11.0.4", - "spatie/phpunit-snapshot-assertions": "^5.1.5", - "spatie/pixelmatch-php": "^1.2.0", - "squizlabs/php_codesniffer": "^3.9" - }, - "suggest": { - "ext-imagick": "to generate QR code images" - }, - "type": "library", - "autoload": { - "psr-4": { - "BaconQrCode\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-2-Clause" - ], - "authors": [ - { - "name": "Ben Scholzen 'DASPRiD'", - "email": "mail@dasprids.de", - "homepage": "https://dasprids.de/", - "role": "Developer" - } - ], - "description": "BaconQrCode is a QR code generator for PHP.", - "homepage": "https://github.com/Bacon/BaconQrCode", - "support": { - "issues": "https://github.com/Bacon/BaconQrCode/issues", - "source": "https://github.com/Bacon/BaconQrCode/tree/v3.0.3" - }, - "time": "2025-11-19T17:15:36+00:00" - }, - { - "name": "brick/math", - "version": "0.14.1", - "source": { - "type": "git", - "url": "https://github.com/brick/math.git", - "reference": "f05858549e5f9d7bb45875a75583240a38a281d0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/brick/math/zipball/f05858549e5f9d7bb45875a75583240a38a281d0", - "reference": "f05858549e5f9d7bb45875a75583240a38a281d0", - "shasum": "" - }, - "require": { - "php": "^8.2" - }, - "require-dev": { - "php-coveralls/php-coveralls": "^2.2", - "phpstan/phpstan": "2.1.22", - "phpunit/phpunit": "^11.5" - }, - "type": "library", - "autoload": { - "psr-4": { - "Brick\\Math\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Arbitrary-precision arithmetic library", - "keywords": [ - "Arbitrary-precision", - "BigInteger", - "BigRational", - "arithmetic", - "bigdecimal", - "bignum", - "bignumber", - "brick", - "decimal", - "integer", - "math", - "mathematics", - "rational" - ], - "support": { - "issues": "https://github.com/brick/math/issues", - "source": "https://github.com/brick/math/tree/0.14.1" - }, - "funding": [ - { - "url": "https://github.com/BenMorel", - "type": "github" - } - ], - "time": "2025-11-24T14:40:29+00:00" - }, - { - "name": "carbonphp/carbon-doctrine-types", - "version": "3.2.0", - "source": { - "type": "git", - "url": "https://github.com/CarbonPHP/carbon-doctrine-types.git", - "reference": "18ba5ddfec8976260ead6e866180bd5d2f71aa1d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/CarbonPHP/carbon-doctrine-types/zipball/18ba5ddfec8976260ead6e866180bd5d2f71aa1d", - "reference": "18ba5ddfec8976260ead6e866180bd5d2f71aa1d", - "shasum": "" - }, - "require": { - "php": "^8.1" - }, - "conflict": { - "doctrine/dbal": "<4.0.0 || >=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": "dasprid/enum", - "version": "1.0.7", - "source": { - "type": "git", - "url": "https://github.com/DASPRiD/Enum.git", - "reference": "b5874fa9ed0043116c72162ec7f4fb50e02e7cce" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/DASPRiD/Enum/zipball/b5874fa9ed0043116c72162ec7f4fb50e02e7cce", - "reference": "b5874fa9ed0043116c72162ec7f4fb50e02e7cce", - "shasum": "" - }, - "require": { - "php": ">=7.1 <9.0" - }, - "require-dev": { - "phpunit/phpunit": "^7 || ^8 || ^9 || ^10 || ^11", - "squizlabs/php_codesniffer": "*" - }, - "type": "library", - "autoload": { - "psr-4": { - "DASPRiD\\Enum\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-2-Clause" - ], - "authors": [ - { - "name": "Ben Scholzen 'DASPRiD'", - "email": "mail@dasprids.de", - "homepage": "https://dasprids.de/", - "role": "Developer" - } - ], - "description": "PHP 7.1 enum implementation", - "keywords": [ - "enum", - "map" - ], - "support": { - "issues": "https://github.com/DASPRiD/Enum/issues", - "source": "https://github.com/DASPRiD/Enum/tree/1.0.7" - }, - "time": "2025-09-16T12:23:56+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/deprecations", - "version": "1.1.5", - "source": { - "type": "git", - "url": "https://github.com/doctrine/deprecations.git", - "reference": "459c2f5dd3d6a4633d3b5f46ee2b1c40f57d3f38" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/deprecations/zipball/459c2f5dd3d6a4633d3b5f46ee2b1c40f57d3f38", - "reference": "459c2f5dd3d6a4633d3b5f46ee2b1c40f57d3f38", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0" - }, - "conflict": { - "phpunit/phpunit": "<=7.5 || >=13" - }, - "require-dev": { - "doctrine/coding-standard": "^9 || ^12 || ^13", - "phpstan/phpstan": "1.4.10 || 2.1.11", - "phpstan/phpstan-phpunit": "^1.0 || ^2", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6 || ^10.5 || ^11.5 || ^12", - "psr/log": "^1 || ^2 || ^3" - }, - "suggest": { - "psr/log": "Allows logging deprecations via PSR-3 logger implementation" - }, - "type": "library", - "autoload": { - "psr-4": { - "Doctrine\\Deprecations\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.", - "homepage": "https://www.doctrine-project.org/", - "support": { - "issues": "https://github.com/doctrine/deprecations/issues", - "source": "https://github.com/doctrine/deprecations/tree/1.1.5" - }, - "time": "2025-04-07T20:06:18+00:00" - }, - { - "name": "doctrine/inflector", - "version": "2.1.0", - "source": { - "type": "git", - "url": "https://github.com/doctrine/inflector.git", - "reference": "6d6c96277ea252fc1304627204c3d5e6e15faa3b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/inflector/zipball/6d6c96277ea252fc1304627204c3d5e6e15faa3b", - "reference": "6d6c96277ea252fc1304627204c3d5e6e15faa3b", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "require-dev": { - "doctrine/coding-standard": "^12.0 || ^13.0", - "phpstan/phpstan": "^1.12 || ^2.0", - "phpstan/phpstan-phpunit": "^1.4 || ^2.0", - "phpstan/phpstan-strict-rules": "^1.6 || ^2.0", - "phpunit/phpunit": "^8.5 || ^12.2" - }, - "type": "library", - "autoload": { - "psr-4": { - "Doctrine\\Inflector\\": "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": "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.1.0" - }, - "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": "2025-08-10T19:31:58+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": "dragonmantank/cron-expression", - "version": "v3.6.0", - "source": { - "type": "git", - "url": "https://github.com/dragonmantank/cron-expression.git", - "reference": "d61a8a9604ec1f8c3d150d09db6ce98b32675013" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/dragonmantank/cron-expression/zipball/d61a8a9604ec1f8c3d150d09db6ce98b32675013", - "reference": "d61a8a9604ec1f8c3d150d09db6ce98b32675013", - "shasum": "" - }, - "require": { - "php": "^8.2|^8.3|^8.4|^8.5" - }, - "replace": { - "mtdowling/cron-expression": "^1.0" - }, - "require-dev": { - "phpstan/extension-installer": "^1.4.3", - "phpstan/phpstan": "^1.12.32|^2.1.31", - "phpunit/phpunit": "^8.5.48|^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.6.0" - }, - "funding": [ - { - "url": "https://github.com/dragonmantank", - "type": "github" - } - ], - "time": "2025-10-31T18:51:33+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.4.0", - "source": { - "type": "git", - "url": "https://github.com/fruitcake/php-cors.git", - "reference": "38aaa6c3fd4c157ffe2a4d10aa8b9b16ba8de379" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/fruitcake/php-cors/zipball/38aaa6c3fd4c157ffe2a4d10aa8b9b16ba8de379", - "reference": "38aaa6c3fd4c157ffe2a4d10aa8b9b16ba8de379", - "shasum": "" - }, - "require": { - "php": "^8.1", - "symfony/http-foundation": "^5.4|^6.4|^7.3|^8" - }, - "require-dev": { - "phpstan/phpstan": "^2", - "phpunit/phpunit": "^9", - "squizlabs/php_codesniffer": "^4" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.3-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.4.0" - }, - "funding": [ - { - "url": "https://fruitcake.nl", - "type": "custom" - }, - { - "url": "https://github.com/barryvdh", - "type": "github" - } - ], - "time": "2025-12-03T09:33:47+00:00" - }, - { - "name": "graham-campbell/result-type", - "version": "v1.1.4", - "source": { - "type": "git", - "url": "https://github.com/GrahamCampbell/Result-Type.git", - "reference": "e01f4a821471308ba86aa202fed6698b6b695e3b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/e01f4a821471308ba86aa202fed6698b6b695e3b", - "reference": "e01f4a821471308ba86aa202fed6698b6b695e3b", - "shasum": "" - }, - "require": { - "php": "^7.2.5 || ^8.0", - "phpoption/phpoption": "^1.9.5" - }, - "require-dev": { - "phpunit/phpunit": "^8.5.41 || ^9.6.22 || ^10.5.45 || ^11.5.7" - }, - "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.4" - }, - "funding": [ - { - "url": "https://github.com/GrahamCampbell", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/graham-campbell/result-type", - "type": "tidelift" - } - ], - "time": "2025-12-27T19:43:20+00:00" - }, - { - "name": "guzzlehttp/guzzle", - "version": "7.10.0", - "source": { - "type": "git", - "url": "https://github.com/guzzle/guzzle.git", - "reference": "b51ac707cfa420b7bfd4e4d5e510ba8008e822b4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/b51ac707cfa420b7bfd4e4d5e510ba8008e822b4", - "reference": "b51ac707cfa420b7bfd4e4d5e510ba8008e822b4", - "shasum": "" - }, - "require": { - "ext-json": "*", - "guzzlehttp/promises": "^2.3", - "guzzlehttp/psr7": "^2.8", - "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.10.0" - }, - "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-08-23T22:36:01+00:00" - }, - { - "name": "guzzlehttp/promises", - "version": "2.3.0", - "source": { - "type": "git", - "url": "https://github.com/guzzle/promises.git", - "reference": "481557b130ef3790cf82b713667b43030dc9c957" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/481557b130ef3790cf82b713667b43030dc9c957", - "reference": "481557b130ef3790cf82b713667b43030dc9c957", - "shasum": "" - }, - "require": { - "php": "^7.2.5 || ^8.0" - }, - "require-dev": { - "bamarni/composer-bin-plugin": "^1.8.2", - "phpunit/phpunit": "^8.5.44 || ^9.6.25" - }, - "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.3.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-08-22T14:34:08+00:00" - }, - { - "name": "guzzlehttp/psr7", - "version": "2.8.0", - "source": { - "type": "git", - "url": "https://github.com/guzzle/psr7.git", - "reference": "21dc724a0583619cd1652f673303492272778051" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/21dc724a0583619cd1652f673303492272778051", - "reference": "21dc724a0583619cd1652f673303492272778051", - "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.44 || ^9.6.25" - }, - "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.8.0" - }, - "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-08-23T21:21:41+00:00" - }, - { - "name": "guzzlehttp/uri-template", - "version": "v1.0.5", - "source": { - "type": "git", - "url": "https://github.com/guzzle/uri-template.git", - "reference": "4f4bbd4e7172148801e76e3decc1e559bdee34e1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/guzzle/uri-template/zipball/4f4bbd4e7172148801e76e3decc1e559bdee34e1", - "reference": "4f4bbd4e7172148801e76e3decc1e559bdee34e1", - "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.44 || ^9.6.25", - "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.5" - }, - "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-08-22T14:27:06+00:00" - }, - { - "name": "laravel/fortify", - "version": "v1.33.0", - "source": { - "type": "git", - "url": "https://github.com/laravel/fortify.git", - "reference": "e0666dabeec0b6428678af1d51f436dcfb24e3a9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laravel/fortify/zipball/e0666dabeec0b6428678af1d51f436dcfb24e3a9", - "reference": "e0666dabeec0b6428678af1d51f436dcfb24e3a9", - "shasum": "" - }, - "require": { - "bacon/bacon-qr-code": "^3.0", - "ext-json": "*", - "illuminate/support": "^10.0|^11.0|^12.0", - "php": "^8.1", - "pragmarx/google2fa": "^9.0", - "symfony/console": "^6.0|^7.0" - }, - "require-dev": { - "orchestra/testbench": "^8.36|^9.15|^10.8", - "phpstan/phpstan": "^1.10" - }, - "type": "library", - "extra": { - "laravel": { - "providers": [ - "Laravel\\Fortify\\FortifyServiceProvider" - ] - }, - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Laravel\\Fortify\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Taylor Otwell", - "email": "taylor@laravel.com" - } - ], - "description": "Backend controllers and scaffolding for Laravel authentication.", - "keywords": [ - "auth", - "laravel" - ], - "support": { - "issues": "https://github.com/laravel/fortify/issues", - "source": "https://github.com/laravel/fortify" - }, - "time": "2025-12-15T14:48:33+00:00" - }, - { - "name": "laravel/framework", - "version": "v12.46.0", - "source": { - "type": "git", - "url": "https://github.com/laravel/framework.git", - "reference": "9dcff48d25a632c1fadb713024c952fec489c4ae" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/9dcff48d25a632c1fadb713024c952fec489c4ae", - "reference": "9dcff48d25a632c1fadb713024c952fec489c4ae", - "shasum": "" - }, - "require": { - "brick/math": "^0.11|^0.12|^0.13|^0.14", - "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.33", - "symfony/polyfill-php84": "^1.33", - "symfony/polyfill-php85": "^1.33", - "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/json-schema": "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/reflection": "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", - "opis/json-schema": "^2.4.1", - "orchestra/testbench-core": "^10.8.1", - "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|^1.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 generate fake data using the fake() helper (^1.23).", - "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|^1.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/Reflection/helpers.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/", - "src/Illuminate/Reflection/" - ] - } - }, - "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": "2026-01-07T23:26:53+00:00" - }, - { - "name": "laravel/prompts", - "version": "v0.3.8", - "source": { - "type": "git", - "url": "https://github.com/laravel/prompts.git", - "reference": "096748cdfb81988f60090bbb839ce3205ace0d35" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laravel/prompts/zipball/096748cdfb81988f60090bbb839ce3205ace0d35", - "reference": "096748cdfb81988f60090bbb839ce3205ace0d35", - "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|^4.0", - "phpstan/phpstan": "^1.12.28", - "phpstan/phpstan-mockery": "^1.1.3" - }, - "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.8" - }, - "time": "2025-11-21T20:52:52+00:00" - }, - { - "name": "laravel/serializable-closure", - "version": "v2.0.7", - "source": { - "type": "git", - "url": "https://github.com/laravel/serializable-closure.git", - "reference": "cb291e4c998ac50637c7eeb58189c14f5de5b9dd" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/cb291e4c998ac50637c7eeb58189c14f5de5b9dd", - "reference": "cb291e4c998ac50637c7eeb58189c14f5de5b9dd", - "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|^4.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-11-21T20:52:36+00:00" - }, - { - "name": "laravel/telescope", - "version": "v5.16.1", - "source": { - "type": "git", - "url": "https://github.com/laravel/telescope.git", - "reference": "dc114b94f025b8c16b5eb3194b4ddc0e46d5310c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laravel/telescope/zipball/dc114b94f025b8c16b5eb3194b4ddc0e46d5310c", - "reference": "dc114b94f025b8c16b5eb3194b4ddc0e46d5310c", - "shasum": "" - }, - "require": { - "ext-json": "*", - "laravel/framework": "^8.37|^9.0|^10.0|^11.0|^12.0", - "php": "^8.0", - "symfony/console": "^5.3|^6.0|^7.0", - "symfony/var-dumper": "^5.0|^6.0|^7.0" - }, - "require-dev": { - "ext-gd": "*", - "guzzlehttp/guzzle": "^6.0|^7.0", - "laravel/octane": "^1.4|^2.0", - "orchestra/testbench": "^6.47.1|^7.55|^8.36|^9.15|^10.8", - "phpstan/phpstan": "^1.10" - }, - "type": "library", - "extra": { - "laravel": { - "providers": [ - "Laravel\\Telescope\\TelescopeServiceProvider" - ] - } - }, - "autoload": { - "psr-4": { - "Laravel\\Telescope\\": "src/", - "Laravel\\Telescope\\Database\\Factories\\": "database/factories/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Taylor Otwell", - "email": "taylor@laravel.com" - }, - { - "name": "Mohamed Said", - "email": "mohamed@laravel.com" - } - ], - "description": "An elegant debug assistant for the Laravel framework.", - "keywords": [ - "debugging", - "laravel", - "monitoring" - ], - "support": { - "issues": "https://github.com/laravel/telescope/issues", - "source": "https://github.com/laravel/telescope/tree/v5.16.1" - }, - "time": "2025-12-30T17:31:31+00:00" - }, - { - "name": "laravel/tinker", - "version": "v2.11.0", - "source": { - "type": "git", - "url": "https://github.com/laravel/tinker.git", - "reference": "3d34b97c9a1747a81a3fde90482c092bd8b66468" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laravel/tinker/zipball/3d34b97c9a1747a81a3fde90482c092bd8b66468", - "reference": "3d34b97c9a1747a81a3fde90482c092bd8b66468", - "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|^8.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.11.0" - }, - "time": "2025-12-19T19:16:45+00:00" - }, - { - "name": "league/commonmark", - "version": "2.8.0", - "source": { - "type": "git", - "url": "https://github.com/thephpleague/commonmark.git", - "reference": "4efa10c1e56488e658d10adf7b7b7dcd19940bfb" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/4efa10c1e56488e658d10adf7b7b7dcd19940bfb", - "reference": "4efa10c1e56488e658d10adf7b7b7dcd19940bfb", - "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.9-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-11-26T21:48:24+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.2", - "source": { - "type": "git", - "url": "https://github.com/thephpleague/flysystem.git", - "reference": "5966a8ba23e62bdb518dd9e0e665c2dbd4b5b277" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/5966a8ba23e62bdb518dd9e0e665c2dbd4b5b277", - "reference": "5966a8ba23e62bdb518dd9e0e665c2dbd4b5b277", - "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.2" - }, - "time": "2025-11-10T17:13:11+00:00" - }, - { - "name": "league/flysystem-local", - "version": "3.30.2", - "source": { - "type": "git", - "url": "https://github.com/thephpleague/flysystem-local.git", - "reference": "ab4f9d0d672f601b102936aa728801dd1a11968d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem-local/zipball/ab4f9d0d672f601b102936aa728801dd1a11968d", - "reference": "ab4f9d0d672f601b102936aa728801dd1a11968d", - "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.2" - }, - "time": "2025-11-10T11:23:37+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.7.0", - "source": { - "type": "git", - "url": "https://github.com/thephpleague/uri.git", - "reference": "8d587cddee53490f9b82bf203d3a9aa7ea4f9807" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/thephpleague/uri/zipball/8d587cddee53490f9b82bf203d3a9aa7ea4f9807", - "reference": "8d587cddee53490f9b82bf203d3a9aa7ea4f9807", - "shasum": "" - }, - "require": { - "league/uri-interfaces": "^7.7", - "php": "^8.1", - "psr/http-factory": "^1" - }, - "conflict": { - "league/uri-schemes": "^1.0" - }, - "suggest": { - "ext-bcmath": "to improve IPV4 host parsing", - "ext-dom": "to convert the URI into an HTML anchor tag", - "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", - "ext-uri": "to use the PHP native URI class", - "jeremykendall/php-domain-parser": "to resolve Public Suffix and Top Level Domain", - "league/uri-components": "Needed to easily manipulate URI objects components", - "league/uri-polyfill": "Needed to backport the PHP URI extension for older versions of PHP", - "php-64bit": "to improve IPV4 host parsing", - "rowbot/url": "to handle WHATWG URL", - "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": [ - "URN", - "data-uri", - "file-uri", - "ftp", - "hostname", - "http", - "https", - "middleware", - "parse_str", - "parse_url", - "psr-7", - "query-string", - "querystring", - "rfc2141", - "rfc3986", - "rfc3987", - "rfc6570", - "rfc8141", - "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.7.0" - }, - "funding": [ - { - "url": "https://github.com/sponsors/nyamsprod", - "type": "github" - } - ], - "time": "2025-12-07T16:02:06+00:00" - }, - { - "name": "league/uri-interfaces", - "version": "7.7.0", - "source": { - "type": "git", - "url": "https://github.com/thephpleague/uri-interfaces.git", - "reference": "62ccc1a0435e1c54e10ee6022df28d6c04c2946c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/thephpleague/uri-interfaces/zipball/62ccc1a0435e1c54e10ee6022df28d6c04c2946c", - "reference": "62ccc1a0435e1c54e10ee6022df28d6c04c2946c", - "shasum": "" - }, - "require": { - "ext-filter": "*", - "php": "^8.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", - "rowbot/url": "to handle WHATWG URL", - "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 tools for parsing and resolving RFC3987/RFC3986 URI", - "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.7.0" - }, - "funding": [ - { - "url": "https://github.com/sponsors/nyamsprod", - "type": "github" - } - ], - "time": "2025-12-07T16:03:21+00:00" - }, - { - "name": "livewire/livewire", - "version": "v3.7.3", - "source": { - "type": "git", - "url": "https://github.com/livewire/livewire.git", - "reference": "a5384df9fbd3eaf02e053bc49aabc8ace293fc1c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/livewire/livewire/zipball/a5384df9fbd3eaf02e053bc49aabc8ace293fc1c", - "reference": "a5384df9fbd3eaf02e053bc49aabc8ace293fc1c", - "shasum": "" - }, - "require": { - "illuminate/database": "^10.0|^11.0|^12.0", - "illuminate/routing": "^10.0|^11.0|^12.0", - "illuminate/support": "^10.0|^11.0|^12.0", - "illuminate/validation": "^10.0|^11.0|^12.0", - "laravel/prompts": "^0.1.24|^0.2|^0.3", - "league/mime-type-detection": "^1.9", - "php": "^8.1", - "symfony/console": "^6.0|^7.0", - "symfony/http-kernel": "^6.2|^7.0" - }, - "require-dev": { - "calebporzio/sushi": "^2.1", - "laravel/framework": "^10.15.0|^11.0|^12.0", - "mockery/mockery": "^1.3.1", - "orchestra/testbench": "^8.21.0|^9.0|^10.0", - "orchestra/testbench-dusk": "^8.24|^9.1|^10.0", - "phpunit/phpunit": "^10.4|^11.5", - "psy/psysh": "^0.11.22|^0.12" - }, - "type": "library", - "extra": { - "laravel": { - "aliases": { - "Livewire": "Livewire\\Livewire" - }, - "providers": [ - "Livewire\\LivewireServiceProvider" - ] - } - }, - "autoload": { - "files": [ - "src/helpers.php" - ], - "psr-4": { - "Livewire\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Caleb Porzio", - "email": "calebporzio@gmail.com" - } - ], - "description": "A front-end framework for Laravel.", - "support": { - "issues": "https://github.com/livewire/livewire/issues", - "source": "https://github.com/livewire/livewire/tree/v3.7.3" - }, - "funding": [ - { - "url": "https://github.com/livewire", - "type": "github" - } - ], - "time": "2025-12-19T02:00:29+00:00" - }, - { - "name": "livewire/volt", - "version": "v1.10.1", - "source": { - "type": "git", - "url": "https://github.com/livewire/volt.git", - "reference": "48cff133990c6261c63ee279fc091af6f6c6654e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/livewire/volt/zipball/48cff133990c6261c63ee279fc091af6f6c6654e", - "reference": "48cff133990c6261c63ee279fc091af6f6c6654e", - "shasum": "" - }, - "require": { - "laravel/framework": "^10.38.2|^11.0|^12.0", - "livewire/livewire": "^3.6.1|^4.0", - "php": "^8.1" - }, - "require-dev": { - "laravel/folio": "^1.1", - "orchestra/testbench": "^8.36|^9.15|^10.8", - "pestphp/pest": "^2.9.5|^3.0|^4.0", - "phpstan/phpstan": "^1.10" - }, - "type": "library", - "extra": { - "laravel": { - "providers": [ - "Livewire\\Volt\\VoltServiceProvider" - ] - }, - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "files": [ - "functions.php" - ], - "psr-4": { - "Livewire\\Volt\\": "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": "An elegantly crafted functional API for Laravel Livewire.", - "homepage": "https://github.com/livewire/volt", - "keywords": [ - "laravel", - "livewire", - "volt" - ], - "support": { - "issues": "https://github.com/livewire/volt/issues", - "source": "https://github.com/livewire/volt" - }, - "time": "2025-11-25T16:19:15+00:00" - }, - { - "name": "monolog/monolog", - "version": "3.10.0", - "source": { - "type": "git", - "url": "https://github.com/Seldaek/monolog.git", - "reference": "b321dd6749f0bf7189444158a3ce785cc16d69b0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/b321dd6749f0bf7189444158a3ce785cc16d69b0", - "reference": "b321dd6749f0bf7189444158a3ce785cc16d69b0", - "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 || ^2.0", - "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.10.0" - }, - "funding": [ - { - "url": "https://github.com/Seldaek", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/monolog/monolog", - "type": "tidelift" - } - ], - "time": "2026-01-02T08:56:05+00:00" - }, - { - "name": "nesbot/carbon", - "version": "3.11.0", - "source": { - "type": "git", - "url": "https://github.com/CarbonPHP/carbon.git", - "reference": "bdb375400dcd162624531666db4799b36b64e4a1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/CarbonPHP/carbon/zipball/bdb375400dcd162624531666db4799b36b64e4a1", - "reference": "bdb375400dcd162624531666db4799b36b64e4a1", - "shasum": "" - }, - "require": { - "carbonphp/carbon-doctrine-types": "<100.0", - "ext-json": "*", - "php": "^8.1", - "psr/clock": "^1.0", - "symfony/clock": "^6.3.12 || ^7.0 || ^8.0", - "symfony/polyfill-mbstring": "^1.0", - "symfony/translation": "^4.4.18 || ^5.2.1 || ^6.0 || ^7.0 || ^8.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": "^v3.87.1", - "kylekatarnls/multi-tester": "^2.5.3", - "phpmd/phpmd": "^2.15.0", - "phpstan/extension-installer": "^1.4.3", - "phpstan/phpstan": "^2.1.22", - "phpunit/phpunit": "^10.5.53", - "squizlabs/php_codesniffer": "^3.13.4" - }, - "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-12-02T21:04:28+00:00" - }, - { - "name": "nette/schema", - "version": "v1.3.3", - "source": { - "type": "git", - "url": "https://github.com/nette/schema.git", - "reference": "2befc2f42d7c715fd9d95efc31b1081e5d765004" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nette/schema/zipball/2befc2f42d7c715fd9d95efc31b1081e5d765004", - "reference": "2befc2f42d7c715fd9d95efc31b1081e5d765004", - "shasum": "" - }, - "require": { - "nette/utils": "^4.0", - "php": "8.1 - 8.5" - }, - "require-dev": { - "nette/tester": "^2.5.2", - "phpstan/phpstan-nette": "^2.0@stable", - "tracy/tracy": "^2.8" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.3-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 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.3" - }, - "time": "2025-10-30T22:57:59+00:00" - }, - { - "name": "nette/utils", - "version": "v4.1.1", - "source": { - "type": "git", - "url": "https://github.com/nette/utils.git", - "reference": "c99059c0315591f1a0db7ad6002000288ab8dc72" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nette/utils/zipball/c99059c0315591f1a0db7ad6002000288ab8dc72", - "reference": "c99059c0315591f1a0db7ad6002000288ab8dc72", - "shasum": "" - }, - "require": { - "php": "8.2 - 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.1-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.1.1" - }, - "time": "2025-12-22T12:14:32+00:00" - }, - { - "name": "nicmart/tree", - "version": "0.10.1", - "source": { - "type": "git", - "url": "https://github.com/nicmart/Tree.git", - "reference": "2ef11e329d26005ef49dbacd0223bcfd2515b6cc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nicmart/Tree/zipball/2ef11e329d26005ef49dbacd0223bcfd2515b6cc", - "reference": "2ef11e329d26005ef49dbacd0223bcfd2515b6cc", - "shasum": "" - }, - "require": { - "php": "~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0" - }, - "require-dev": { - "ergebnis/composer-normalize": "^2.48.2", - "ergebnis/license": "^2.7.0", - "ergebnis/php-cs-fixer-config": "^6.28.1", - "fakerphp/faker": "^1.24.1", - "infection/infection": "~0.26.19", - "phpunit/phpunit": "^9.6.19", - "psalm/plugin-phpunit": "~0.19.0", - "vimeo/psalm": "^5.26.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Tree\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolò Martini", - "email": "nicmartnic@gmail.com" - }, - { - "name": "Andreas Möller", - "email": "am@localheinz.com" - } - ], - "description": "A basic but flexible php tree data structure and a fluent tree builder implementation.", - "support": { - "issues": "https://github.com/nicmart/Tree/issues", - "source": "https://github.com/nicmart/Tree/tree/0.10.1" - }, - "time": "2025-11-25T08:51:01+00:00" - }, - { - "name": "nikic/php-parser", - "version": "v5.7.0", - "source": { - "type": "git", - "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/dca41cd15c2ac9d055ad70dbfd011130757d1f82", - "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82", - "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.x-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.7.0" - }, - "time": "2025-12-06T11:56:16+00:00" - }, - { - "name": "nunomaduro/termwind", - "version": "v2.3.3", - "source": { - "type": "git", - "url": "https://github.com/nunomaduro/termwind.git", - "reference": "6fb2a640ff502caace8e05fd7be3b503a7e1c017" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nunomaduro/termwind/zipball/6fb2a640ff502caace8e05fd7be3b503a7e1c017", - "reference": "6fb2a640ff502caace8e05fd7be3b503a7e1c017", - "shasum": "" - }, - "require": { - "ext-mbstring": "*", - "php": "^8.2", - "symfony/console": "^7.3.6" - }, - "require-dev": { - "illuminate/console": "^11.46.1", - "laravel/pint": "^1.25.1", - "mockery/mockery": "^1.6.12", - "pestphp/pest": "^2.36.0 || ^3.8.4 || ^4.1.3", - "phpstan/phpstan": "^1.12.32", - "phpstan/phpstan-strict-rules": "^1.6.2", - "symfony/var-dumper": "^7.3.5", - "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.3" - }, - "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-11-20T02:34:59+00:00" - }, - { - "name": "paragonie/constant_time_encoding", - "version": "v3.1.3", - "source": { - "type": "git", - "url": "https://github.com/paragonie/constant_time_encoding.git", - "reference": "d5b01a39b3415c2cd581d3bd3a3575c1ebbd8e77" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/d5b01a39b3415c2cd581d3bd3a3575c1ebbd8e77", - "reference": "d5b01a39b3415c2cd581d3bd3a3575c1ebbd8e77", - "shasum": "" - }, - "require": { - "php": "^8" - }, - "require-dev": { - "infection/infection": "^0", - "nikic/php-fuzzer": "^0", - "phpunit/phpunit": "^9|^10|^11", - "vimeo/psalm": "^4|^5|^6" - }, - "type": "library", - "autoload": { - "psr-4": { - "ParagonIE\\ConstantTime\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Paragon Initiative Enterprises", - "email": "security@paragonie.com", - "homepage": "https://paragonie.com", - "role": "Maintainer" - }, - { - "name": "Steve 'Sc00bz' Thomas", - "email": "steve@tobtu.com", - "homepage": "https://www.tobtu.com", - "role": "Original Developer" - } - ], - "description": "Constant-time Implementations of RFC 4648 Encoding (Base-64, Base-32, Base-16)", - "keywords": [ - "base16", - "base32", - "base32_decode", - "base32_encode", - "base64", - "base64_decode", - "base64_encode", - "bin2hex", - "encoding", - "hex", - "hex2bin", - "rfc4648" - ], - "support": { - "email": "info@paragonie.com", - "issues": "https://github.com/paragonie/constant_time_encoding/issues", - "source": "https://github.com/paragonie/constant_time_encoding" - }, - "time": "2025-09-24T15:06:41+00:00" - }, - { - "name": "phpdocumentor/reflection", - "version": "6.4.4", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/Reflection.git", - "reference": "5e5db15b34e6eae755cb97beaa7fe076ae9e8d4c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/Reflection/zipball/5e5db15b34e6eae755cb97beaa7fe076ae9e8d4c", - "reference": "5e5db15b34e6eae755cb97beaa7fe076ae9e8d4c", - "shasum": "" - }, - "require": { - "composer-runtime-api": "^2", - "nikic/php-parser": "~4.18 || ^5.0", - "php": "8.1.*|8.2.*|8.3.*|8.4.*|8.5.*", - "phpdocumentor/reflection-common": "^2.1", - "phpdocumentor/reflection-docblock": "^5", - "phpdocumentor/type-resolver": "^1.4", - "symfony/polyfill-php80": "^1.28", - "webmozart/assert": "^1.7" - }, - "require-dev": { - "dealerdirect/phpcodesniffer-composer-installer": "^1.0", - "doctrine/coding-standard": "^13.0", - "eliashaeussler/phpunit-attributes": "^1.8", - "mikey179/vfsstream": "~1.2", - "mockery/mockery": "~1.6.0", - "phpspec/prophecy-phpunit": "^2.4", - "phpstan/extension-installer": "^1.1", - "phpstan/phpstan": "^1.8", - "phpstan/phpstan-webmozart-assert": "^1.2", - "phpunit/phpunit": "^10.5.53", - "psalm/phar": "^6.0", - "rector/rector": "^1.0.0", - "squizlabs/php_codesniffer": "^3.8" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-5.x": "5.3.x-dev", - "dev-6.x": "6.0.x-dev" - } - }, - "autoload": { - "files": [ - "src/php-parser/Modifiers.php" - ], - "psr-4": { - "phpDocumentor\\": "src/phpDocumentor" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Reflection library to do Static Analysis for PHP Projects", - "homepage": "http://www.phpdoc.org", - "keywords": [ - "phpDocumentor", - "phpdoc", - "reflection", - "static analysis" - ], - "support": { - "issues": "https://github.com/phpDocumentor/Reflection/issues", - "source": "https://github.com/phpDocumentor/Reflection/tree/6.4.4" - }, - "time": "2025-11-25T21:21:18+00:00" - }, - { - "name": "phpdocumentor/reflection-common", - "version": "2.2.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionCommon.git", - "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", - "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-2.x": "2.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jaap van Otterdijk", - "email": "opensource@ijaap.nl" - } - ], - "description": "Common reflection classes used by phpdocumentor to reflect the code structure", - "homepage": "http://www.phpdoc.org", - "keywords": [ - "FQSEN", - "phpDocumentor", - "phpdoc", - "reflection", - "static analysis" - ], - "support": { - "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", - "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" - }, - "time": "2020-06-27T09:03:43+00:00" - }, - { - "name": "phpdocumentor/reflection-docblock", - "version": "5.6.6", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "5cee1d3dfc2d2aa6599834520911d246f656bcb8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/5cee1d3dfc2d2aa6599834520911d246f656bcb8", - "reference": "5cee1d3dfc2d2aa6599834520911d246f656bcb8", - "shasum": "" - }, - "require": { - "doctrine/deprecations": "^1.1", - "ext-filter": "*", - "php": "^7.4 || ^8.0", - "phpdocumentor/reflection-common": "^2.2", - "phpdocumentor/type-resolver": "^1.7", - "phpstan/phpdoc-parser": "^1.7|^2.0", - "webmozart/assert": "^1.9.1 || ^2" - }, - "require-dev": { - "mockery/mockery": "~1.3.5 || ~1.6.0", - "phpstan/extension-installer": "^1.1", - "phpstan/phpstan": "^1.8", - "phpstan/phpstan-mockery": "^1.1", - "phpstan/phpstan-webmozart-assert": "^1.2", - "phpunit/phpunit": "^9.5", - "psalm/phar": "^5.26" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - }, - { - "name": "Jaap van Otterdijk", - "email": "opensource@ijaap.nl" - } - ], - "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "support": { - "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", - "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.6.6" - }, - "time": "2025-12-22T21:13:58+00:00" - }, - { - "name": "phpdocumentor/type-resolver", - "version": "1.12.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "92a98ada2b93d9b201a613cb5a33584dde25f195" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/92a98ada2b93d9b201a613cb5a33584dde25f195", - "reference": "92a98ada2b93d9b201a613cb5a33584dde25f195", - "shasum": "" - }, - "require": { - "doctrine/deprecations": "^1.0", - "php": "^7.3 || ^8.0", - "phpdocumentor/reflection-common": "^2.0", - "phpstan/phpdoc-parser": "^1.18|^2.0" - }, - "require-dev": { - "ext-tokenizer": "*", - "phpbench/phpbench": "^1.2", - "phpstan/extension-installer": "^1.1", - "phpstan/phpstan": "^1.8", - "phpstan/phpstan-phpunit": "^1.1", - "phpunit/phpunit": "^9.5", - "rector/rector": "^0.13.9", - "vimeo/psalm": "^4.25" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-1.x": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - } - ], - "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", - "support": { - "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.12.0" - }, - "time": "2025-11-21T15:09:14+00:00" - }, - { - "name": "phpoption/phpoption", - "version": "1.9.5", - "source": { - "type": "git", - "url": "https://github.com/schmittjoh/php-option.git", - "reference": "75365b91986c2405cf5e1e012c5595cd487a98be" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/75365b91986c2405cf5e1e012c5595cd487a98be", - "reference": "75365b91986c2405cf5e1e012c5595cd487a98be", - "shasum": "" - }, - "require": { - "php": "^7.2.5 || ^8.0" - }, - "require-dev": { - "bamarni/composer-bin-plugin": "^1.8.2", - "phpunit/phpunit": "^8.5.44 || ^9.6.25 || ^10.5.53 || ^11.5.34" - }, - "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.5" - }, - "funding": [ - { - "url": "https://github.com/GrahamCampbell", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/phpoption/phpoption", - "type": "tidelift" - } - ], - "time": "2025-12-27T19:41:33+00:00" - }, - { - "name": "phpstan/phpdoc-parser", - "version": "2.3.1", - "source": { - "type": "git", - "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "16dbf9937da8d4528ceb2145c9c7c0bd29e26374" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/16dbf9937da8d4528ceb2145c9c7c0bd29e26374", - "reference": "16dbf9937da8d4528ceb2145c9c7c0bd29e26374", - "shasum": "" - }, - "require": { - "php": "^7.4 || ^8.0" - }, - "require-dev": { - "doctrine/annotations": "^2.0", - "nikic/php-parser": "^5.3.0", - "php-parallel-lint/php-parallel-lint": "^1.2", - "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "^2.0", - "phpstan/phpstan-phpunit": "^2.0", - "phpstan/phpstan-strict-rules": "^2.0", - "phpunit/phpunit": "^9.6", - "symfony/process": "^5.2" - }, - "type": "library", - "autoload": { - "psr-4": { - "PHPStan\\PhpDocParser\\": [ - "src/" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "PHPDoc parser with support for nullable, intersection and generic types", - "support": { - "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/2.3.1" - }, - "time": "2026-01-12T11:33:04+00:00" - }, - { - "name": "pragmarx/google2fa", - "version": "v9.0.0", - "source": { - "type": "git", - "url": "https://github.com/antonioribeiro/google2fa.git", - "reference": "e6bc62dd6ae83acc475f57912e27466019a1f2cf" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/antonioribeiro/google2fa/zipball/e6bc62dd6ae83acc475f57912e27466019a1f2cf", - "reference": "e6bc62dd6ae83acc475f57912e27466019a1f2cf", - "shasum": "" - }, - "require": { - "paragonie/constant_time_encoding": "^1.0|^2.0|^3.0", - "php": "^7.1|^8.0" - }, - "require-dev": { - "phpstan/phpstan": "^1.9", - "phpunit/phpunit": "^7.5.15|^8.5|^9.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "PragmaRX\\Google2FA\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Antonio Carlos Ribeiro", - "email": "acr@antoniocarlosribeiro.com", - "role": "Creator & Designer" - } - ], - "description": "A One Time Password Authentication package, compatible with Google Authenticator.", - "keywords": [ - "2fa", - "Authentication", - "Two Factor Authentication", - "google2fa" - ], - "support": { - "issues": "https://github.com/antonioribeiro/google2fa/issues", - "source": "https://github.com/antonioribeiro/google2fa/tree/v9.0.0" - }, - "time": "2025-09-19T22:51:08+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.18", - "source": { - "type": "git", - "url": "https://github.com/bobthecow/psysh.git", - "reference": "ddff0ac01beddc251786fe70367cd8bbdb258196" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/bobthecow/psysh/zipball/ddff0ac01beddc251786fe70367cd8bbdb258196", - "reference": "ddff0ac01beddc251786fe70367cd8bbdb258196", - "shasum": "" - }, - "require": { - "ext-json": "*", - "ext-tokenizer": "*", - "nikic/php-parser": "^5.0 || ^4.0", - "php": "^8.0 || ^7.4", - "symfony/console": "^8.0 || ^7.0 || ^6.0 || ^5.0 || ^4.0 || ^3.4", - "symfony/var-dumper": "^8.0 || ^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", - "composer/class-map-generator": "^1.6" - }, - "suggest": { - "composer/class-map-generator": "Improved tab completion performance with better class discovery.", - "ext-pcntl": "Enabling the PCNTL extension makes PsySH a lot happier :)", - "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.18" - }, - "time": "2025-12-17T14:35:46+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.2", - "source": { - "type": "git", - "url": "https://github.com/ramsey/uuid.git", - "reference": "8429c78ca35a09f27565311b98101e2826affde0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/ramsey/uuid/zipball/8429c78ca35a09f27565311b98101e2826affde0", - "reference": "8429c78ca35a09f27565311b98101e2826affde0", - "shasum": "" - }, - "require": { - "brick/math": "^0.8.16 || ^0.9 || ^0.10 || ^0.11 || ^0.12 || ^0.13 || ^0.14", - "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.2" - }, - "time": "2025-12-14T04:43:48+00:00" - }, - { - "name": "spatie/browsershot", - "version": "5.2.0", - "source": { - "type": "git", - "url": "https://github.com/spatie/browsershot.git", - "reference": "9bc6b8d67175810d7a399b2588c3401efe2d02a8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/spatie/browsershot/zipball/9bc6b8d67175810d7a399b2588c3401efe2d02a8", - "reference": "9bc6b8d67175810d7a399b2588c3401efe2d02a8", - "shasum": "" - }, - "require": { - "ext-fileinfo": "*", - "ext-json": "*", - "php": "^8.2", - "spatie/temporary-directory": "^2.0", - "symfony/process": "^6.0|^7.0|^8.0" - }, - "require-dev": { - "pestphp/pest": "^3.0|^4.0", - "spatie/image": "^3.6", - "spatie/pdf-to-text": "^1.52", - "spatie/phpunit-snapshot-assertions": "^5.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Spatie\\Browsershot\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Freek Van der Herten", - "email": "freek@spatie.be", - "homepage": "https://github.com/freekmurze", - "role": "Developer" - } - ], - "description": "Convert a webpage to an image or pdf using headless Chrome", - "homepage": "https://github.com/spatie/browsershot", - "keywords": [ - "chrome", - "convert", - "headless", - "image", - "pdf", - "puppeteer", - "screenshot", - "webpage" - ], - "support": { - "source": "https://github.com/spatie/browsershot/tree/5.2.0" - }, - "funding": [ - { - "url": "https://github.com/spatie", - "type": "github" - } - ], - "time": "2025-12-22T10:02:16+00:00" - }, - { - "name": "spatie/crawler", - "version": "8.4.7", - "source": { - "type": "git", - "url": "https://github.com/spatie/crawler.git", - "reference": "67cbd569437d0e35b1332c5f21d009cac8b4a37b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/spatie/crawler/zipball/67cbd569437d0e35b1332c5f21d009cac8b4a37b", - "reference": "67cbd569437d0e35b1332c5f21d009cac8b4a37b", - "shasum": "" - }, - "require": { - "guzzlehttp/guzzle": "^7.3", - "guzzlehttp/psr7": "^2.0", - "illuminate/collections": "^10.0|^11.0|^12.0", - "nicmart/tree": "^0.10", - "php": "^8.2", - "spatie/browsershot": "^5.0.5", - "spatie/robots-txt": "^2.0", - "symfony/dom-crawler": "^6.0|^7.0|^8.0" - }, - "require-dev": { - "pestphp/pest": "^2.0|^3.0", - "spatie/ray": "^1.37" - }, - "type": "library", - "autoload": { - "psr-4": { - "Spatie\\Crawler\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Freek Van der Herten", - "email": "freek@spatie.be" - } - ], - "description": "Crawl all internal links found on a website", - "homepage": "https://github.com/spatie/crawler", - "keywords": [ - "crawler", - "link", - "spatie", - "website" - ], - "support": { - "issues": "https://github.com/spatie/crawler/issues", - "source": "https://github.com/spatie/crawler/tree/8.4.7" - }, - "funding": [ - { - "url": "https://spatie.be/open-source/support-us", - "type": "custom" - }, - { - "url": "https://github.com/spatie", - "type": "github" - } - ], - "time": "2025-11-26T17:35:15+00:00" - }, - { - "name": "spatie/laravel-data", - "version": "4.18.0", - "source": { - "type": "git", - "url": "https://github.com/spatie/laravel-data.git", - "reference": "c10784f1133d540a702bd6db36ed659f4bc0606a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/spatie/laravel-data/zipball/c10784f1133d540a702bd6db36ed659f4bc0606a", - "reference": "c10784f1133d540a702bd6db36ed659f4bc0606a", - "shasum": "" - }, - "require": { - "illuminate/contracts": "^10.0|^11.0|^12.0", - "php": "^8.1", - "phpdocumentor/reflection": "^6.0", - "spatie/laravel-package-tools": "^1.9.0", - "spatie/php-structure-discoverer": "^2.0" - }, - "require-dev": { - "fakerphp/faker": "^1.14", - "friendsofphp/php-cs-fixer": "^3.0", - "inertiajs/inertia-laravel": "^2.0", - "livewire/livewire": "^3.0", - "mockery/mockery": "^1.6", - "nesbot/carbon": "^2.63|^3.0", - "orchestra/testbench": "^8.0|^9.0|^10.0", - "pestphp/pest": "^2.31|^3.0", - "pestphp/pest-plugin-laravel": "^2.0|^3.0", - "pestphp/pest-plugin-livewire": "^2.1|^3.0", - "phpbench/phpbench": "^1.2", - "phpstan/extension-installer": "^1.1", - "phpunit/phpunit": "^10.0|^11.0|^12.0", - "spatie/invade": "^1.0", - "spatie/laravel-typescript-transformer": "^2.5", - "spatie/pest-plugin-snapshots": "^2.1", - "spatie/test-time": "^1.2" - }, - "type": "library", - "extra": { - "laravel": { - "providers": [ - "Spatie\\LaravelData\\LaravelDataServiceProvider" - ] - } - }, - "autoload": { - "psr-4": { - "Spatie\\LaravelData\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ruben Van Assche", - "email": "ruben@spatie.be", - "role": "Developer" - } - ], - "description": "Create unified resources and data transfer objects", - "homepage": "https://github.com/spatie/laravel-data", - "keywords": [ - "laravel", - "laravel-data", - "spatie" - ], - "support": { - "issues": "https://github.com/spatie/laravel-data/issues", - "source": "https://github.com/spatie/laravel-data/tree/4.18.0" - }, - "funding": [ - { - "url": "https://github.com/spatie", - "type": "github" - } - ], - "time": "2025-10-16T16:44:07+00:00" - }, - { - "name": "spatie/laravel-package-tools", - "version": "1.92.7", - "source": { - "type": "git", - "url": "https://github.com/spatie/laravel-package-tools.git", - "reference": "f09a799850b1ed765103a4f0b4355006360c49a5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/spatie/laravel-package-tools/zipball/f09a799850b1ed765103a4f0b4355006360c49a5", - "reference": "f09a799850b1ed765103a4f0b4355006360c49a5", - "shasum": "" - }, - "require": { - "illuminate/contracts": "^9.28|^10.0|^11.0|^12.0", - "php": "^8.0" - }, - "require-dev": { - "mockery/mockery": "^1.5", - "orchestra/testbench": "^7.7|^8.0|^9.0|^10.0", - "pestphp/pest": "^1.23|^2.1|^3.1", - "phpunit/php-code-coverage": "^9.0|^10.0|^11.0", - "phpunit/phpunit": "^9.5.24|^10.5|^11.5", - "spatie/pest-plugin-test-time": "^1.1|^2.2" - }, - "type": "library", - "autoload": { - "psr-4": { - "Spatie\\LaravelPackageTools\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Freek Van der Herten", - "email": "freek@spatie.be", - "role": "Developer" - } - ], - "description": "Tools for creating Laravel packages", - "homepage": "https://github.com/spatie/laravel-package-tools", - "keywords": [ - "laravel-package-tools", - "spatie" - ], - "support": { - "issues": "https://github.com/spatie/laravel-package-tools/issues", - "source": "https://github.com/spatie/laravel-package-tools/tree/1.92.7" - }, - "funding": [ - { - "url": "https://github.com/spatie", - "type": "github" - } - ], - "time": "2025-07-17T15:46:43+00:00" - }, - { - "name": "spatie/laravel-sitemap", - "version": "7.3.8", - "source": { - "type": "git", - "url": "https://github.com/spatie/laravel-sitemap.git", - "reference": "9ff614d4834ada564aed5ed88507c9e5baab8e51" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/spatie/laravel-sitemap/zipball/9ff614d4834ada564aed5ed88507c9e5baab8e51", - "reference": "9ff614d4834ada564aed5ed88507c9e5baab8e51", - "shasum": "" - }, - "require": { - "guzzlehttp/guzzle": "^7.8", - "illuminate/support": "^11.0|^12.0", - "nesbot/carbon": "^2.71|^3.0", - "php": "^8.2||^8.3||^8.4", - "spatie/crawler": "^8.0.1", - "spatie/laravel-package-tools": "^1.16.1", - "symfony/dom-crawler": "^6.3.4|^7.0|^8.0" - }, - "require-dev": { - "mockery/mockery": "^1.6.6", - "orchestra/testbench": "^9.0|^10.0", - "pestphp/pest": "^3.7.4", - "spatie/pest-plugin-snapshots": "^2.1", - "spatie/phpunit-snapshot-assertions": "^5.1.2", - "spatie/temporary-directory": "^2.2" - }, - "type": "library", - "extra": { - "laravel": { - "providers": [ - "Spatie\\Sitemap\\SitemapServiceProvider" - ] - } - }, - "autoload": { - "psr-4": { - "Spatie\\Sitemap\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Freek Van der Herten", - "email": "freek@spatie.be", - "homepage": "https://spatie.be", - "role": "Developer" - } - ], - "description": "Create and generate sitemaps with ease", - "homepage": "https://github.com/spatie/laravel-sitemap", - "keywords": [ - "laravel-sitemap", - "spatie" - ], - "support": { - "source": "https://github.com/spatie/laravel-sitemap/tree/7.3.8" - }, - "funding": [ - { - "url": "https://spatie.be/open-source/support-us", - "type": "custom" - } - ], - "time": "2025-11-25T21:06:08+00:00" - }, - { - "name": "spatie/laravel-sluggable", - "version": "3.7.5", - "source": { - "type": "git", - "url": "https://github.com/spatie/laravel-sluggable.git", - "reference": "e4fdd519e043a2af02b52eec2c3be2dd2e262e27" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/spatie/laravel-sluggable/zipball/e4fdd519e043a2af02b52eec2c3be2dd2e262e27", - "reference": "e4fdd519e043a2af02b52eec2c3be2dd2e262e27", - "shasum": "" - }, - "require": { - "illuminate/database": "^8.0|^9.0|^10.0|^11.0|^12.0", - "illuminate/support": "^8.0|^9.0|^10.0|^11.0|^12.0", - "php": "^8.0" - }, - "require-dev": { - "orchestra/testbench": "^6.23|^7.0|^8.0|^9.0|^10.0", - "pestphp/pest": "^1.20|^2.0|^3.7", - "spatie/laravel-translatable": "^5.0|^6.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Spatie\\Sluggable\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Freek Van der Herten", - "email": "freek@spatie.be", - "homepage": "https://spatie.be", - "role": "Developer" - } - ], - "description": "Generate slugs when saving Eloquent models", - "homepage": "https://github.com/spatie/laravel-sluggable", - "keywords": [ - "laravel-sluggable", - "spatie" - ], - "support": { - "source": "https://github.com/spatie/laravel-sluggable/tree/3.7.5" - }, - "funding": [ - { - "url": "https://github.com/spatie", - "type": "github" - } - ], - "time": "2025-04-24T09:21:00+00:00" - }, - { - "name": "spatie/php-structure-discoverer", - "version": "2.3.3", - "source": { - "type": "git", - "url": "https://github.com/spatie/php-structure-discoverer.git", - "reference": "552a5b974a9853a32e5677a66e85ae615a96a90b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/spatie/php-structure-discoverer/zipball/552a5b974a9853a32e5677a66e85ae615a96a90b", - "reference": "552a5b974a9853a32e5677a66e85ae615a96a90b", - "shasum": "" - }, - "require": { - "illuminate/collections": "^11.0|^12.0", - "php": "^8.3", - "spatie/laravel-package-tools": "^1.92.7", - "symfony/finder": "^6.0|^7.3.5|^8.0" - }, - "require-dev": { - "amphp/parallel": "^2.3.2", - "illuminate/console": "^11.0|^12.0", - "nunomaduro/collision": "^7.0|^8.8.3", - "orchestra/testbench": "^9.5|^10.8", - "pestphp/pest": "^3.8|^4.0", - "pestphp/pest-plugin-laravel": "^3.2|^4.0", - "phpstan/extension-installer": "^1.4.3", - "phpstan/phpstan-deprecation-rules": "^1.2.1", - "phpstan/phpstan-phpunit": "^1.4.2", - "spatie/laravel-ray": "^1.43.1" - }, - "suggest": { - "amphp/parallel": "When you want to use the Parallel discover worker" - }, - "type": "library", - "extra": { - "laravel": { - "providers": [ - "Spatie\\StructureDiscoverer\\StructureDiscovererServiceProvider" - ] - } - }, - "autoload": { - "psr-4": { - "Spatie\\StructureDiscoverer\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ruben Van Assche", - "email": "ruben@spatie.be", - "role": "Developer" - } - ], - "description": "Automatically discover structures within your PHP application", - "homepage": "https://github.com/spatie/php-structure-discoverer", - "keywords": [ - "discover", - "laravel", - "php", - "php-structure-discoverer" - ], - "support": { - "issues": "https://github.com/spatie/php-structure-discoverer/issues", - "source": "https://github.com/spatie/php-structure-discoverer/tree/2.3.3" - }, - "funding": [ - { - "url": "https://github.com/LaravelAutoDiscoverer", - "type": "github" - } - ], - "time": "2025-11-24T16:41:01+00:00" - }, - { - "name": "spatie/robots-txt", - "version": "2.5.3", - "source": { - "type": "git", - "url": "https://github.com/spatie/robots-txt.git", - "reference": "edb91c798ec70583d41c131019da45fa167af5e8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/spatie/robots-txt/zipball/edb91c798ec70583d41c131019da45fa167af5e8", - "reference": "edb91c798ec70583d41c131019da45fa167af5e8", - "shasum": "" - }, - "require": { - "php": "^8.1" - }, - "require-dev": { - "phpunit/phpunit": "^11.5.2" - }, - "type": "library", - "autoload": { - "psr-4": { - "Spatie\\Robots\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Brent Roose", - "email": "brent@spatie.be", - "homepage": "https://spatie.be", - "role": "Developer" - } - ], - "description": "Determine if a page may be crawled from robots.txt and robots meta tags", - "homepage": "https://github.com/spatie/robots-txt", - "keywords": [ - "robots-txt", - "spatie" - ], - "support": { - "issues": "https://github.com/spatie/robots-txt/issues", - "source": "https://github.com/spatie/robots-txt/tree/2.5.3" - }, - "funding": [ - { - "url": "https://spatie.be/open-source/support-us", - "type": "custom" - }, - { - "url": "https://github.com/spatie", - "type": "github" - } - ], - "time": "2025-11-20T13:00:33+00:00" - }, - { - "name": "spatie/temporary-directory", - "version": "2.3.1", - "source": { - "type": "git", - "url": "https://github.com/spatie/temporary-directory.git", - "reference": "662e481d6ec07ef29fd05010433428851a42cd07" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/spatie/temporary-directory/zipball/662e481d6ec07ef29fd05010433428851a42cd07", - "reference": "662e481d6ec07ef29fd05010433428851a42cd07", - "shasum": "" - }, - "require": { - "php": "^8.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.5" - }, - "type": "library", - "autoload": { - "psr-4": { - "Spatie\\TemporaryDirectory\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Alex Vanderbist", - "email": "alex@spatie.be", - "homepage": "https://spatie.be", - "role": "Developer" - } - ], - "description": "Easily create, use and destroy temporary directories", - "homepage": "https://github.com/spatie/temporary-directory", - "keywords": [ - "php", - "spatie", - "temporary-directory" - ], - "support": { - "issues": "https://github.com/spatie/temporary-directory/issues", - "source": "https://github.com/spatie/temporary-directory/tree/2.3.1" - }, - "funding": [ - { - "url": "https://spatie.be/open-source/support-us", - "type": "custom" - }, - { - "url": "https://github.com/spatie", - "type": "github" - } - ], - "time": "2026-01-12T07:42:22+00:00" - }, - { - "name": "spatie/yaml-front-matter", - "version": "2.1.1", - "source": { - "type": "git", - "url": "https://github.com/spatie/yaml-front-matter.git", - "reference": "3066996d0e4ed74bcc22c261084a9df727bf7e36" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/spatie/yaml-front-matter/zipball/3066996d0e4ed74bcc22c261084a9df727bf7e36", - "reference": "3066996d0e4ed74bcc22c261084a9df727bf7e36", - "shasum": "" - }, - "require": { - "php": "^8.0", - "symfony/yaml": "^6.0|^7.0|^8.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Spatie\\YamlFrontMatter\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Sebastian De Deyne", - "email": "sebastian@spatie.be", - "homepage": "https://spatie.be", - "role": "Developer" - } - ], - "description": "A to the point yaml front matter parser", - "homepage": "https://github.com/sebastiandedeyne/yaml-front-matter", - "keywords": [ - "front matter", - "jekyll", - "spatie", - "yaml" - ], - "support": { - "source": "https://github.com/spatie/yaml-front-matter/tree/2.1.1" - }, - "funding": [ - { - "url": "https://spatie.be/open-source/support-us", - "type": "custom" - }, - { - "url": "https://github.com/spatie", - "type": "github" - } - ], - "time": "2025-11-24T16:17:28+00:00" - }, - { - "name": "symfony/clock", - "version": "v8.0.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/clock.git", - "reference": "832119f9b8dbc6c8e6f65f30c5969eca1e88764f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/clock/zipball/832119f9b8dbc6c8e6f65f30c5969eca1e88764f", - "reference": "832119f9b8dbc6c8e6f65f30c5969eca1e88764f", - "shasum": "" - }, - "require": { - "php": ">=8.4", - "psr/clock": "^1.0" - }, - "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/v8.0.0" - }, - "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-11-12T15:46:48+00:00" - }, - { - "name": "symfony/console", - "version": "v7.4.3", - "source": { - "type": "git", - "url": "https://github.com/symfony/console.git", - "reference": "732a9ca6cd9dfd940c639062d5edbde2f6727fb6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/732a9ca6cd9dfd940c639062d5edbde2f6727fb6", - "reference": "732a9ca6cd9dfd940c639062d5edbde2f6727fb6", - "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|^8.0" - }, - "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|^8.0", - "symfony/dependency-injection": "^6.4|^7.0|^8.0", - "symfony/event-dispatcher": "^6.4|^7.0|^8.0", - "symfony/http-foundation": "^6.4|^7.0|^8.0", - "symfony/http-kernel": "^6.4|^7.0|^8.0", - "symfony/lock": "^6.4|^7.0|^8.0", - "symfony/messenger": "^6.4|^7.0|^8.0", - "symfony/process": "^6.4|^7.0|^8.0", - "symfony/stopwatch": "^6.4|^7.0|^8.0", - "symfony/var-dumper": "^6.4|^7.0|^8.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.4.3" - }, - "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-12-23T14:50:43+00:00" - }, - { - "name": "symfony/css-selector", - "version": "v8.0.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/css-selector.git", - "reference": "6225bd458c53ecdee056214cb4a2ffaf58bd592b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/6225bd458c53ecdee056214cb4a2ffaf58bd592b", - "reference": "6225bd458c53ecdee056214cb4a2ffaf58bd592b", - "shasum": "" - }, - "require": { - "php": ">=8.4" - }, - "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/v8.0.0" - }, - "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-10-30T14:17:19+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/dom-crawler", - "version": "v8.0.1", - "source": { - "type": "git", - "url": "https://github.com/symfony/dom-crawler.git", - "reference": "11a3dbe6f6c0ae03ae71f879cf5c2e28db107179" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/11a3dbe6f6c0ae03ae71f879cf5c2e28db107179", - "reference": "11a3dbe6f6c0ae03ae71f879cf5c2e28db107179", - "shasum": "" - }, - "require": { - "php": ">=8.4", - "symfony/polyfill-ctype": "^1.8", - "symfony/polyfill-mbstring": "^1.0" - }, - "require-dev": { - "symfony/css-selector": "^7.4|^8.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\DomCrawler\\": "" - }, - "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 DOM navigation for HTML and XML documents", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/dom-crawler/tree/v8.0.1" - }, - "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-12-06T17:00:47+00:00" - }, - { - "name": "symfony/error-handler", - "version": "v7.4.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/error-handler.git", - "reference": "48be2b0653594eea32dcef130cca1c811dcf25c2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/48be2b0653594eea32dcef130cca1c811dcf25c2", - "reference": "48be2b0653594eea32dcef130cca1c811dcf25c2", - "shasum": "" - }, - "require": { - "php": ">=8.2", - "psr/log": "^1|^2|^3", - "symfony/polyfill-php85": "^1.32", - "symfony/var-dumper": "^6.4|^7.0|^8.0" - }, - "conflict": { - "symfony/deprecation-contracts": "<2.5", - "symfony/http-kernel": "<6.4" - }, - "require-dev": { - "symfony/console": "^6.4|^7.0|^8.0", - "symfony/deprecation-contracts": "^2.5|^3", - "symfony/http-kernel": "^6.4|^7.0|^8.0", - "symfony/serializer": "^6.4|^7.0|^8.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.4.0" - }, - "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-11-05T14:29:59+00:00" - }, - { - "name": "symfony/event-dispatcher", - "version": "v8.0.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "573f95783a2ec6e38752979db139f09fec033f03" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/573f95783a2ec6e38752979db139f09fec033f03", - "reference": "573f95783a2ec6e38752979db139f09fec033f03", - "shasum": "" - }, - "require": { - "php": ">=8.4", - "symfony/event-dispatcher-contracts": "^2.5|^3" - }, - "conflict": { - "symfony/security-http": "<7.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": "^7.4|^8.0", - "symfony/dependency-injection": "^7.4|^8.0", - "symfony/error-handler": "^7.4|^8.0", - "symfony/expression-language": "^7.4|^8.0", - "symfony/framework-bundle": "^7.4|^8.0", - "symfony/http-foundation": "^7.4|^8.0", - "symfony/service-contracts": "^2.5|^3", - "symfony/stopwatch": "^7.4|^8.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/v8.0.0" - }, - "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-10-30T14:17:19+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.4.3", - "source": { - "type": "git", - "url": "https://github.com/symfony/finder.git", - "reference": "fffe05569336549b20a1be64250b40516d6e8d06" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/fffe05569336549b20a1be64250b40516d6e8d06", - "reference": "fffe05569336549b20a1be64250b40516d6e8d06", - "shasum": "" - }, - "require": { - "php": ">=8.2" - }, - "require-dev": { - "symfony/filesystem": "^6.4|^7.0|^8.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.4.3" - }, - "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-12-23T14:50:43+00:00" - }, - { - "name": "symfony/http-foundation", - "version": "v7.4.3", - "source": { - "type": "git", - "url": "https://github.com/symfony/http-foundation.git", - "reference": "a70c745d4cea48dbd609f4075e5f5cbce453bd52" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/a70c745d4cea48dbd609f4075e5f5cbce453bd52", - "reference": "a70c745d4cea48dbd609f4075e5f5cbce453bd52", - "shasum": "" - }, - "require": { - "php": ">=8.2", - "symfony/deprecation-contracts": "^2.5|^3", - "symfony/polyfill-mbstring": "^1.1" - }, - "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|^8.0", - "symfony/clock": "^6.4|^7.0|^8.0", - "symfony/dependency-injection": "^6.4|^7.0|^8.0", - "symfony/expression-language": "^6.4|^7.0|^8.0", - "symfony/http-kernel": "^6.4|^7.0|^8.0", - "symfony/mime": "^6.4|^7.0|^8.0", - "symfony/rate-limiter": "^6.4|^7.0|^8.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.4.3" - }, - "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-12-23T14:23:49+00:00" - }, - { - "name": "symfony/http-kernel", - "version": "v7.4.3", - "source": { - "type": "git", - "url": "https://github.com/symfony/http-kernel.git", - "reference": "885211d4bed3f857b8c964011923528a55702aa5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/885211d4bed3f857b8c964011923528a55702aa5", - "reference": "885211d4bed3f857b8c964011923528a55702aa5", - "shasum": "" - }, - "require": { - "php": ">=8.2", - "psr/log": "^1|^2|^3", - "symfony/deprecation-contracts": "^2.5|^3", - "symfony/error-handler": "^6.4|^7.0|^8.0", - "symfony/event-dispatcher": "^7.3|^8.0", - "symfony/http-foundation": "^7.4|^8.0", - "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/flex": "<2.10", - "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|^8.0", - "symfony/clock": "^6.4|^7.0|^8.0", - "symfony/config": "^6.4|^7.0|^8.0", - "symfony/console": "^6.4|^7.0|^8.0", - "symfony/css-selector": "^6.4|^7.0|^8.0", - "symfony/dependency-injection": "^6.4|^7.0|^8.0", - "symfony/dom-crawler": "^6.4|^7.0|^8.0", - "symfony/expression-language": "^6.4|^7.0|^8.0", - "symfony/finder": "^6.4|^7.0|^8.0", - "symfony/http-client-contracts": "^2.5|^3", - "symfony/process": "^6.4|^7.0|^8.0", - "symfony/property-access": "^7.1|^8.0", - "symfony/routing": "^6.4|^7.0|^8.0", - "symfony/serializer": "^7.1|^8.0", - "symfony/stopwatch": "^6.4|^7.0|^8.0", - "symfony/translation": "^6.4|^7.0|^8.0", - "symfony/translation-contracts": "^2.5|^3", - "symfony/uid": "^6.4|^7.0|^8.0", - "symfony/validator": "^6.4|^7.0|^8.0", - "symfony/var-dumper": "^6.4|^7.0|^8.0", - "symfony/var-exporter": "^6.4|^7.0|^8.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.4.3" - }, - "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-12-31T08:43:57+00:00" - }, - { - "name": "symfony/mailer", - "version": "v7.4.3", - "source": { - "type": "git", - "url": "https://github.com/symfony/mailer.git", - "reference": "e472d35e230108231ccb7f51eb6b2100cac02ee4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/mailer/zipball/e472d35e230108231ccb7f51eb6b2100cac02ee4", - "reference": "e472d35e230108231ccb7f51eb6b2100cac02ee4", - "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|^8.0", - "symfony/mime": "^7.2|^8.0", - "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|^8.0", - "symfony/http-client": "^6.4|^7.0|^8.0", - "symfony/messenger": "^6.4|^7.0|^8.0", - "symfony/twig-bridge": "^6.4|^7.0|^8.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.4.3" - }, - "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-12-16T08:02:06+00:00" - }, - { - "name": "symfony/mime", - "version": "v7.4.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/mime.git", - "reference": "bdb02729471be5d047a3ac4a69068748f1a6be7a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/bdb02729471be5d047a3ac4a69068748f1a6be7a", - "reference": "bdb02729471be5d047a3ac4a69068748f1a6be7a", - "shasum": "" - }, - "require": { - "php": ">=8.2", - "symfony/deprecation-contracts": "^2.5|^3", - "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|^8.0", - "symfony/process": "^6.4|^7.0|^8.0", - "symfony/property-access": "^6.4|^7.0|^8.0", - "symfony/property-info": "^6.4|^7.0|^8.0", - "symfony/serializer": "^6.4.3|^7.0.3|^8.0" - }, - "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.4.0" - }, - "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-11-16T10:14:42+00:00" - }, - { - "name": "symfony/polyfill-ctype", - "version": "v1.33.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.33.0" - }, - "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": "2024-09-09T11:45:10+00:00" - }, - { - "name": "symfony/polyfill-intl-grapheme", - "version": "v1.33.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "380872130d3a5dd3ace2f4010d95125fde5d5c70" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/380872130d3a5dd3ace2f4010d95125fde5d5c70", - "reference": "380872130d3a5dd3ace2f4010d95125fde5d5c70", - "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.33.0" - }, - "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-06-27T09:58:17+00:00" - }, - { - "name": "symfony/polyfill-intl-idn", - "version": "v1.33.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.33.0" - }, - "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": "2024-09-10T14:38:51+00:00" - }, - { - "name": "symfony/polyfill-intl-normalizer", - "version": "v1.33.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.33.0" - }, - "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": "2024-09-09T11:45:10+00:00" - }, - { - "name": "symfony/polyfill-mbstring", - "version": "v1.33.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.33.0" - }, - "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": "2024-12-23T08:48:59+00:00" - }, - { - "name": "symfony/polyfill-php80", - "version": "v1.33.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.33.0" - }, - "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-01-02T08:10:11+00:00" - }, - { - "name": "symfony/polyfill-php83", - "version": "v1.33.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php83.git", - "reference": "17f6f9a6b1735c0f163024d959f700cfbc5155e5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/17f6f9a6b1735c0f163024d959f700cfbc5155e5", - "reference": "17f6f9a6b1735c0f163024d959f700cfbc5155e5", - "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.33.0" - }, - "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-08T02:45:35+00:00" - }, - { - "name": "symfony/polyfill-php84", - "version": "v1.33.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php84.git", - "reference": "d8ced4d875142b6a7426000426b8abc631d6b191" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php84/zipball/d8ced4d875142b6a7426000426b8abc631d6b191", - "reference": "d8ced4d875142b6a7426000426b8abc631d6b191", - "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\\Php84\\": "" - }, - "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.4+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php84/tree/v1.33.0" - }, - "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-06-24T13:30:11+00:00" - }, - { - "name": "symfony/polyfill-php85", - "version": "v1.33.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php85.git", - "reference": "d4e5fcd4ab3d998ab16c0db48e6cbb9a01993f91" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php85/zipball/d4e5fcd4ab3d998ab16c0db48e6cbb9a01993f91", - "reference": "d4e5fcd4ab3d998ab16c0db48e6cbb9a01993f91", - "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\\Php85\\": "" - }, - "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.5+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php85/tree/v1.33.0" - }, - "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-06-23T16:12:55+00:00" - }, - { - "name": "symfony/polyfill-uuid", - "version": "v1.33.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.33.0" - }, - "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": "2024-09-09T11:45:10+00:00" - }, - { - "name": "symfony/process", - "version": "v7.4.3", - "source": { - "type": "git", - "url": "https://github.com/symfony/process.git", - "reference": "2f8e1a6cdf590ca63715da4d3a7a3327404a523f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/2f8e1a6cdf590ca63715da4d3a7a3327404a523f", - "reference": "2f8e1a6cdf590ca63715da4d3a7a3327404a523f", - "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.4.3" - }, - "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-12-19T10:00:43+00:00" - }, - { - "name": "symfony/routing", - "version": "v7.4.3", - "source": { - "type": "git", - "url": "https://github.com/symfony/routing.git", - "reference": "5d3fd7adf8896c2fdb54e2f0f35b1bcbd9e45090" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/5d3fd7adf8896c2fdb54e2f0f35b1bcbd9e45090", - "reference": "5d3fd7adf8896c2fdb54e2f0f35b1bcbd9e45090", - "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|^8.0", - "symfony/dependency-injection": "^6.4|^7.0|^8.0", - "symfony/expression-language": "^6.4|^7.0|^8.0", - "symfony/http-foundation": "^6.4|^7.0|^8.0", - "symfony/yaml": "^6.4|^7.0|^8.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.4.3" - }, - "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-12-19T10:00:43+00:00" - }, - { - "name": "symfony/service-contracts", - "version": "v3.6.1", - "source": { - "type": "git", - "url": "https://github.com/symfony/service-contracts.git", - "reference": "45112560a3ba2d715666a509a0bc9521d10b6c43" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/45112560a3ba2d715666a509a0bc9521d10b6c43", - "reference": "45112560a3ba2d715666a509a0bc9521d10b6c43", - "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.1" - }, - "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:30:57+00:00" - }, - { - "name": "symfony/string", - "version": "v8.0.1", - "source": { - "type": "git", - "url": "https://github.com/symfony/string.git", - "reference": "ba65a969ac918ce0cc3edfac6cdde847eba231dc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/ba65a969ac918ce0cc3edfac6cdde847eba231dc", - "reference": "ba65a969ac918ce0cc3edfac6cdde847eba231dc", - "shasum": "" - }, - "require": { - "php": ">=8.4", - "symfony/polyfill-ctype": "^1.8", - "symfony/polyfill-intl-grapheme": "^1.33", - "symfony/polyfill-intl-normalizer": "^1.0", - "symfony/polyfill-mbstring": "^1.0" - }, - "conflict": { - "symfony/translation-contracts": "<2.5" - }, - "require-dev": { - "symfony/emoji": "^7.4|^8.0", - "symfony/http-client": "^7.4|^8.0", - "symfony/intl": "^7.4|^8.0", - "symfony/translation-contracts": "^2.5|^3.0", - "symfony/var-exporter": "^7.4|^8.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/v8.0.1" - }, - "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-12-01T09:13:36+00:00" - }, - { - "name": "symfony/translation", - "version": "v8.0.3", - "source": { - "type": "git", - "url": "https://github.com/symfony/translation.git", - "reference": "60a8f11f0e15c48f2cc47c4da53873bb5b62135d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/60a8f11f0e15c48f2cc47c4da53873bb5b62135d", - "reference": "60a8f11f0e15c48f2cc47c4da53873bb5b62135d", - "shasum": "" - }, - "require": { - "php": ">=8.4", - "symfony/polyfill-mbstring": "^1.0", - "symfony/translation-contracts": "^3.6.1" - }, - "conflict": { - "nikic/php-parser": "<5.0", - "symfony/http-client-contracts": "<2.5", - "symfony/service-contracts": "<2.5" - }, - "provide": { - "symfony/translation-implementation": "2.3|3.0" - }, - "require-dev": { - "nikic/php-parser": "^5.0", - "psr/log": "^1|^2|^3", - "symfony/config": "^7.4|^8.0", - "symfony/console": "^7.4|^8.0", - "symfony/dependency-injection": "^7.4|^8.0", - "symfony/finder": "^7.4|^8.0", - "symfony/http-client-contracts": "^2.5|^3.0", - "symfony/http-kernel": "^7.4|^8.0", - "symfony/intl": "^7.4|^8.0", - "symfony/polyfill-intl-icu": "^1.21", - "symfony/routing": "^7.4|^8.0", - "symfony/service-contracts": "^2.5|^3", - "symfony/yaml": "^7.4|^8.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/v8.0.3" - }, - "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-12-21T10:59:45+00:00" - }, - { - "name": "symfony/translation-contracts", - "version": "v3.6.1", - "source": { - "type": "git", - "url": "https://github.com/symfony/translation-contracts.git", - "reference": "65a8bc82080447fae78373aa10f8d13b38338977" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/65a8bc82080447fae78373aa10f8d13b38338977", - "reference": "65a8bc82080447fae78373aa10f8d13b38338977", - "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.1" - }, - "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/uid", - "version": "v7.4.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/uid.git", - "reference": "2498e9f81b7baa206f44de583f2f48350b90142c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/uid/zipball/2498e9f81b7baa206f44de583f2f48350b90142c", - "reference": "2498e9f81b7baa206f44de583f2f48350b90142c", - "shasum": "" - }, - "require": { - "php": ">=8.2", - "symfony/polyfill-uuid": "^1.15" - }, - "require-dev": { - "symfony/console": "^6.4|^7.0|^8.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.4.0" - }, - "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-09-25T11:02:55+00:00" - }, - { - "name": "symfony/var-dumper", - "version": "v7.4.3", - "source": { - "type": "git", - "url": "https://github.com/symfony/var-dumper.git", - "reference": "7e99bebcb3f90d8721890f2963463280848cba92" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/7e99bebcb3f90d8721890f2963463280848cba92", - "reference": "7e99bebcb3f90d8721890f2963463280848cba92", - "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|^8.0", - "symfony/http-kernel": "^6.4|^7.0|^8.0", - "symfony/process": "^6.4|^7.0|^8.0", - "symfony/uid": "^6.4|^7.0|^8.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.4.3" - }, - "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-12-18T07:04:31+00:00" - }, - { - "name": "symfony/yaml", - "version": "v7.4.1", - "source": { - "type": "git", - "url": "https://github.com/symfony/yaml.git", - "reference": "24dd4de28d2e3988b311751ac49e684d783e2345" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/24dd4de28d2e3988b311751ac49e684d783e2345", - "reference": "24dd4de28d2e3988b311751ac49e684d783e2345", - "shasum": "" - }, - "require": { - "php": ">=8.2", - "symfony/deprecation-contracts": "^2.5|^3", - "symfony/polyfill-ctype": "^1.8" - }, - "conflict": { - "symfony/console": "<6.4" - }, - "require-dev": { - "symfony/console": "^6.4|^7.0|^8.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.4.1" - }, - "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-12-04T18:11:45+00:00" - }, - { - "name": "tijsverkoyen/css-to-inline-styles", - "version": "v2.4.0", - "source": { - "type": "git", - "url": "https://github.com/tijsverkoyen/CssToInlineStyles.git", - "reference": "f0292ccf0ec75843d65027214426b6b163b48b41" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/tijsverkoyen/CssToInlineStyles/zipball/f0292ccf0ec75843d65027214426b6b163b48b41", - "reference": "f0292ccf0ec75843d65027214426b6b163b48b41", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-libxml": "*", - "php": "^7.4 || ^8.0", - "symfony/css-selector": "^5.4 || ^6.0 || ^7.0 || ^8.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.4.0" - }, - "time": "2025-12-02T11:56:42+00:00" - }, - { - "name": "vlucas/phpdotenv", - "version": "v5.6.3", - "source": { - "type": "git", - "url": "https://github.com/vlucas/phpdotenv.git", - "reference": "955e7815d677a3eaa7075231212f2110983adecc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/955e7815d677a3eaa7075231212f2110983adecc", - "reference": "955e7815d677a3eaa7075231212f2110983adecc", - "shasum": "" - }, - "require": { - "ext-pcre": "*", - "graham-campbell/result-type": "^1.1.4", - "php": "^7.2.5 || ^8.0", - "phpoption/phpoption": "^1.9.5", - "symfony/polyfill-ctype": "^1.26", - "symfony/polyfill-mbstring": "^1.26", - "symfony/polyfill-php80": "^1.26" - }, - "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.3" - }, - "funding": [ - { - "url": "https://github.com/GrahamCampbell", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/vlucas/phpdotenv", - "type": "tidelift" - } - ], - "time": "2025-12-27T19:49:13+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.12.1", - "source": { - "type": "git", - "url": "https://github.com/webmozarts/assert.git", - "reference": "9be6926d8b485f55b9229203f962b51ed377ba68" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/webmozarts/assert/zipball/9be6926d8b485f55b9229203f962b51ed377ba68", - "reference": "9be6926d8b485f55b9229203f962b51ed377ba68", - "shasum": "" - }, - "require": { - "ext-ctype": "*", - "ext-date": "*", - "ext-filter": "*", - "php": "^7.2 || ^8.0" - }, - "suggest": { - "ext-intl": "", - "ext-simplexml": "", - "ext-spl": "" - }, - "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.12.1" - }, - "time": "2025-10-29T15:56:20+00:00" - } - ], - "packages-dev": [ - { - "name": "brianium/paratest", - "version": "v7.16.1", - "source": { - "type": "git", - "url": "https://github.com/paratestphp/paratest.git", - "reference": "f0fdfd8e654e0d38bc2ba756a6cabe7be287390b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/paratestphp/paratest/zipball/f0fdfd8e654e0d38bc2ba756a6cabe7be287390b", - "reference": "f0fdfd8e654e0d38bc2ba756a6cabe7be287390b", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-pcre": "*", - "ext-reflection": "*", - "ext-simplexml": "*", - "fidry/cpu-core-counter": "^1.3.0", - "jean85/pretty-package-versions": "^2.1.1", - "php": "~8.3.0 || ~8.4.0 || ~8.5.0", - "phpunit/php-code-coverage": "^12.5.2", - "phpunit/php-file-iterator": "^6", - "phpunit/php-timer": "^8", - "phpunit/phpunit": "^12.5.4", - "sebastian/environment": "^8.0.3", - "symfony/console": "^7.3.4 || ^8.0.0", - "symfony/process": "^7.3.4 || ^8.0.0" - }, - "require-dev": { - "doctrine/coding-standard": "^14.0.0", - "ext-pcntl": "*", - "ext-pcov": "*", - "ext-posix": "*", - "phpstan/phpstan": "^2.1.33", - "phpstan/phpstan-deprecation-rules": "^2.0.3", - "phpstan/phpstan-phpunit": "^2.0.11", - "phpstan/phpstan-strict-rules": "^2.0.7", - "symfony/filesystem": "^7.3.2 || ^8.0.0" - }, - "bin": [ - "bin/paratest", - "bin/paratest_for_phpstorm" - ], - "type": "library", - "autoload": { - "psr-4": { - "ParaTest\\": [ - "src/" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Brian Scaturro", - "email": "scaturrob@gmail.com", - "role": "Developer" - }, - { - "name": "Filippo Tessarotto", - "email": "zoeslam@gmail.com", - "role": "Developer" - } - ], - "description": "Parallel testing for PHP", - "homepage": "https://github.com/paratestphp/paratest", - "keywords": [ - "concurrent", - "parallel", - "phpunit", - "testing" - ], - "support": { - "issues": "https://github.com/paratestphp/paratest/issues", - "source": "https://github.com/paratestphp/paratest/tree/v7.16.1" - }, - "funding": [ - { - "url": "https://github.com/sponsors/Slamdunk", - "type": "github" - }, - { - "url": "https://paypal.me/filippotessarotto", - "type": "paypal" - } - ], - "time": "2026-01-08T07:23:06+00:00" - }, - { - "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": "fidry/cpu-core-counter", - "version": "1.3.0", - "source": { - "type": "git", - "url": "https://github.com/theofidry/cpu-core-counter.git", - "reference": "db9508f7b1474469d9d3c53b86f817e344732678" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/db9508f7b1474469d9d3c53b86f817e344732678", - "reference": "db9508f7b1474469d9d3c53b86f817e344732678", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "require-dev": { - "fidry/makefile": "^0.2.0", - "fidry/php-cs-fixer-config": "^1.1.2", - "phpstan/extension-installer": "^1.2.0", - "phpstan/phpstan": "^2.0", - "phpstan/phpstan-deprecation-rules": "^2.0.0", - "phpstan/phpstan-phpunit": "^2.0", - "phpstan/phpstan-strict-rules": "^2.0", - "phpunit/phpunit": "^8.5.31 || ^9.5.26", - "webmozarts/strict-phpunit": "^7.5" - }, - "type": "library", - "autoload": { - "psr-4": { - "Fidry\\CpuCoreCounter\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Théo FIDRY", - "email": "theo.fidry@gmail.com" - } - ], - "description": "Tiny utility to get the number of CPU cores.", - "keywords": [ - "CPU", - "core" - ], - "support": { - "issues": "https://github.com/theofidry/cpu-core-counter/issues", - "source": "https://github.com/theofidry/cpu-core-counter/tree/1.3.0" - }, - "funding": [ - { - "url": "https://github.com/theofidry", - "type": "github" - } - ], - "time": "2025-08-14T07:29:31+00:00" - }, - { - "name": "filp/whoops", - "version": "2.18.4", - "source": { - "type": "git", - "url": "https://github.com/filp/whoops.git", - "reference": "d2102955e48b9fd9ab24280a7ad12ed552752c4d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/filp/whoops/zipball/d2102955e48b9fd9ab24280a7ad12ed552752c4d", - "reference": "d2102955e48b9fd9ab24280a7ad12ed552752c4d", - "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.4" - }, - "funding": [ - { - "url": "https://github.com/denis-sokolov", - "type": "github" - } - ], - "time": "2025-08-08T12:00:00+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": "jean85/pretty-package-versions", - "version": "2.1.1", - "source": { - "type": "git", - "url": "https://github.com/Jean85/pretty-package-versions.git", - "reference": "4d7aa5dab42e2a76d99559706022885de0e18e1a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Jean85/pretty-package-versions/zipball/4d7aa5dab42e2a76d99559706022885de0e18e1a", - "reference": "4d7aa5dab42e2a76d99559706022885de0e18e1a", - "shasum": "" - }, - "require": { - "composer-runtime-api": "^2.1.0", - "php": "^7.4|^8.0" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "^3.2", - "jean85/composer-provided-replaced-stub-package": "^1.0", - "phpstan/phpstan": "^2.0", - "phpunit/phpunit": "^7.5|^8.5|^9.6", - "rector/rector": "^2.0", - "vimeo/psalm": "^4.3 || ^5.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Jean85\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Alessandro Lai", - "email": "alessandro.lai85@gmail.com" - } - ], - "description": "A library to get pretty versions strings of installed dependencies", - "keywords": [ - "composer", - "package", - "release", - "versions" - ], - "support": { - "issues": "https://github.com/Jean85/pretty-package-versions/issues", - "source": "https://github.com/Jean85/pretty-package-versions/tree/2.1.1" - }, - "time": "2025-03-19T14:43:43+00:00" - }, - { - "name": "laradumps/laradumps", - "version": "v5.0.0", - "source": { - "type": "git", - "url": "https://github.com/laradumps/laradumps.git", - "reference": "7bfb9b888ce351ca151e29cacf2e2e74c7b62f72" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laradumps/laradumps/zipball/7bfb9b888ce351ca151e29cacf2e2e74c7b62f72", - "reference": "7bfb9b888ce351ca151e29cacf2e2e74c7b62f72", - "shasum": "" - }, - "require": { - "illuminate/mail": "^11.0|^12.0", - "illuminate/support": "^11.0|^12.0", - "laradumps/laradumps-core": "^4.0.0", - "nunomaduro/termwind": "^2.3.3", - "php": "^8.2" - }, - "require-dev": { - "larastan/larastan": "^3.8", - "laravel/framework": "^11.0|^12.0", - "laravel/pint": "^1.26.0", - "livewire/livewire": "^3.7.1|^4.0", - "mockery/mockery": "^1.6.12", - "orchestra/testbench-core": "^9.4|^10.0", - "pestphp/pest": "^3.7.0|^4.0.0", - "symfony/var-dumper": "^7.1.3|^8.0" - }, - "type": "library", - "extra": { - "laravel": { - "providers": [ - "LaraDumps\\LaraDumps\\LaraDumpsServiceProvider" - ] - } - }, - "autoload": { - "files": [ - "src/functions.php" - ], - "psr-4": { - "LaraDumps\\LaraDumps\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Luan Freitas", - "email": "luanfreitas10@protonmail.com", - "role": "Developer" - } - ], - "description": "LaraDumps is a friendly app designed to boost your Laravel PHP coding and debugging experience.", - "homepage": "https://github.com/laradumps/laradumps", - "support": { - "issues": "https://github.com/laradumps/laradumps/issues", - "source": "https://github.com/laradumps/laradumps/tree/v5.0.0" - }, - "funding": [ - { - "url": "https://github.com/luanfreitasdev", - "type": "github" - } - ], - "time": "2025-12-13T12:44:16+00:00" - }, - { - "name": "laradumps/laradumps-core", - "version": "v4.0.0", - "source": { - "type": "git", - "url": "https://github.com/laradumps/laradumps-core.git", - "reference": "bb57c8fccb785777020b85592d718e8ff0c9a23a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laradumps/laradumps-core/zipball/bb57c8fccb785777020b85592d718e8ff0c9a23a", - "reference": "bb57c8fccb785777020b85592d718e8ff0c9a23a", - "shasum": "" - }, - "require": { - "ext-curl": "*", - "nunomaduro/termwind": "^2.0", - "php": "^8.2", - "ramsey/uuid": "^4.9.1", - "spatie/backtrace": "^1.5", - "symfony/console": "^6.4|^7.0|^8.0", - "symfony/finder": "^6.4|^7.0|^8.0", - "symfony/process": "^6.4|^7.0|^8.0", - "symfony/var-dumper": "^6.4|^7.0|^8.0", - "symfony/yaml": "^6.4|^7.0|^8.0" - }, - "require-dev": { - "illuminate/support": "^10.46", - "laravel/pint": "^1.26.0", - "pestphp/pest": "^3.0|^4.0", - "phpstan/phpstan": "^1.10.50" - }, - "bin": [ - "bin/laradumps" - ], - "type": "library", - "autoload": { - "files": [ - "src/functions.php" - ], - "psr-4": { - "LaraDumps\\LaraDumpsCore\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Luan Freitas", - "email": "luanfreitas10@protonmail.com", - "role": "Developer" - } - ], - "description": "LaraDumps is a friendly app designed to boost your Laravel / PHP coding and debugging experience.", - "homepage": "https://github.com/laradumps/laradumps-core", - "support": { - "issues": "https://github.com/laradumps/laradumps-core/issues", - "source": "https://github.com/laradumps/laradumps-core/tree/v4.0.0" - }, - "funding": [ - { - "url": "https://github.com/luanfreitasdev", - "type": "github" - } - ], - "time": "2025-12-12T22:10:38+00:00" - }, - { - "name": "laravel/boost", - "version": "v1.8.9", - "source": { - "type": "git", - "url": "https://github.com/laravel/boost.git", - "reference": "1f2c2d41b5216618170fb6730ec13bf894c5bffd" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laravel/boost/zipball/1f2c2d41b5216618170fb6730ec13bf894c5bffd", - "reference": "1f2c2d41b5216618170fb6730ec13bf894c5bffd", - "shasum": "" - }, - "require": { - "guzzlehttp/guzzle": "^7.9", - "illuminate/console": "^10.49.0|^11.45.3|^12.41.1", - "illuminate/contracts": "^10.49.0|^11.45.3|^12.41.1", - "illuminate/routing": "^10.49.0|^11.45.3|^12.41.1", - "illuminate/support": "^10.49.0|^11.45.3|^12.41.1", - "laravel/mcp": "^0.5.1", - "laravel/prompts": "0.1.25|^0.3.6", - "laravel/roster": "^0.2.9", - "php": "^8.1" - }, - "require-dev": { - "laravel/pint": "^1.20.0", - "mockery/mockery": "^1.6.12", - "orchestra/testbench": "^8.36.0|^9.15.0|^10.6", - "pestphp/pest": "^2.36.0|^3.8.4|^4.1.5", - "phpstan/phpstan": "^2.1.27", - "rector/rector": "^2.1" - }, - "type": "library", - "extra": { - "laravel": { - "providers": [ - "Laravel\\Boost\\BoostServiceProvider" - ] - }, - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Laravel\\Boost\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Laravel Boost accelerates AI-assisted development by providing the essential context and structure that AI needs to generate high-quality, Laravel-specific code.", - "homepage": "https://github.com/laravel/boost", - "keywords": [ - "ai", - "dev", - "laravel" - ], - "support": { - "issues": "https://github.com/laravel/boost/issues", - "source": "https://github.com/laravel/boost" - }, - "time": "2026-01-07T18:43:11+00:00" - }, - { - "name": "laravel/mcp", - "version": "v0.5.2", - "source": { - "type": "git", - "url": "https://github.com/laravel/mcp.git", - "reference": "b9bdd8d6f8b547c8733fe6826b1819341597ba3c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laravel/mcp/zipball/b9bdd8d6f8b547c8733fe6826b1819341597ba3c", - "reference": "b9bdd8d6f8b547c8733fe6826b1819341597ba3c", - "shasum": "" - }, - "require": { - "ext-json": "*", - "ext-mbstring": "*", - "illuminate/console": "^10.49.0|^11.45.3|^12.41.1", - "illuminate/container": "^10.49.0|^11.45.3|^12.41.1", - "illuminate/contracts": "^10.49.0|^11.45.3|^12.41.1", - "illuminate/http": "^10.49.0|^11.45.3|^12.41.1", - "illuminate/json-schema": "^12.41.1", - "illuminate/routing": "^10.49.0|^11.45.3|^12.41.1", - "illuminate/support": "^10.49.0|^11.45.3|^12.41.1", - "illuminate/validation": "^10.49.0|^11.45.3|^12.41.1", - "php": "^8.1" - }, - "require-dev": { - "laravel/pint": "^1.20", - "orchestra/testbench": "^8.36|^9.15|^10.8", - "pestphp/pest": "^2.36.0|^3.8.4|^4.1.0", - "phpstan/phpstan": "^2.1.27", - "rector/rector": "^2.2.4" - }, - "type": "library", - "extra": { - "laravel": { - "aliases": { - "Mcp": "Laravel\\Mcp\\Server\\Facades\\Mcp" - }, - "providers": [ - "Laravel\\Mcp\\Server\\McpServiceProvider" - ] - } - }, - "autoload": { - "psr-4": { - "Laravel\\Mcp\\": "src/", - "Laravel\\Mcp\\Server\\": "src/Server/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Taylor Otwell", - "email": "taylor@laravel.com" - } - ], - "description": "Rapidly build MCP servers for your Laravel applications.", - "homepage": "https://github.com/laravel/mcp", - "keywords": [ - "laravel", - "mcp" - ], - "support": { - "issues": "https://github.com/laravel/mcp/issues", - "source": "https://github.com/laravel/mcp" - }, - "time": "2025-12-19T19:32:34+00:00" - }, - { - "name": "laravel/pail", - "version": "v1.2.4", - "source": { - "type": "git", - "url": "https://github.com/laravel/pail.git", - "reference": "49f92285ff5d6fc09816e976a004f8dec6a0ea30" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laravel/pail/zipball/49f92285ff5d6fc09816e976a004f8dec6a0ea30", - "reference": "49f92285ff5d6fc09816e976a004f8dec6a0ea30", - "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.17|^10.8", - "pestphp/pest": "^2.20|^3.0|^4.0", - "pestphp/pest-plugin-type-coverage": "^2.3|^3.0|^4.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-11-20T16:29:35+00:00" - }, - { - "name": "laravel/pint", - "version": "v1.27.0", - "source": { - "type": "git", - "url": "https://github.com/laravel/pint.git", - "reference": "c67b4195b75491e4dfc6b00b1c78b68d86f54c90" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laravel/pint/zipball/c67b4195b75491e4dfc6b00b1c78b68d86f54c90", - "reference": "c67b4195b75491e4dfc6b00b1c78b68d86f54c90", - "shasum": "" - }, - "require": { - "ext-json": "*", - "ext-mbstring": "*", - "ext-tokenizer": "*", - "ext-xml": "*", - "php": "^8.2.0" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "^3.92.4", - "illuminate/view": "^12.44.0", - "larastan/larastan": "^3.8.1", - "laravel-zero/framework": "^12.0.4", - "mockery/mockery": "^1.6.12", - "nunomaduro/termwind": "^2.3.3", - "pestphp/pest": "^3.8.4" - }, - "bin": [ - "builds/pint" - ], - "type": "project", - "autoload": { - "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": [ - "dev", - "format", - "formatter", - "lint", - "linter", - "php" - ], - "support": { - "issues": "https://github.com/laravel/pint/issues", - "source": "https://github.com/laravel/pint" - }, - "time": "2026-01-05T16:49:17+00:00" - }, - { - "name": "laravel/roster", - "version": "v0.2.9", - "source": { - "type": "git", - "url": "https://github.com/laravel/roster.git", - "reference": "82bbd0e2de614906811aebdf16b4305956816fa6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laravel/roster/zipball/82bbd0e2de614906811aebdf16b4305956816fa6", - "reference": "82bbd0e2de614906811aebdf16b4305956816fa6", - "shasum": "" - }, - "require": { - "illuminate/console": "^10.0|^11.0|^12.0", - "illuminate/contracts": "^10.0|^11.0|^12.0", - "illuminate/routing": "^10.0|^11.0|^12.0", - "illuminate/support": "^10.0|^11.0|^12.0", - "php": "^8.1|^8.2", - "symfony/yaml": "^6.4|^7.2" - }, - "require-dev": { - "laravel/pint": "^1.14", - "mockery/mockery": "^1.6", - "orchestra/testbench": "^8.22.0|^9.0|^10.0", - "pestphp/pest": "^2.0|^3.0", - "phpstan/phpstan": "^2.0" - }, - "type": "library", - "extra": { - "laravel": { - "providers": [ - "Laravel\\Roster\\RosterServiceProvider" - ] - }, - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Laravel\\Roster\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Detect packages & approaches in use within a Laravel project", - "homepage": "https://github.com/laravel/roster", - "keywords": [ - "dev", - "laravel" - ], - "support": { - "issues": "https://github.com/laravel/roster/issues", - "source": "https://github.com/laravel/roster" - }, - "time": "2025-10-20T09:56:46+00:00" - }, - { - "name": "laravel/sail", - "version": "v1.52.0", - "source": { - "type": "git", - "url": "https://github.com/laravel/sail.git", - "reference": "64ac7d8abb2dbcf2b76e61289451bae79066b0b3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laravel/sail/zipball/64ac7d8abb2dbcf2b76e61289451bae79066b0b3", - "reference": "64ac7d8abb2dbcf2b76e61289451bae79066b0b3", - "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": "^2.0" - }, - "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": "2026-01-01T02:46:03+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.3", - "source": { - "type": "git", - "url": "https://github.com/nunomaduro/collision.git", - "reference": "1dc9e88d105699d0fee8bb18890f41b274f6b4c4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nunomaduro/collision/zipball/1dc9e88d105699d0fee8bb18890f41b274f6b4c4", - "reference": "1dc9e88d105699d0fee8bb18890f41b274f6b4c4", - "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 || ^4.0.0", - "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-11-20T02:55:25+00:00" - }, - { - "name": "pestphp/pest", - "version": "v4.3.1", - "source": { - "type": "git", - "url": "https://github.com/pestphp/pest.git", - "reference": "bc57a84e77afd4544ff9643a6858f68d05aeab96" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/pestphp/pest/zipball/bc57a84e77afd4544ff9643a6858f68d05aeab96", - "reference": "bc57a84e77afd4544ff9643a6858f68d05aeab96", - "shasum": "" - }, - "require": { - "brianium/paratest": "^7.16.0", - "nunomaduro/collision": "^8.8.3", - "nunomaduro/termwind": "^2.3.3", - "pestphp/pest-plugin": "^4.0.0", - "pestphp/pest-plugin-arch": "^4.0.0", - "pestphp/pest-plugin-mutate": "^4.0.1", - "pestphp/pest-plugin-profanity": "^4.2.1", - "php": "^8.3.0", - "phpunit/phpunit": "^12.5.4", - "symfony/process": "^7.4.3|^8.0.0" - }, - "conflict": { - "filp/whoops": "<2.18.3", - "phpunit/phpunit": ">12.5.4", - "sebastian/exporter": "<7.0.0", - "webmozart/assert": "<1.11.0" - }, - "require-dev": { - "pestphp/pest-dev-tools": "^4.0.0", - "pestphp/pest-plugin-browser": "^4.1.1", - "pestphp/pest-plugin-type-coverage": "^4.0.3", - "psy/psysh": "^0.12.18" - }, - "bin": [ - "bin/pest" - ], - "type": "library", - "extra": { - "pest": { - "plugins": [ - "Pest\\Mutate\\Plugins\\Mutate", - "Pest\\Plugins\\Configuration", - "Pest\\Plugins\\Bail", - "Pest\\Plugins\\Cache", - "Pest\\Plugins\\Coverage", - "Pest\\Plugins\\Init", - "Pest\\Plugins\\Environment", - "Pest\\Plugins\\Help", - "Pest\\Plugins\\Memory", - "Pest\\Plugins\\Only", - "Pest\\Plugins\\Printer", - "Pest\\Plugins\\ProcessIsolation", - "Pest\\Plugins\\Profile", - "Pest\\Plugins\\Retry", - "Pest\\Plugins\\Snapshot", - "Pest\\Plugins\\Verbose", - "Pest\\Plugins\\Version", - "Pest\\Plugins\\Shard", - "Pest\\Plugins\\Parallel" - ] - }, - "phpstan": { - "includes": [ - "extension.neon" - ] - } - }, - "autoload": { - "files": [ - "src/Functions.php", - "src/Pest.php" - ], - "psr-4": { - "Pest\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nuno Maduro", - "email": "enunomaduro@gmail.com" - } - ], - "description": "The elegant PHP Testing Framework.", - "keywords": [ - "framework", - "pest", - "php", - "test", - "testing", - "unit" - ], - "support": { - "issues": "https://github.com/pestphp/pest/issues", - "source": "https://github.com/pestphp/pest/tree/v4.3.1" - }, - "funding": [ - { - "url": "https://www.paypal.com/paypalme/enunomaduro", - "type": "custom" - }, - { - "url": "https://github.com/nunomaduro", - "type": "github" - } - ], - "time": "2026-01-04T16:29:59+00:00" - }, - { - "name": "pestphp/pest-plugin", - "version": "v4.0.0", - "source": { - "type": "git", - "url": "https://github.com/pestphp/pest-plugin.git", - "reference": "9d4b93d7f73d3f9c3189bb22c220fef271cdf568" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/pestphp/pest-plugin/zipball/9d4b93d7f73d3f9c3189bb22c220fef271cdf568", - "reference": "9d4b93d7f73d3f9c3189bb22c220fef271cdf568", - "shasum": "" - }, - "require": { - "composer-plugin-api": "^2.0.0", - "composer-runtime-api": "^2.2.2", - "php": "^8.3" - }, - "conflict": { - "pestphp/pest": "<4.0.0" - }, - "require-dev": { - "composer/composer": "^2.8.10", - "pestphp/pest": "^4.0.0", - "pestphp/pest-dev-tools": "^4.0.0" - }, - "type": "composer-plugin", - "extra": { - "class": "Pest\\Plugin\\Manager" - }, - "autoload": { - "psr-4": { - "Pest\\Plugin\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "The Pest plugin manager", - "keywords": [ - "framework", - "manager", - "pest", - "php", - "plugin", - "test", - "testing", - "unit" - ], - "support": { - "source": "https://github.com/pestphp/pest-plugin/tree/v4.0.0" - }, - "funding": [ - { - "url": "https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=66BYDWAT92N6L", - "type": "custom" - }, - { - "url": "https://github.com/nunomaduro", - "type": "github" - }, - { - "url": "https://www.patreon.com/nunomaduro", - "type": "patreon" - } - ], - "time": "2025-08-20T12:35:58+00:00" - }, - { - "name": "pestphp/pest-plugin-arch", - "version": "v4.0.0", - "source": { - "type": "git", - "url": "https://github.com/pestphp/pest-plugin-arch.git", - "reference": "25bb17e37920ccc35cbbcda3b00d596aadf3e58d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/pestphp/pest-plugin-arch/zipball/25bb17e37920ccc35cbbcda3b00d596aadf3e58d", - "reference": "25bb17e37920ccc35cbbcda3b00d596aadf3e58d", - "shasum": "" - }, - "require": { - "pestphp/pest-plugin": "^4.0.0", - "php": "^8.3", - "ta-tikoma/phpunit-architecture-test": "^0.8.5" - }, - "require-dev": { - "pestphp/pest": "^4.0.0", - "pestphp/pest-dev-tools": "^4.0.0" - }, - "type": "library", - "extra": { - "pest": { - "plugins": [ - "Pest\\Arch\\Plugin" - ] - } - }, - "autoload": { - "files": [ - "src/Autoload.php" - ], - "psr-4": { - "Pest\\Arch\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "The Arch plugin for Pest PHP.", - "keywords": [ - "arch", - "architecture", - "framework", - "pest", - "php", - "plugin", - "test", - "testing", - "unit" - ], - "support": { - "source": "https://github.com/pestphp/pest-plugin-arch/tree/v4.0.0" - }, - "funding": [ - { - "url": "https://www.paypal.com/paypalme/enunomaduro", - "type": "custom" - }, - { - "url": "https://github.com/nunomaduro", - "type": "github" - } - ], - "time": "2025-08-20T13:10:51+00:00" - }, - { - "name": "pestphp/pest-plugin-laravel", - "version": "v4.0.0", - "source": { - "type": "git", - "url": "https://github.com/pestphp/pest-plugin-laravel.git", - "reference": "e12a07046b826a40b1c8632fd7b80d6b8d7b628e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/pestphp/pest-plugin-laravel/zipball/e12a07046b826a40b1c8632fd7b80d6b8d7b628e", - "reference": "e12a07046b826a40b1c8632fd7b80d6b8d7b628e", - "shasum": "" - }, - "require": { - "laravel/framework": "^11.45.2|^12.25.0", - "pestphp/pest": "^4.0.0", - "php": "^8.3.0" - }, - "require-dev": { - "laravel/dusk": "^8.3.3", - "orchestra/testbench": "^9.13.0|^10.5.0", - "pestphp/pest-dev-tools": "^4.0.0" - }, - "type": "library", - "extra": { - "pest": { - "plugins": [ - "Pest\\Laravel\\Plugin" - ] - }, - "laravel": { - "providers": [ - "Pest\\Laravel\\PestServiceProvider" - ] - } - }, - "autoload": { - "files": [ - "src/Autoload.php" - ], - "psr-4": { - "Pest\\Laravel\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "The Pest Laravel Plugin", - "keywords": [ - "framework", - "laravel", - "pest", - "php", - "test", - "testing", - "unit" - ], - "support": { - "source": "https://github.com/pestphp/pest-plugin-laravel/tree/v4.0.0" - }, - "funding": [ - { - "url": "https://www.paypal.com/paypalme/enunomaduro", - "type": "custom" - }, - { - "url": "https://github.com/nunomaduro", - "type": "github" - } - ], - "time": "2025-08-20T12:46:37+00:00" - }, - { - "name": "pestphp/pest-plugin-mutate", - "version": "v4.0.1", - "source": { - "type": "git", - "url": "https://github.com/pestphp/pest-plugin-mutate.git", - "reference": "d9b32b60b2385e1688a68cc227594738ec26d96c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/pestphp/pest-plugin-mutate/zipball/d9b32b60b2385e1688a68cc227594738ec26d96c", - "reference": "d9b32b60b2385e1688a68cc227594738ec26d96c", - "shasum": "" - }, - "require": { - "nikic/php-parser": "^5.6.1", - "pestphp/pest-plugin": "^4.0.0", - "php": "^8.3", - "psr/simple-cache": "^3.0.0" - }, - "require-dev": { - "pestphp/pest": "^4.0.0", - "pestphp/pest-dev-tools": "^4.0.0", - "pestphp/pest-plugin-type-coverage": "^4.0.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Pest\\Mutate\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nuno Maduro", - "email": "enunomaduro@gmail.com" - }, - { - "name": "Sandro Gehri", - "email": "sandrogehri@gmail.com" - } - ], - "description": "Mutates your code to find untested cases", - "keywords": [ - "framework", - "mutate", - "mutation", - "pest", - "php", - "plugin", - "test", - "testing", - "unit" - ], - "support": { - "source": "https://github.com/pestphp/pest-plugin-mutate/tree/v4.0.1" - }, - "funding": [ - { - "url": "https://www.paypal.com/paypalme/enunomaduro", - "type": "custom" - }, - { - "url": "https://github.com/gehrisandro", - "type": "github" - }, - { - "url": "https://github.com/nunomaduro", - "type": "github" - } - ], - "time": "2025-08-21T20:19:25+00:00" - }, - { - "name": "pestphp/pest-plugin-profanity", - "version": "v4.2.1", - "source": { - "type": "git", - "url": "https://github.com/pestphp/pest-plugin-profanity.git", - "reference": "343cfa6f3564b7e35df0ebb77b7fa97039f72b27" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/pestphp/pest-plugin-profanity/zipball/343cfa6f3564b7e35df0ebb77b7fa97039f72b27", - "reference": "343cfa6f3564b7e35df0ebb77b7fa97039f72b27", - "shasum": "" - }, - "require": { - "pestphp/pest-plugin": "^4.0.0", - "php": "^8.3" - }, - "require-dev": { - "faissaloux/pest-plugin-inside": "^1.9", - "pestphp/pest": "^4.0.0", - "pestphp/pest-dev-tools": "^4.0.0" - }, - "type": "library", - "extra": { - "pest": { - "plugins": [ - "Pest\\Profanity\\Plugin" - ] - } - }, - "autoload": { - "psr-4": { - "Pest\\Profanity\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "The Pest Profanity Plugin", - "keywords": [ - "framework", - "pest", - "php", - "plugin", - "profanity", - "test", - "testing", - "unit" - ], - "support": { - "source": "https://github.com/pestphp/pest-plugin-profanity/tree/v4.2.1" - }, - "time": "2025-12-08T00:13:17+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": "12.5.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "4a9739b51cbcb355f6e95659612f92e282a7077b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/4a9739b51cbcb355f6e95659612f92e282a7077b", - "reference": "4a9739b51cbcb355f6e95659612f92e282a7077b", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-libxml": "*", - "ext-xmlwriter": "*", - "nikic/php-parser": "^5.7.0", - "php": ">=8.3", - "phpunit/php-file-iterator": "^6.0", - "phpunit/php-text-template": "^5.0", - "sebastian/complexity": "^5.0", - "sebastian/environment": "^8.0.3", - "sebastian/lines-of-code": "^4.0", - "sebastian/version": "^6.0", - "theseer/tokenizer": "^2.0.1" - }, - "require-dev": { - "phpunit/phpunit": "^12.5.1" - }, - "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": "12.5.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/12.5.2" - }, - "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-12-24T07:03:04+00:00" - }, - { - "name": "phpunit/php-file-iterator", - "version": "6.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "961bc913d42fe24a257bfff826a5068079ac7782" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/961bc913d42fe24a257bfff826a5068079ac7782", - "reference": "961bc913d42fe24a257bfff826a5068079ac7782", - "shasum": "" - }, - "require": { - "php": ">=8.3" - }, - "require-dev": { - "phpunit/phpunit": "^12.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", - "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/6.0.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2025-02-07T04:58:37+00:00" - }, - { - "name": "phpunit/php-invoker", - "version": "6.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-invoker.git", - "reference": "12b54e689b07a25a9b41e57736dfab6ec9ae5406" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/12b54e689b07a25a9b41e57736dfab6ec9ae5406", - "reference": "12b54e689b07a25a9b41e57736dfab6ec9ae5406", - "shasum": "" - }, - "require": { - "php": ">=8.3" - }, - "require-dev": { - "ext-pcntl": "*", - "phpunit/phpunit": "^12.0" - }, - "suggest": { - "ext-pcntl": "*" - }, - "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", - "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/6.0.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2025-02-07T04:58:58+00:00" - }, - { - "name": "phpunit/php-text-template", - "version": "5.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "e1367a453f0eda562eedb4f659e13aa900d66c53" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/e1367a453f0eda562eedb4f659e13aa900d66c53", - "reference": "e1367a453f0eda562eedb4f659e13aa900d66c53", - "shasum": "" - }, - "require": { - "php": ">=8.3" - }, - "require-dev": { - "phpunit/phpunit": "^12.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": "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/5.0.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2025-02-07T04:59:16+00:00" - }, - { - "name": "phpunit/php-timer", - "version": "8.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "f258ce36aa457f3aa3339f9ed4c81fc66dc8c2cc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/f258ce36aa457f3aa3339f9ed4c81fc66dc8c2cc", - "reference": "f258ce36aa457f3aa3339f9ed4c81fc66dc8c2cc", - "shasum": "" - }, - "require": { - "php": ">=8.3" - }, - "require-dev": { - "phpunit/phpunit": "^12.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "8.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/8.0.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2025-02-07T04:59:38+00:00" - }, - { - "name": "phpunit/phpunit", - "version": "12.5.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "4ba0e923f9d3fc655de22f9547c01d15a41fc93a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/4ba0e923f9d3fc655de22f9547c01d15a41fc93a", - "reference": "4ba0e923f9d3fc655de22f9547c01d15a41fc93a", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-json": "*", - "ext-libxml": "*", - "ext-mbstring": "*", - "ext-xml": "*", - "ext-xmlwriter": "*", - "myclabs/deep-copy": "^1.13.4", - "phar-io/manifest": "^2.0.4", - "phar-io/version": "^3.2.1", - "php": ">=8.3", - "phpunit/php-code-coverage": "^12.5.1", - "phpunit/php-file-iterator": "^6.0.0", - "phpunit/php-invoker": "^6.0.0", - "phpunit/php-text-template": "^5.0.0", - "phpunit/php-timer": "^8.0.0", - "sebastian/cli-parser": "^4.2.0", - "sebastian/comparator": "^7.1.3", - "sebastian/diff": "^7.0.0", - "sebastian/environment": "^8.0.3", - "sebastian/exporter": "^7.0.2", - "sebastian/global-state": "^8.0.2", - "sebastian/object-enumerator": "^7.0.0", - "sebastian/type": "^6.0.3", - "sebastian/version": "^6.0.0", - "staabm/side-effects-detector": "^1.0.5" - }, - "bin": [ - "phpunit" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "12.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/12.5.4" - }, - "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-12-15T06:05:34+00:00" - }, - { - "name": "sebastian/cli-parser", - "version": "4.2.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/cli-parser.git", - "reference": "90f41072d220e5c40df6e8635f5dafba2d9d4d04" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/90f41072d220e5c40df6e8635f5dafba2d9d4d04", - "reference": "90f41072d220e5c40df6e8635f5dafba2d9d4d04", - "shasum": "" - }, - "require": { - "php": ">=8.3" - }, - "require-dev": { - "phpunit/phpunit": "^12.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "4.2-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/4.2.0" - }, - "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/cli-parser", - "type": "tidelift" - } - ], - "time": "2025-09-14T09:36:45+00:00" - }, - { - "name": "sebastian/comparator", - "version": "7.1.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "dc904b4bb3ab070865fa4068cd84f3da8b945148" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/dc904b4bb3ab070865fa4068cd84f3da8b945148", - "reference": "dc904b4bb3ab070865fa4068cd84f3da8b945148", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-mbstring": "*", - "php": ">=8.3", - "sebastian/diff": "^7.0", - "sebastian/exporter": "^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^12.2" - }, - "suggest": { - "ext-bcmath": "For comparing BcMath\\Number objects" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "7.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": "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/7.1.3" - }, - "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/comparator", - "type": "tidelift" - } - ], - "time": "2025-08-20T11:27:00+00:00" - }, - { - "name": "sebastian/complexity", - "version": "5.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "bad4316aba5303d0221f43f8cee37eb58d384bbb" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/bad4316aba5303d0221f43f8cee37eb58d384bbb", - "reference": "bad4316aba5303d0221f43f8cee37eb58d384bbb", - "shasum": "" - }, - "require": { - "nikic/php-parser": "^5.0", - "php": ">=8.3" - }, - "require-dev": { - "phpunit/phpunit": "^12.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": "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/5.0.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2025-02-07T04:55:25+00:00" - }, - { - "name": "sebastian/diff", - "version": "7.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "7ab1ea946c012266ca32390913653d844ecd085f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/7ab1ea946c012266ca32390913653d844ecd085f", - "reference": "7ab1ea946c012266ca32390913653d844ecd085f", - "shasum": "" - }, - "require": { - "php": ">=8.3" - }, - "require-dev": { - "phpunit/phpunit": "^12.0", - "symfony/process": "^7.2" - }, - "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" - }, - { - "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/7.0.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2025-02-07T04:55:46+00:00" - }, - { - "name": "sebastian/environment", - "version": "8.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "24a711b5c916efc6d6e62aa65aa2ec98fef77f68" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/24a711b5c916efc6d6e62aa65aa2ec98fef77f68", - "reference": "24a711b5c916efc6d6e62aa65aa2ec98fef77f68", - "shasum": "" - }, - "require": { - "php": ">=8.3" - }, - "require-dev": { - "phpunit/phpunit": "^12.0" - }, - "suggest": { - "ext-posix": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "8.0-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/8.0.3" - }, - "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-08-12T14:11:56+00:00" - }, - { - "name": "sebastian/exporter", - "version": "7.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "016951ae10980765e4e7aee491eb288c64e505b7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/016951ae10980765e4e7aee491eb288c64e505b7", - "reference": "016951ae10980765e4e7aee491eb288c64e505b7", - "shasum": "" - }, - "require": { - "ext-mbstring": "*", - "php": ">=8.3", - "sebastian/recursion-context": "^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^12.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" - }, - { - "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/7.0.2" - }, - "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/exporter", - "type": "tidelift" - } - ], - "time": "2025-09-24T06:16:11+00:00" - }, - { - "name": "sebastian/global-state", - "version": "8.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "ef1377171613d09edd25b7816f05be8313f9115d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/ef1377171613d09edd25b7816f05be8313f9115d", - "reference": "ef1377171613d09edd25b7816f05be8313f9115d", - "shasum": "" - }, - "require": { - "php": ">=8.3", - "sebastian/object-reflector": "^5.0", - "sebastian/recursion-context": "^7.0" - }, - "require-dev": { - "ext-dom": "*", - "phpunit/phpunit": "^12.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "8.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/8.0.2" - }, - "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/global-state", - "type": "tidelift" - } - ], - "time": "2025-08-29T11:29:25+00:00" - }, - { - "name": "sebastian/lines-of-code", - "version": "4.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "97ffee3bcfb5805568d6af7f0f893678fc076d2f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/97ffee3bcfb5805568d6af7f0f893678fc076d2f", - "reference": "97ffee3bcfb5805568d6af7f0f893678fc076d2f", - "shasum": "" - }, - "require": { - "nikic/php-parser": "^5.0", - "php": ">=8.3" - }, - "require-dev": { - "phpunit/phpunit": "^12.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 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/4.0.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2025-02-07T04:57:28+00:00" - }, - { - "name": "sebastian/object-enumerator", - "version": "7.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "1effe8e9b8e068e9ae228e542d5d11b5d16db894" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/1effe8e9b8e068e9ae228e542d5d11b5d16db894", - "reference": "1effe8e9b8e068e9ae228e542d5d11b5d16db894", - "shasum": "" - }, - "require": { - "php": ">=8.3", - "sebastian/object-reflector": "^5.0", - "sebastian/recursion-context": "^7.0" - }, - "require-dev": { - "phpunit/phpunit": "^12.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": "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/7.0.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2025-02-07T04:57:48+00:00" - }, - { - "name": "sebastian/object-reflector", - "version": "5.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "4bfa827c969c98be1e527abd576533293c634f6a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/4bfa827c969c98be1e527abd576533293c634f6a", - "reference": "4bfa827c969c98be1e527abd576533293c634f6a", - "shasum": "" - }, - "require": { - "php": ">=8.3" - }, - "require-dev": { - "phpunit/phpunit": "^12.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" - } - ], - "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/5.0.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2025-02-07T04:58:17+00:00" - }, - { - "name": "sebastian/recursion-context", - "version": "7.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "0b01998a7d5b1f122911a66bebcb8d46f0c82d8c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/0b01998a7d5b1f122911a66bebcb8d46f0c82d8c", - "reference": "0b01998a7d5b1f122911a66bebcb8d46f0c82d8c", - "shasum": "" - }, - "require": { - "php": ">=8.3" - }, - "require-dev": { - "phpunit/phpunit": "^12.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" - }, - { - "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/7.0.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/recursion-context", - "type": "tidelift" - } - ], - "time": "2025-08-13T04:44:59+00:00" - }, - { - "name": "sebastian/type", - "version": "6.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/type.git", - "reference": "e549163b9760b8f71f191651d22acf32d56d6d4d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/e549163b9760b8f71f191651d22acf32d56d6d4d", - "reference": "e549163b9760b8f71f191651d22acf32d56d6d4d", - "shasum": "" - }, - "require": { - "php": ">=8.3" - }, - "require-dev": { - "phpunit/phpunit": "^12.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", - "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/6.0.3" - }, - "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/type", - "type": "tidelift" - } - ], - "time": "2025-08-09T06:57:12+00:00" - }, - { - "name": "sebastian/version", - "version": "6.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/version.git", - "reference": "3e6ccf7657d4f0a59200564b08cead899313b53c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/3e6ccf7657d4f0a59200564b08cead899313b53c", - "reference": "3e6ccf7657d4f0a59200564b08cead899313b53c", - "shasum": "" - }, - "require": { - "php": ">=8.3" - }, - "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", - "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/6.0.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2025-02-07T05:00:38+00:00" - }, - { - "name": "spatie/backtrace", - "version": "1.8.1", - "source": { - "type": "git", - "url": "https://github.com/spatie/backtrace.git", - "reference": "8c0f16a59ae35ec8c62d85c3c17585158f430110" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/spatie/backtrace/zipball/8c0f16a59ae35ec8c62d85c3c17585158f430110", - "reference": "8c0f16a59ae35ec8c62d85c3c17585158f430110", - "shasum": "" - }, - "require": { - "php": "^7.3 || ^8.0" - }, - "require-dev": { - "ext-json": "*", - "laravel/serializable-closure": "^1.3 || ^2.0", - "phpunit/phpunit": "^9.3 || ^11.4.3", - "spatie/phpunit-snapshot-assertions": "^4.2 || ^5.1.6", - "symfony/var-dumper": "^5.1 || ^6.0 || ^7.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Spatie\\Backtrace\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Freek Van de Herten", - "email": "freek@spatie.be", - "homepage": "https://spatie.be", - "role": "Developer" - } - ], - "description": "A better backtrace", - "homepage": "https://github.com/spatie/backtrace", - "keywords": [ - "Backtrace", - "spatie" - ], - "support": { - "issues": "https://github.com/spatie/backtrace/issues", - "source": "https://github.com/spatie/backtrace/tree/1.8.1" - }, - "funding": [ - { - "url": "https://github.com/sponsors/spatie", - "type": "github" - }, - { - "url": "https://spatie.be/open-source/support-us", - "type": "other" - } - ], - "time": "2025-08-26T08:22:30+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": "ta-tikoma/phpunit-architecture-test", - "version": "0.8.5", - "source": { - "type": "git", - "url": "https://github.com/ta-tikoma/phpunit-architecture-test.git", - "reference": "cf6fb197b676ba716837c886baca842e4db29005" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/ta-tikoma/phpunit-architecture-test/zipball/cf6fb197b676ba716837c886baca842e4db29005", - "reference": "cf6fb197b676ba716837c886baca842e4db29005", - "shasum": "" - }, - "require": { - "nikic/php-parser": "^4.18.0 || ^5.0.0", - "php": "^8.1.0", - "phpdocumentor/reflection-docblock": "^5.3.0", - "phpunit/phpunit": "^10.5.5 || ^11.0.0 || ^12.0.0", - "symfony/finder": "^6.4.0 || ^7.0.0" - }, - "require-dev": { - "laravel/pint": "^1.13.7", - "phpstan/phpstan": "^1.10.52" - }, - "type": "library", - "autoload": { - "psr-4": { - "PHPUnit\\Architecture\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ni Shi", - "email": "futik0ma011@gmail.com" - }, - { - "name": "Nuno Maduro", - "email": "enunomaduro@gmail.com" - } - ], - "description": "Methods for testing application architecture", - "keywords": [ - "architecture", - "phpunit", - "stucture", - "test", - "testing" - ], - "support": { - "issues": "https://github.com/ta-tikoma/phpunit-architecture-test/issues", - "source": "https://github.com/ta-tikoma/phpunit-architecture-test/tree/0.8.5" - }, - "time": "2025-04-20T20:23:40+00:00" - }, - { - "name": "theseer/tokenizer", - "version": "2.0.1", - "source": { - "type": "git", - "url": "https://github.com/theseer/tokenizer.git", - "reference": "7989e43bf381af0eac72e4f0ca5bcbfa81658be4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/7989e43bf381af0eac72e4f0ca5bcbfa81658be4", - "reference": "7989e43bf381af0eac72e4f0ca5bcbfa81658be4", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-tokenizer": "*", - "ext-xmlwriter": "*", - "php": "^8.1" - }, - "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/2.0.1" - }, - "funding": [ - { - "url": "https://github.com/theseer", - "type": "github" - } - ], - "time": "2025-12-08T11:19:18+00:00" - } - ], - "aliases": [], - "minimum-stability": "stable", - "stability-flags": {}, - "prefer-stable": true, - "prefer-lowest": false, - "platform": { - "php": "^8.4" - }, - "platform-dev": {}, - "plugin-api-version": "2.9.0" -} diff --git a/config/fortify.php b/config/fortify.php deleted file mode 100644 index e29363f..0000000 --- a/config/fortify.php +++ /dev/null @@ -1,159 +0,0 @@ - 'web', - - /* - |-------------------------------------------------------------------------- - | Fortify Password Broker - |-------------------------------------------------------------------------- - | - | Here you may specify which password broker Fortify can use when a user - | is resetting their password. This configured value should match one - | of your password brokers setup in your "auth" configuration file. - | - */ - - 'passwords' => 'users', - - /* - |-------------------------------------------------------------------------- - | Username / Email - |-------------------------------------------------------------------------- - | - | This value defines which model attribute should be considered as your - | application's "username" field. Typically, this might be the email - | address of the users but you are free to change this value here. - | - | Out of the box, Fortify expects forgot password and reset password - | requests to have a field named 'email'. If the application uses - | another name for the field you may define it below as needed. - | - */ - - 'username' => 'email', - - 'email' => 'email', - - /* - |-------------------------------------------------------------------------- - | Lowercase Usernames - |-------------------------------------------------------------------------- - | - | This value defines whether usernames should be lowercased before saving - | them in the database, as some database system string fields are case - | sensitive. You may disable this for your application if necessary. - | - */ - - 'lowercase_usernames' => true, - - /* - |-------------------------------------------------------------------------- - | Home Path - |-------------------------------------------------------------------------- - | - | Here you may configure the path where users will get redirected during - | authentication or password reset when the operations are successful - | and the user is authenticated. You are free to change this value. - | - */ - - 'home' => '/dashboard', - - /* - |-------------------------------------------------------------------------- - | Fortify Routes Prefix / Subdomain - |-------------------------------------------------------------------------- - | - | Here you may specify which prefix Fortify will assign to all the routes - | that it registers with the application. If necessary, you may change - | subdomain under which all of the Fortify routes will be available. - | - */ - - 'prefix' => '', - - 'domain' => null, - - /* - |-------------------------------------------------------------------------- - | Fortify Routes Middleware - |-------------------------------------------------------------------------- - | - | Here you may specify which middleware Fortify will assign to the routes - | that it registers with the application. If necessary, you may change - | these middleware but typically this provided default is preferred. - | - */ - - 'middleware' => ['web'], - - /* - |-------------------------------------------------------------------------- - | Rate Limiting - |-------------------------------------------------------------------------- - | - | By default, Fortify will throttle logins to five requests per minute for - | every email and IP address combination. However, if you would like to - | specify a custom rate limiter to call then you may specify it here. - | - */ - - 'limiters' => [ - 'login' => 'login', - 'two-factor' => 'two-factor', - ], - - /* - |-------------------------------------------------------------------------- - | Register View Routes - |-------------------------------------------------------------------------- - | - | Here you may specify if the routes returning views should be disabled as - | you may not need them when building your own application. This may be - | especially true if you're writing a custom single-page application. - | - */ - - 'views' => true, - - /* - |-------------------------------------------------------------------------- - | Features - |-------------------------------------------------------------------------- - | - | Some of the Fortify features are optional. You may disable the features - | by removing them from this array. You're free to only remove some of - | these features or you can even remove all of these if you need to. - | - */ - - 'features' => [ - Features::registration(), - Features::resetPasswords(), - Features::emailVerification(), - // Features::updateProfileInformation(), - // Features::updatePasswords(), - Features::twoFactorAuthentication([ - 'confirm' => true, - 'confirmPassword' => true, - // 'window' => 0, - ]), - ], - -]; diff --git a/database/data/vades-article-categories.csv b/database/data/vades-article-categories.csv new file mode 100644 index 0000000..e620054 --- /dev/null +++ b/database/data/vades-article-categories.csv @@ -0,0 +1,2 @@ +title,excerpt,slug +General,General categories,general \ No newline at end of file diff --git a/database/seeders/CategorySeederProject.php b/database/seeders/CategorySeederProject.php index 10f19b6..6c9708a 100644 --- a/database/seeders/CategorySeederProject.php +++ b/database/seeders/CategorySeederProject.php @@ -4,6 +4,7 @@ namespace Database\Seeders; +use App\Enums\ContentContentType; use App\Models\Category; use App\Models\Project; use Illuminate\Database\Seeder; @@ -16,8 +17,10 @@ class CategorySeederProject extends Seeder */ public function run(): void { - $ivnbgProjectId = Project::where('slug', 'ivnbg')->first()->id; - $this->storeData('data/ivnbg-categories.csv', $ivnbgProjectId,'place'); + $vadesProjectId = Project::where('slug', 'vades')->first()->id; + $this->storeData('data/vades-article-categories.csv', $vadesProjectId,ContentContentType::Article->value); + /*$ivnbgProjectId = Project::where('slug', 'ivnbg')->first()->id; + $this->storeData('data/ivnbg-categories.csv', $ivnbgProjectId,'place');*/ } private function storeData(string $filePath, int $projectId, string $contentType): void diff --git a/database/seeders/ProjectSeeder.php b/database/seeders/ProjectSeeder.php index d3b24c7..50883ce 100644 --- a/database/seeders/ProjectSeeder.php +++ b/database/seeders/ProjectSeeder.php @@ -21,7 +21,7 @@ public function run(): void 'metadata' => ['url' => 'www.ivnbg.com'], ], [ - 'slug' => 'Project::MartinVach->value', + 'slug' => AppProject::MartinVach->value, 'excerpt' => 'martinvach.com project', 'metadata' => ['url' => 'www.martinvach.com'], ], @@ -31,7 +31,7 @@ public function run(): void 'metadata' => ['url' => 'www.myprompties.com'], ], [ - 'slug' => AppProject::MyPrompties->value, + 'slug' => AppProject::Vades->value, 'excerpt' => 'vades.dev project', 'metadata' => ['url' => 'www.vades.dev'], ], From fa50627016b47d5761eb57f4141df4d2341f413b Mon Sep 17 00:00:00 2001 From: Martin Vach Date: Tue, 17 Feb 2026 11:36:49 +0100 Subject: [PATCH 005/103] Feature/#5 basic mvc (#10) * #5: Adding basic config * #5: Implement multi-domain architecture with default theme, web controllers, and extensive shared UI components. * U * #5: Implementing Laravel Boost * #5: Handling project slug * #5: Handling views and nav * #5: Adding blog * #5: Adding blog * #5: Importing images * #5: Importing images * #5: Display images * #5: Updating page object * #5: Updating page header * #5: Updating tags * #5: Adding Meta pages * #5: Adding Content Renderer * #5: Updating provider and service * #5: Adding contact form * #5: Adding search-suggestion * #5: Adding categories-dropdown * #5: Updating project slug * #5: Adding language files * #5: Updating vite config * #5: Adding sitemap generator * #5: Adding sitemap generator * #5: Getting project url from enums --------- Co-authored-by: martin.vach --- .gemini/settings.json | 11 + .github/copilot-instructions.md | 505 +- .gitignore | 2 + DEPLOYMENT.md | 25 + GEMINI.md | 523 + .../Commands/GenerateDefaultSitemap.php | 71 + app/Enums/AppProject.php | 31 +- app/Enums/ContentContentType.php | 19 + .../Web/Default/ArticleController.php | 60 + .../Web/Default/HomeController.php | 19 + .../Web/Default/PageController.php | 29 + .../Controllers/Web/Default/TagController.php | 27 + app/Models/Content.php | 25 +- app/Models/Inquiry.php | 1 + app/Models/Tag.php | 9 + app/Models/User.php | 8 +- app/Providers/MultiDomainServiceProvider.php | 137 +- app/Services/DomainManagerService.php | 159 +- app/Services/Import/ProjectContentService.php | 29 +- app/Traits/HasDynamicContent.php | 38 + app/Utils/ImageUtil.php | 15 + boost.json | 4 +- composer.json | 6 +- composer.lock | 11023 ++++++++++++++++ config/app.php | 2 +- config/myapp.php | 39 + ...026_01_05_184533_create_projects_table.php | 3 +- database/seeders/CategorySeederProject.php | 3 +- database/seeders/ProjectSeeder.php | 18 +- lang/en/app.php | 62 + lang/en/auth.php | 20 + lang/en/pagination.php | 19 + lang/en/passwords.php | 22 + lang/en/validation.php | 194 + public/sitemap.xml | 255 + resources/css/app.css | 1 - resources/css/default/app.css | 10 + resources/css/default/theme.css | 72 + resources/css/vades/app.css | 10 + resources/css/vades/theme.css | 72 + .../default/article/index.blade.php | 51 + .../default/article/show-default.blade.php | 34 + .../views/components/default/data/nav.php | 100 + .../components/default/home/index.blade.php | 8 + .../views/components/default/layout.blade.php | 44 + .../components/default/page/index.blade.php | 29 + .../default/partials/footer/brand.blade.php | 3 + .../default/partials/footer/index.blade.php | 6 + .../default/partials/footer/nav.blade.php | 5 + .../default/partials/header/brand.blade.php | 3 + .../default/partials/header/index.blade.php | 21 + .../default/partials/header/nav.blade.php | 5 + .../default/partials/page-header.blade.php | 26 + .../partials/supplementary/index.blade.php | 10 + .../components/default/tag/index.blade.php | 24 + .../myprompties/home.blade.php | 0 .../views/components/shared/alert.blade.php | 4 + .../views/components/shared/badge.blade.php | 9 + .../views/components/shared/card.blade.php | 13 + .../shared/categories-dropdown.blade.php | 39 + .../components/shared/dropdown.blade.php | 22 + .../views/components/shared/gtag.blade.php | 10 + .../views/components/shared/iframe.blade.php | 9 + .../views/components/shared/img-svg.blade.php | 10 + .../components/shared/jumbotron.blade.php | 6 + .../components/shared/lightbox.blade.php | 99 + .../views/components/shared/modal.blade.php | 46 + .../components/shared/page-header.blade.php | 22 + .../components/shared/pagination.blade.php | 35 + .../views/components/shared/panel.blade.php | 9 + .../components/shared/post-image.blade.php | 18 + .../components/shared/prev-next.blade.php | 20 + resources/views/components/vades/data/nav.php | 97 + .../vades/home.blade.php | 0 .../categories-dropdown.blade.php" | 34 + .../categories-dropdown.php" | 35 + .../contact-form.blade.php" | 51 + .../contact-form.php" | 49 + .../search-suggestion.blade.php" | 40 + .../search-suggestion.php" | 98 + resources/views/default/home.blade.php | 34 - resources/views/errors/401.blade.php | 5 + resources/views/errors/402.blade.php | 5 + resources/views/errors/403.blade.php | 5 + resources/views/errors/404.blade.php | 7 + resources/views/errors/419.blade.php | 5 + resources/views/errors/429.blade.php | 5 + resources/views/errors/500.blade.php | 6 + resources/views/errors/503.blade.php | 5 + resources/views/errors/layout.blade.php | 35 + resources/views/errors/minimal.blade.php | 34 + resources/views/livewire/.gitkeep | 0 .../vendor/pagination/bootstrap-4.blade.php | 46 + .../vendor/pagination/bootstrap-5.blade.php | 88 + .../views/vendor/pagination/default.blade.php | 46 + .../vendor/pagination/semantic-ui.blade.php | 36 + .../pagination/simple-bootstrap-4.blade.php | 27 + .../pagination/simple-bootstrap-5.blade.php | 29 + .../pagination/simple-default.blade.php | 19 + .../pagination/simple-tailwind.blade.php | 25 + .../vendor/pagination/tailwind.blade.php | 106 + routes/default.php | 28 +- storage/debugbar/.gitignore | 2 + tests/Unit/AppProjectTest.php | 13 + vite.config.js | 9 +- 105 files changed, 14752 insertions(+), 590 deletions(-) create mode 100644 .gemini/settings.json create mode 100644 DEPLOYMENT.md create mode 100644 GEMINI.md create mode 100644 app/Console/Commands/GenerateDefaultSitemap.php create mode 100644 app/Http/Controllers/Web/Default/ArticleController.php create mode 100644 app/Http/Controllers/Web/Default/HomeController.php create mode 100644 app/Http/Controllers/Web/Default/PageController.php create mode 100644 app/Http/Controllers/Web/Default/TagController.php create mode 100644 app/Traits/HasDynamicContent.php create mode 100644 app/Utils/ImageUtil.php create mode 100644 composer.lock create mode 100644 config/myapp.php create mode 100644 lang/en/app.php create mode 100644 lang/en/auth.php create mode 100644 lang/en/pagination.php create mode 100644 lang/en/passwords.php create mode 100644 lang/en/validation.php create mode 100644 public/sitemap.xml delete mode 100644 resources/css/app.css create mode 100644 resources/css/default/app.css create mode 100644 resources/css/default/theme.css create mode 100644 resources/css/vades/app.css create mode 100644 resources/css/vades/theme.css create mode 100644 resources/views/components/default/article/index.blade.php create mode 100644 resources/views/components/default/article/show-default.blade.php create mode 100644 resources/views/components/default/data/nav.php create mode 100644 resources/views/components/default/home/index.blade.php create mode 100644 resources/views/components/default/layout.blade.php create mode 100644 resources/views/components/default/page/index.blade.php create mode 100644 resources/views/components/default/partials/footer/brand.blade.php create mode 100644 resources/views/components/default/partials/footer/index.blade.php create mode 100644 resources/views/components/default/partials/footer/nav.blade.php create mode 100644 resources/views/components/default/partials/header/brand.blade.php create mode 100644 resources/views/components/default/partials/header/index.blade.php create mode 100644 resources/views/components/default/partials/header/nav.blade.php create mode 100644 resources/views/components/default/partials/page-header.blade.php create mode 100644 resources/views/components/default/partials/supplementary/index.blade.php create mode 100644 resources/views/components/default/tag/index.blade.php rename resources/views/{sites => components}/myprompties/home.blade.php (100%) create mode 100644 resources/views/components/shared/alert.blade.php create mode 100644 resources/views/components/shared/badge.blade.php create mode 100644 resources/views/components/shared/card.blade.php create mode 100644 resources/views/components/shared/categories-dropdown.blade.php create mode 100644 resources/views/components/shared/dropdown.blade.php create mode 100644 resources/views/components/shared/gtag.blade.php create mode 100644 resources/views/components/shared/iframe.blade.php create mode 100644 resources/views/components/shared/img-svg.blade.php create mode 100644 resources/views/components/shared/jumbotron.blade.php create mode 100644 resources/views/components/shared/lightbox.blade.php create mode 100644 resources/views/components/shared/modal.blade.php create mode 100644 resources/views/components/shared/page-header.blade.php create mode 100644 resources/views/components/shared/pagination.blade.php create mode 100644 resources/views/components/shared/panel.blade.php create mode 100644 resources/views/components/shared/post-image.blade.php create mode 100644 resources/views/components/shared/prev-next.blade.php create mode 100644 resources/views/components/vades/data/nav.php rename resources/views/{sites => components}/vades/home.blade.php (100%) create mode 100644 "resources/views/components/widgets/\342\232\241categories-dropdown/categories-dropdown.blade.php" create mode 100644 "resources/views/components/widgets/\342\232\241categories-dropdown/categories-dropdown.php" create mode 100644 "resources/views/components/widgets/\342\232\241contact-form/contact-form.blade.php" create mode 100644 "resources/views/components/widgets/\342\232\241contact-form/contact-form.php" create mode 100644 "resources/views/components/widgets/\342\232\241search-suggestion/search-suggestion.blade.php" create mode 100644 "resources/views/components/widgets/\342\232\241search-suggestion/search-suggestion.php" delete mode 100644 resources/views/default/home.blade.php create mode 100644 resources/views/errors/401.blade.php create mode 100644 resources/views/errors/402.blade.php create mode 100644 resources/views/errors/403.blade.php create mode 100644 resources/views/errors/404.blade.php create mode 100644 resources/views/errors/419.blade.php create mode 100644 resources/views/errors/429.blade.php create mode 100644 resources/views/errors/500.blade.php create mode 100644 resources/views/errors/503.blade.php create mode 100644 resources/views/errors/layout.blade.php create mode 100644 resources/views/errors/minimal.blade.php create mode 100644 resources/views/livewire/.gitkeep create mode 100644 resources/views/vendor/pagination/bootstrap-4.blade.php create mode 100644 resources/views/vendor/pagination/bootstrap-5.blade.php create mode 100644 resources/views/vendor/pagination/default.blade.php create mode 100644 resources/views/vendor/pagination/semantic-ui.blade.php create mode 100644 resources/views/vendor/pagination/simple-bootstrap-4.blade.php create mode 100644 resources/views/vendor/pagination/simple-bootstrap-5.blade.php create mode 100644 resources/views/vendor/pagination/simple-default.blade.php create mode 100644 resources/views/vendor/pagination/simple-tailwind.blade.php create mode 100644 resources/views/vendor/pagination/tailwind.blade.php create mode 100644 storage/debugbar/.gitignore create mode 100644 tests/Unit/AppProjectTest.php diff --git a/.gemini/settings.json b/.gemini/settings.json new file mode 100644 index 0000000..8c6715a --- /dev/null +++ b/.gemini/settings.json @@ -0,0 +1,11 @@ +{ + "mcpServers": { + "laravel-boost": { + "command": "php", + "args": [ + "artisan", + "boost:mcp" + ] + } + } +} \ No newline at end of file diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 103a6f3..b4af403 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -9,21 +9,10 @@ The Laravel Boost guidelines are specifically curated by Laravel maintainers for This application is a Laravel application and its main Laravel ecosystems package & versions are below. You are an expert with them all. Ensure you abide by these specific packages & versions. - php - 8.4.16 -- laravel/fortify (FORTIFY) - v1 -- laravel/framework (LARAVEL) - v12 -- laravel/prompts (PROMPTS) - v0 -- livewire/flux (FLUXUI_FREE) - v2 -- livewire/livewire (LIVEWIRE) - v3 -- livewire/volt (VOLT) - v1 -- laravel/mcp (MCP) - v0 -- laravel/pint (PINT) - v1 -- laravel/sail (SAIL) - v1 -- pestphp/pest (PEST) - v4 -- phpunit/phpunit (PHPUNIT) - v12 - tailwindcss (TAILWINDCSS) - v4 ## Conventions -- You must follow all existing code conventions used in this application. When creating or editing a file, check sibling files for the correct structure, approach, naming. +- You must follow all existing code conventions used in this application. When creating or editing a file, check sibling files for the correct structure, approach, and naming. - Use descriptive names for variables and methods. For example, `isRegisteredForDiscounts`, not `discount()`. - Check for existing components to reuse before writing a new one. @@ -31,7 +20,7 @@ This application is a Laravel application and its main Laravel ecosystems packag - Do not create verification scripts or tinker when tests cover that functionality and prove it works. Unit and feature tests are more important. ## Application Structure & Architecture -- Stick to existing directory structure - don't create new base folders without approval. +- Stick to existing directory structure; don't create new base folders without approval. - Do not change the application's dependencies without approval. ## Frontend Bundling @@ -43,17 +32,16 @@ This application is a Laravel application and its main Laravel ecosystems packag ## Documentation Files - You must only create documentation files if explicitly requested by the user. - === boost rules === ## Laravel Boost - Laravel Boost is an MCP server that comes with powerful tools designed specifically for this application. Use them. ## Artisan -- Use the `list-artisan-commands` tool when you need to call an Artisan command to double check the available parameters. +- Use the `list-artisan-commands` tool when you need to call an Artisan command to double-check the available parameters. ## URLs -- Whenever you share a project URL with the user you should use the `get-absolute-url` tool to ensure you're using the correct scheme, domain / IP, and port. +- Whenever you share a project URL with the user, you should use the `get-absolute-url` tool to ensure you're using the correct scheme, domain/IP, and port. ## Tinker / Debugging - You should use the `tinker` tool when you need to execute PHP to debug code or query Eloquent models directly. @@ -64,22 +52,21 @@ This application is a Laravel application and its main Laravel ecosystems packag - Only recent browser logs will be useful - ignore old logs. ## Searching Documentation (Critically Important) -- Boost comes with a powerful `search-docs` tool you should use before any other approaches. This tool automatically passes a list of installed packages and their versions to the remote Boost API, so it returns only version-specific documentation specific for the user's circumstance. You should pass an array of packages to filter on if you know you need docs for particular packages. -- The 'search-docs' tool is perfect for all Laravel related packages, including Laravel, Inertia, Livewire, Filament, Tailwind, Pest, Nova, Nightwatch, etc. -- You must use this tool to search for Laravel-ecosystem documentation before falling back to other approaches. +- Boost comes with a powerful `search-docs` tool you should use before any other approaches when dealing with Laravel or Laravel ecosystem packages. This tool automatically passes a list of installed packages and their versions to the remote Boost API, so it returns only version-specific documentation for the user's circumstance. You should pass an array of packages to filter on if you know you need docs for particular packages. +- The `search-docs` tool is perfect for all Laravel-related packages, including Laravel, Inertia, Livewire, Filament, Tailwind, Pest, Nova, Nightwatch, etc. +- You must use this tool to search for Laravel ecosystem documentation before falling back to other approaches. - Search the documentation before making code changes to ensure we are taking the correct approach. -- Use multiple, broad, simple, topic based queries to start. For example: `['rate limiting', 'routing rate limiting', 'routing']`. -- Do not add package names to queries - package information is already shared. For example, use `test resource table`, not `filament 4 test resource table`. +- Use multiple, broad, simple, topic-based queries to start. For example: `['rate limiting', 'routing rate limiting', 'routing']`. +- Do not add package names to queries; package information is already shared. For example, use `test resource table`, not `filament 4 test resource table`. ### Available Search Syntax - You can and should pass multiple queries at once. The most relevant results will be returned first. -1. Simple Word Searches with auto-stemming - query=authentication - finds 'authenticate' and 'auth' -2. Multiple Words (AND Logic) - query=rate limit - finds knowledge containing both "rate" AND "limit" -3. Quoted Phrases (Exact Position) - query="infinite scroll" - Words must be adjacent and in that order -4. Mixed Queries - query=middleware "rate limit" - "middleware" AND exact phrase "rate limit" -5. Multiple Queries - queries=["authentication", "middleware"] - ANY of these terms - +1. Simple Word Searches with auto-stemming - query=authentication - finds 'authenticate' and 'auth'. +2. Multiple Words (AND Logic) - query=rate limit - finds knowledge containing both "rate" AND "limit". +3. Quoted Phrases (Exact Position) - query="infinite scroll" - words must be adjacent and in that order. +4. Mixed Queries - query=middleware "rate limit" - "middleware" AND exact phrase "rate limit". +5. Multiple Queries - queries=["authentication", "middleware"] - ANY of these terms. === php rules === @@ -90,7 +77,7 @@ This application is a Laravel application and its main Laravel ecosystems packag ### Constructors - Use PHP 8 constructor property promotion in `__construct()`. - public function __construct(public GitHub $github) { } -- Do not allow empty `__construct()` methods with zero parameters. +- Do not allow empty `__construct()` methods with zero parameters unless the constructor is private. ### Type Declarations - Always use explicit return type declarations for methods and functions. @@ -104,7 +91,7 @@ protected function isAccessible(User $user, ?string $path = null): bool ## Comments -- Prefer PHPDoc blocks over comments. Never use comments within the code itself unless there is something _very_ complex going on. +- Prefer PHPDoc blocks over inline comments. Never use comments within the code itself unless there is something very complex going on. ## PHPDoc Blocks - Add useful array shape type definitions for arrays when appropriate. @@ -112,469 +99,44 @@ protected function isAccessible(User $user, ?string $path = null): bool ## Enums - Typically, keys in an Enum should be TitleCase. For example: `FavoritePerson`, `BestLake`, `Monthly`. - -=== herd rules === - -## Laravel Herd - -- The application is served by Laravel Herd and will be available at: https?://[kebab-case-project-dir].test. Use the `get-absolute-url` tool to generate URLs for the user to ensure valid URLs. -- You must not run any commands to make the site available via HTTP(s). It is _always_ available through Laravel Herd. - - === tests rules === ## Test Enforcement - Every change must be programmatically tested. Write a new test or update an existing test, then run the affected tests to make sure they pass. -- Run the minimum number of tests needed to ensure code quality and speed. Use `php artisan test` with a specific filename or filter. - - -=== laravel/core rules === - -## Do Things the Laravel Way - -- Use `php artisan make:` commands to create new files (i.e. migrations, controllers, models, etc.). You can list available Artisan commands using the `list-artisan-commands` tool. -- If you're creating a generic PHP class, use `php artisan make:class`. -- Pass `--no-interaction` to all Artisan commands to ensure they work without user input. You should also pass the correct `--options` to ensure correct behavior. - -### Database -- Always use proper Eloquent relationship methods with return type hints. Prefer relationship methods over raw queries or manual joins. -- Use Eloquent models and relationships before suggesting raw database queries -- Avoid `DB::`; prefer `Model::query()`. Generate code that leverages Laravel's ORM capabilities rather than bypassing them. -- Generate code that prevents N+1 query problems by using eager loading. -- Use Laravel's query builder for very complex database operations. - -### Model Creation -- When creating new models, create useful factories and seeders for them too. Ask the user if they need any other things, using `list-artisan-commands` to check the available options to `php artisan make:model`. - -### APIs & Eloquent Resources -- For APIs, default to using Eloquent API Resources and API versioning unless existing API routes do not, then you should follow existing application convention. - -### Controllers & Validation -- Always create Form Request classes for validation rather than inline validation in controllers. Include both validation rules and custom error messages. -- Check sibling Form Requests to see if the application uses array or string based validation rules. - -### Queues -- Use queued jobs for time-consuming operations with the `ShouldQueue` interface. - -### Authentication & Authorization -- Use Laravel's built-in authentication and authorization features (gates, policies, Sanctum, etc.). - -### URL Generation -- When generating links to other pages, prefer named routes and the `route()` function. - -### Configuration -- Use environment variables only in configuration files - never use the `env()` function directly outside of config files. Always use `config('app.name')`, not `env('APP_NAME')`. - -### Testing -- When creating models for tests, use the factories for the models. Check if the factory has custom states that can be used before manually setting up the model. -- Faker: Use methods such as `$this->faker->word()` or `fake()->randomDigit()`. Follow existing conventions whether to use `$this->faker` or `fake()`. -- When creating tests, make use of `php artisan make:test [options] {name}` to create a feature test, and pass `--unit` to create a unit test. Most tests should be feature tests. - -### Vite Error -- If you receive an "Illuminate\Foundation\ViteException: Unable to locate file in Vite manifest" error, you can run `npm run build` or ask the user to run `npm run dev` or `composer run dev`. - - -=== laravel/v12 rules === - -## Laravel 12 - -- Use the `search-docs` tool to get version specific documentation. -- Since Laravel 11, Laravel has a new streamlined file structure which this project uses. - -### Laravel 12 Structure -- No middleware files in `app/Http/Middleware/`. -- `bootstrap/app.php` is the file to register middleware, exceptions, and routing files. -- `bootstrap/providers.php` contains application specific service providers. -- **No app\Console\Kernel.php** - use `bootstrap/app.php` or `routes/console.php` for console configuration. -- **Commands auto-register** - files in `app/Console/Commands/` are automatically available and do not require manual registration. - -### Database -- When modifying a column, the migration must include all of the attributes that were previously defined on the column. Otherwise, they will be dropped and lost. -- Laravel 11 allows limiting eagerly loaded records natively, without external packages: `$query->latest()->limit(10);`. - -### Models -- Casts can and likely should be set in a `casts()` method on a model rather than the `$casts` property. Follow existing conventions from other models. - - -=== fluxui-free/core rules === - -## Flux UI Free - -- This project is using the free edition of Flux UI. It has full access to the free components and variants, but does not have access to the Pro components. -- Flux UI is a component library for Livewire. Flux is a robust, hand-crafted, UI component library for your Livewire applications. It's built using Tailwind CSS and provides a set of components that are easy to use and customize. -- You should use Flux UI components when available. -- Fallback to standard Blade components if Flux is unavailable. -- If available, use Laravel Boost's `search-docs` tool to get the exact documentation and code snippets available for this project. -- Flux UI components look like this: - - - - - - -### Available Components -This is correct as of Boost installation, but there may be additional components within the codebase. - - -avatar, badge, brand, breadcrumbs, button, callout, checkbox, dropdown, field, heading, icon, input, modal, navbar, otp-input, profile, radio, select, separator, skeleton, switch, text, textarea, tooltip - - - -=== livewire/core rules === - -## Livewire Core -- Use the `search-docs` tool to find exact version specific documentation for how to write Livewire & Livewire tests. -- Use the `php artisan make:livewire [Posts\CreatePost]` artisan command to create new components -- State should live on the server, with the UI reflecting it. -- All Livewire requests hit the Laravel backend, they're like regular HTTP requests. Always validate form data, and run authorization checks in Livewire actions. - -## Livewire Best Practices -- Livewire components require a single root element. -- Use `wire:loading` and `wire:dirty` for delightful loading states. -- Add `wire:key` in loops: - - ```blade - @foreach ($items as $item) -
- {{ $item->name }} -
- @endforeach - ``` - -- Prefer lifecycle hooks like `mount()`, `updatedFoo()` for initialization and reactive side effects: - - - public function mount(User $user) { $this->user = $user; } - public function updatedSearch() { $this->resetPage(); } - - - -## Testing Livewire - - - Livewire::test(Counter::class) - ->assertSet('count', 0) - ->call('increment') - ->assertSet('count', 1) - ->assertSee(1) - ->assertStatus(200); - - - - - $this->get('/posts/create') - ->assertSeeLivewire(CreatePost::class); - - - -=== livewire/v3 rules === - -## Livewire 3 - -### Key Changes From Livewire 2 -- These things changed in Livewire 2, but may not have been updated in this application. Verify this application's setup to ensure you conform with application conventions. - - Use `wire:model.live` for real-time updates, `wire:model` is now deferred by default. - - Components now use the `App\Livewire` namespace (not `App\Http\Livewire`). - - Use `$this->dispatch()` to dispatch events (not `emit` or `dispatchBrowserEvent`). - - Use the `components.layouts.app` view as the typical layout path (not `layouts.app`). - -### New Directives -- `wire:show`, `wire:transition`, `wire:cloak`, `wire:offline`, `wire:target` are available for use. Use the documentation to find usage examples. - -### Alpine -- Alpine is now included with Livewire, don't manually include Alpine.js. -- Plugins included with Alpine: persist, intersect, collapse, and focus. - -### Lifecycle Hooks -- You can listen for `livewire:init` to hook into Livewire initialization, and `fail.status === 419` for the page expiring: - - -document.addEventListener('livewire:init', function () { - Livewire.hook('request', ({ fail }) => { - if (fail && fail.status === 419) { - alert('Your session expired'); - } - }); - - Livewire.hook('message.failed', (message, component) => { - console.error(message); - }); -}); - - - -=== volt/core rules === - -## Livewire Volt - -- This project uses Livewire Volt for interactivity within its pages. New pages requiring interactivity must also use Livewire Volt. There is documentation available for it. -- Make new Volt components using `php artisan make:volt [name] [--test] [--pest]` -- Volt is a **class-based** and **functional** API for Livewire that supports single-file components, allowing a component's PHP logic and Blade templates to co-exist in the same file -- Livewire Volt allows PHP logic and Blade templates in one file. Components use the `@volt` directive. -- You must check existing Volt components to determine if they're functional or class based. If you can't detect that, ask the user which they prefer before writing a Volt component. - -### Volt Functional Component Example - - -@volt - 0]); - -$increment = fn () => $this->count++; -$decrement = fn () => $this->count--; - -$double = computed(fn () => $this->count * 2); -?> - -
-

Count: {{ $count }}

-

Double: {{ $this->double }}

- - -
-@endvolt -
- - -### Volt Class Based Component Example -To get started, define an anonymous class that extends Livewire\Volt\Component. Within the class, you may utilize all of the features of Livewire using traditional Livewire syntax: - - - -use Livewire\Volt\Component; - -new class extends Component { - public $count = 0; - - public function increment() - { - $this->count++; - } -} ?> - -
-

{{ $count }}

- -
-
- - -### Testing Volt & Volt Components -- Use the existing directory for tests if it already exists. Otherwise, fallback to `tests/Feature/Volt`. - - -use Livewire\Volt\Volt; - -test('counter increments', function () { - Volt::test('counter') - ->assertSee('Count: 0') - ->call('increment') - ->assertSee('Count: 1'); -}); - - - - -declare(strict_types=1); - -use App\Models\{User, Product}; -use Livewire\Volt\Volt; - -test('product form creates product', function () { - $user = User::factory()->create(); - - Volt::test('pages.products.create') - ->actingAs($user) - ->set('form.name', 'Test Product') - ->set('form.description', 'Test Description') - ->set('form.price', 99.99) - ->call('create') - ->assertHasNoErrors(); - - expect(Product::where('name', 'Test Product')->exists())->toBeTrue(); -}); - - - -### Common Patterns - - - - null, 'search' => '']); - -$products = computed(fn() => Product::when($this->search, - fn($q) => $q->where('name', 'like', "%{$this->search}%") -)->get()); - -$edit = fn(Product $product) => $this->editing = $product->id; -$delete = fn(Product $product) => $product->delete(); - -?> - - - - - - - - - - - Save - Saving... - - - - -=== pint/core rules === - -## Laravel Pint Code Formatter - -- You must run `vendor/bin/pint --dirty` before finalizing changes to ensure your code matches the project's expected style. -- Do not run `vendor/bin/pint --test`, simply run `vendor/bin/pint` to fix any formatting issues. - - -=== pest/core rules === - -## Pest -### Testing -- If you need to verify a feature is working, write or update a Unit / Feature test. - -### Pest Tests -- All tests must be written using Pest. Use `php artisan make:test --pest {name}`. -- You must not remove any tests or test files from the tests directory without approval. These are not temporary or helper files - these are core to the application. -- Tests should test all of the happy paths, failure paths, and weird paths. -- Tests live in the `tests/Feature` and `tests/Unit` directories. -- Pest tests look and behave like this: - -it('is true', function () { - expect(true)->toBeTrue(); -}); - - -### Running Tests -- Run the minimal number of tests using an appropriate filter before finalizing code edits. -- To run all tests: `php artisan test`. -- To run all tests in a file: `php artisan test tests/Feature/ExampleTest.php`. -- To filter on a particular test name: `php artisan test --filter=testName` (recommended after making a change to a related file). -- When the tests relating to your changes are passing, ask the user if they would like to run the entire test suite to ensure everything is still passing. - -### Pest Assertions -- When asserting status codes on a response, use the specific method like `assertForbidden` and `assertNotFound` instead of using `assertStatus(403)` or similar, e.g.: - -it('returns all', function () { - $response = $this->postJson('/api/docs', []); - - $response->assertSuccessful(); -}); - - -### Mocking -- Mocking can be very helpful when appropriate. -- When mocking, you can use the `Pest\Laravel\mock` Pest function, but always import it via `use function Pest\Laravel\mock;` before using it. Alternatively, you can use `$this->mock()` if existing tests do. -- You can also create partial mocks using the same import or self method. - -### Datasets -- Use datasets in Pest to simplify tests which have a lot of duplicated data. This is often the case when testing validation rules, so consider going with this solution when writing tests for validation rules. - - -it('has emails', function (string $email) { - expect($email)->not->toBeEmpty(); -})->with([ - 'james' => 'james@laravel.com', - 'taylor' => 'taylor@laravel.com', -]); - - - -=== pest/v4 rules === - -## Pest 4 - -- Pest v4 is a huge upgrade to Pest and offers: browser testing, smoke testing, visual regression testing, test sharding, and faster type coverage. -- Browser testing is incredibly powerful and useful for this project. -- Browser tests should live in `tests/Browser/`. -- Use the `search-docs` tool for detailed guidance on utilizing these features. - -### Browser Testing -- You can use Laravel features like `Event::fake()`, `assertAuthenticated()`, and model factories within Pest v4 browser tests, as well as `RefreshDatabase` (when needed) to ensure a clean state for each test. -- Interact with the page (click, type, scroll, select, submit, drag-and-drop, touch gestures, etc.) when appropriate to complete the test. -- If requested, test on multiple browsers (Chrome, Firefox, Safari). -- If requested, test on different devices and viewports (like iPhone 14 Pro, tablets, or custom breakpoints). -- Switch color schemes (light/dark mode) when appropriate. -- Take screenshots or pause tests for debugging when appropriate. - -### Example Tests - - -it('may reset the password', function () { - Notification::fake(); - - $this->actingAs(User::factory()->create()); - - $page = visit('/sign-in'); // Visit on a real browser... - - $page->assertSee('Sign In') - ->assertNoJavascriptErrors() // or ->assertNoConsoleLogs() - ->click('Forgot Password?') - ->fill('email', 'nuno@laravel.com') - ->click('Send Reset Link') - ->assertSee('We have emailed your password reset link!') - - Notification::assertSent(ResetPassword::class); -}); - - - -$pages = visit(['/', '/about', '/contact']); - -$pages->assertNoJavascriptErrors()->assertNoConsoleLogs(); - - +- Run the minimum number of tests needed to ensure code quality and speed. Use `php artisan test --compact` with a specific filename or filter. === tailwindcss/core rules === -## Tailwind Core +## Tailwind CSS -- Use Tailwind CSS classes to style HTML, check and use existing tailwind conventions within the project before writing your own. -- Offer to extract repeated patterns into components that match the project's conventions (i.e. Blade, JSX, Vue, etc..) -- Think through class placement, order, priority, and defaults - remove redundant classes, add classes to parent or child carefully to limit repetition, group elements logically +- Use Tailwind CSS classes to style HTML; check and use existing Tailwind conventions within the project before writing your own. +- Offer to extract repeated patterns into components that match the project's conventions (i.e. Blade, JSX, Vue, etc.). +- Think through class placement, order, priority, and defaults. Remove redundant classes, add classes to parent or child carefully to limit repetition, and group elements logically. - You can use the `search-docs` tool to get exact examples from the official documentation when needed. ### Spacing -- When listing items, use gap utilities for spacing, don't use margins. - - -
-
Superior
-
Michigan
-
Erie
-
-
+- When listing items, use gap utilities for spacing; don't use margins. + +
+
Superior
+
Michigan
+
Erie
+
+
### Dark Mode - If existing pages and components support dark mode, new pages and components must support dark mode in a similar way, typically using `dark:`. - === tailwindcss/v4 rules === -## Tailwind 4 +## Tailwind CSS 4 -- Always use Tailwind CSS v4 - do not use the deprecated utilities. +- Always use Tailwind CSS v4; do not use the deprecated utilities. - `corePlugins` is not supported in Tailwind v4. - In Tailwind v4, configuration is CSS-first using the `@theme` directive — no separate `tailwind.config.js` file is needed. + @theme { --color-brand: oklch(0.72 0.11 178); @@ -590,9 +152,8 @@ $pages->assertNoJavascriptErrors()->assertNoConsoleLogs(); + @import "tailwindcss"; - ### Replaced Utilities -- Tailwind v4 removed deprecated utilities. Do not use the deprecated option - use the replacement. +- Tailwind v4 removed deprecated utilities. Do not use the deprecated option; use the replacement. - Opacity values are still numeric. | Deprecated | Replacement | diff --git a/.gitignore b/.gitignore index 016d612..2d7be98 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,5 @@ yarn-error.log /.zed laradumps.yaml +.junie +.history diff --git a/DEPLOYMENT.md b/DEPLOYMENT.md new file mode 100644 index 0000000..03b6ff9 --- /dev/null +++ b/DEPLOYMENT.md @@ -0,0 +1,25 @@ +# Deployment Instructions +This document provides step-by-step instructions for deploying the application to a production environment. +## Create symbolic link for storage +To ensure that images stored in the `storage` folder are accessible via the web, you need to create a symbolic link. Run the following command in your terminal: +```bash +php artisan storage:link +``` +This command creates a symbolic link from `public/storage` to `storage/app/public`, allowing you to access images stored in the storage folder through your web server. +### Verify the symbolic link +After running the command, verify that the symbolic link was created successfully by checking the contents of the `public` directory: +```bash +ls -la public/ +``` +You should see a line indicating that `storage` is a symbolic link pointing to `../storage/app/public`. +### Set correct permissions +Ensure that the web server has the correct permissions to read from the `storage` folder. You may need to adjust the permissions using the following command: +```bash +chmod -R 775 storage +``` +Make sure the web server user (e.g., `www-data` for Apache) has access to the `storage` directory. +### Test image access +To confirm that images can be accessed correctly, try to load an image stored in the `storage/app/public` directory via your web browser. The URL should look like this: +``` +http://your-domain.com/storage/images/your-image.jpg +``` \ No newline at end of file diff --git a/GEMINI.md b/GEMINI.md new file mode 100644 index 0000000..e25af94 --- /dev/null +++ b/GEMINI.md @@ -0,0 +1,523 @@ + +=== foundation rules === + +# Laravel Boost Guidelines + +The Laravel Boost guidelines are specifically curated by Laravel maintainers for this application. These guidelines should be followed closely to enhance the user's satisfaction building Laravel applications. + +## Foundational Context +This application is a Laravel application and its main Laravel ecosystems package & versions are below. You are an expert with them all. Ensure you abide by these specific packages & versions. + +- php - 8.4.16 +- laravel/framework (LARAVEL) - v12 +- laravel/prompts (PROMPTS) - v0 +- laravel/telescope (TELESCOPE) - v5 +- livewire/livewire (LIVEWIRE) - v4 +- livewire/volt (VOLT) - v1 +- laravel/mcp (MCP) - v0 +- laravel/pint (PINT) - v1 +- laravel/sail (SAIL) - v1 +- pestphp/pest (PEST) - v4 +- phpunit/phpunit (PHPUNIT) - v12 +- tailwindcss (TAILWINDCSS) - v4 + +## Conventions +- You must follow all existing code conventions used in this application. When creating or editing a file, check sibling files for the correct structure, approach, and naming. +- Use descriptive names for variables and methods. For example, `isRegisteredForDiscounts`, not `discount()`. +- Check for existing components to reuse before writing a new one. + +## Verification Scripts +- Do not create verification scripts or tinker when tests cover that functionality and prove it works. Unit and feature tests are more important. + +## Application Structure & Architecture +- Stick to existing directory structure; don't create new base folders without approval. +- Do not change the application's dependencies without approval. + +## Frontend Bundling +- If the user doesn't see a frontend change reflected in the UI, it could mean they need to run `npm run build`, `npm run dev`, or `composer run dev`. Ask them. + +## Replies +- Be concise in your explanations - focus on what's important rather than explaining obvious details. + +## Documentation Files +- You must only create documentation files if explicitly requested by the user. + +=== boost rules === + +## Laravel Boost +- Laravel Boost is an MCP server that comes with powerful tools designed specifically for this application. Use them. + +## Artisan +- Use the `list-artisan-commands` tool when you need to call an Artisan command to double-check the available parameters. + +## URLs +- Whenever you share a project URL with the user, you should use the `get-absolute-url` tool to ensure you're using the correct scheme, domain/IP, and port. + +## Tinker / Debugging +- You should use the `tinker` tool when you need to execute PHP to debug code or query Eloquent models directly. +- Use the `database-query` tool when you only need to read from the database. + +## Reading Browser Logs With the `browser-logs` Tool +- You can read browser logs, errors, and exceptions using the `browser-logs` tool from Boost. +- Only recent browser logs will be useful - ignore old logs. + +## Searching Documentation (Critically Important) +- Boost comes with a powerful `search-docs` tool you should use before any other approaches when dealing with Laravel or Laravel ecosystem packages. This tool automatically passes a list of installed packages and their versions to the remote Boost API, so it returns only version-specific documentation for the user's circumstance. You should pass an array of packages to filter on if you know you need docs for particular packages. +- The `search-docs` tool is perfect for all Laravel-related packages, including Laravel, Inertia, Livewire, Filament, Tailwind, Pest, Nova, Nightwatch, etc. +- You must use this tool to search for Laravel ecosystem documentation before falling back to other approaches. +- Search the documentation before making code changes to ensure we are taking the correct approach. +- Use multiple, broad, simple, topic-based queries to start. For example: `['rate limiting', 'routing rate limiting', 'routing']`. +- Do not add package names to queries; package information is already shared. For example, use `test resource table`, not `filament 4 test resource table`. + +### Available Search Syntax +- You can and should pass multiple queries at once. The most relevant results will be returned first. + +1. Simple Word Searches with auto-stemming - query=authentication - finds 'authenticate' and 'auth'. +2. Multiple Words (AND Logic) - query=rate limit - finds knowledge containing both "rate" AND "limit". +3. Quoted Phrases (Exact Position) - query="infinite scroll" - words must be adjacent and in that order. +4. Mixed Queries - query=middleware "rate limit" - "middleware" AND exact phrase "rate limit". +5. Multiple Queries - queries=["authentication", "middleware"] - ANY of these terms. + +=== php rules === + +## PHP + +- Always use curly braces for control structures, even if it has one line. + +### Constructors +- Use PHP 8 constructor property promotion in `__construct()`. + - public function __construct(public GitHub $github) { } +- Do not allow empty `__construct()` methods with zero parameters unless the constructor is private. + +### Type Declarations +- Always use explicit return type declarations for methods and functions. +- Use appropriate PHP type hints for method parameters. + + +protected function isAccessible(User $user, ?string $path = null): bool +{ + ... +} + + +## Comments +- Prefer PHPDoc blocks over inline comments. Never use comments within the code itself unless there is something very complex going on. + +## PHPDoc Blocks +- Add useful array shape type definitions for arrays when appropriate. + +## Enums +- Typically, keys in an Enum should be TitleCase. For example: `FavoritePerson`, `BestLake`, `Monthly`. + +=== tests rules === + +## Test Enforcement + +- Every change must be programmatically tested. Write a new test or update an existing test, then run the affected tests to make sure they pass. +- Run the minimum number of tests needed to ensure code quality and speed. Use `php artisan test --compact` with a specific filename or filter. + +=== laravel/core rules === + +## Do Things the Laravel Way + +- Use `php artisan make:` commands to create new files (i.e. migrations, controllers, models, etc.). You can list available Artisan commands using the `list-artisan-commands` tool. +- If you're creating a generic PHP class, use `php artisan make:class`. +- Pass `--no-interaction` to all Artisan commands to ensure they work without user input. You should also pass the correct `--options` to ensure correct behavior. + +### Database +- Always use proper Eloquent relationship methods with return type hints. Prefer relationship methods over raw queries or manual joins. +- Use Eloquent models and relationships before suggesting raw database queries. +- Avoid `DB::`; prefer `Model::query()`. Generate code that leverages Laravel's ORM capabilities rather than bypassing them. +- Generate code that prevents N+1 query problems by using eager loading. +- Use Laravel's query builder for very complex database operations. + +### Model Creation +- When creating new models, create useful factories and seeders for them too. Ask the user if they need any other things, using `list-artisan-commands` to check the available options to `php artisan make:model`. + +### APIs & Eloquent Resources +- For APIs, default to using Eloquent API Resources and API versioning unless existing API routes do not, then you should follow existing application convention. + +### Controllers & Validation +- Always create Form Request classes for validation rather than inline validation in controllers. Include both validation rules and custom error messages. +- Check sibling Form Requests to see if the application uses array or string based validation rules. + +### Queues +- Use queued jobs for time-consuming operations with the `ShouldQueue` interface. + +### Authentication & Authorization +- Use Laravel's built-in authentication and authorization features (gates, policies, Sanctum, etc.). + +### URL Generation +- When generating links to other pages, prefer named routes and the `route()` function. + +### Configuration +- Use environment variables only in configuration files - never use the `env()` function directly outside of config files. Always use `config('app.name')`, not `env('APP_NAME')`. + +### Testing +- When creating models for tests, use the factories for the models. Check if the factory has custom states that can be used before manually setting up the model. +- Faker: Use methods such as `$this->faker->word()` or `fake()->randomDigit()`. Follow existing conventions whether to use `$this->faker` or `fake()`. +- When creating tests, make use of `php artisan make:test [options] {name}` to create a feature test, and pass `--unit` to create a unit test. Most tests should be feature tests. + +### Vite Error +- If you receive an "Illuminate\Foundation\ViteException: Unable to locate file in Vite manifest" error, you can run `npm run build` or ask the user to run `npm run dev` or `composer run dev`. + +=== laravel/v12 rules === + +## Laravel 12 + +- Use the `search-docs` tool to get version-specific documentation. +- Since Laravel 11, Laravel has a new streamlined file structure which this project uses. + +### Laravel 12 Structure +- In Laravel 12, middleware are no longer registered in `app/Http/Kernel.php`. +- Middleware are configured declaratively in `bootstrap/app.php` using `Application::configure()->withMiddleware()`. +- `bootstrap/app.php` is the file to register middleware, exceptions, and routing files. +- `bootstrap/providers.php` contains application specific service providers. +- The `app\Console\Kernel.php` file no longer exists; use `bootstrap/app.php` or `routes/console.php` for console configuration. +- Console commands in `app/Console/Commands/` are automatically available and do not require manual registration. + +### Database +- When modifying a column, the migration must include all of the attributes that were previously defined on the column. Otherwise, they will be dropped and lost. +- Laravel 12 allows limiting eagerly loaded records natively, without external packages: `$query->latest()->limit(10);`. + +### Models +- Casts can and likely should be set in a `casts()` method on a model rather than the `$casts` property. Follow existing conventions from other models. + +=== livewire/core rules === + +## Livewire + +- Use the `search-docs` tool to find exact version-specific documentation for how to write Livewire and Livewire tests. +- Use the `php artisan make:livewire [Posts\CreatePost]` Artisan command to create new components. +- State should live on the server, with the UI reflecting it. +- All Livewire requests hit the Laravel backend; they're like regular HTTP requests. Always validate form data and run authorization checks in Livewire actions. + +## Livewire Best Practices +- Livewire components require a single root element. +- Use `wire:loading` and `wire:dirty` for delightful loading states. +- Add `wire:key` in loops: + + ```blade + @foreach ($items as $item) +
+ {{ $item->name }} +
+ @endforeach + ``` + +- Prefer lifecycle hooks like `mount()`, `updatedFoo()` for initialization and reactive side effects: + + + public function mount(User $user) { $this->user = $user; } + public function updatedSearch() { $this->resetPage(); } + + +## Testing Livewire + + + Livewire::test(Counter::class) + ->assertSet('count', 0) + ->call('increment') + ->assertSet('count', 1) + ->assertSee(1) + ->assertStatus(200); + + + + $this->get('/posts/create') + ->assertSeeLivewire(CreatePost::class); + + +=== volt/core rules === + +## Livewire Volt + +- This project uses Livewire Volt for interactivity within its pages. New pages requiring interactivity must also use Livewire Volt. +- Make new Volt components using `php artisan make:volt [name] [--test] [--pest]`. +- Volt is a class-based and functional API for Livewire that supports single-file components, allowing a component's PHP logic and Blade templates to coexist in the same file. +- Livewire Volt allows PHP logic and Blade templates in one file. Components use the `@volt` directive. +- You must check existing Volt components to determine if they're functional or class-based. If you can't detect that, ask the user which they prefer before writing a Volt component. + +### Volt Functional Component Example + + +@volt + 0]); + +$increment = fn () => $this->count++; +$decrement = fn () => $this->count--; + +$double = computed(fn () => $this->count * 2); +?> + +
+

Count: {{ $count }}

+

Double: {{ $this->double }}

+ + +
+@endvolt +
+ +### Volt Class Based Component Example +To get started, define an anonymous class that extends Livewire\Volt\Component. Within the class, you may utilize all of the features of Livewire using traditional Livewire syntax: + + +use Livewire\Volt\Component; + +new class extends Component { + public $count = 0; + + public function increment() + { + $this->count++; + } +} ?> + +
+

{{ $count }}

+ +
+
+ +### Testing Volt & Volt Components +- Use the existing directory for tests if it already exists. Otherwise, fallback to `tests/Feature/Volt`. + + +use Livewire\Volt\Volt; + +test('counter increments', function () { + Volt::test('counter') + ->assertSee('Count: 0') + ->call('increment') + ->assertSee('Count: 1'); +}); + + + +declare(strict_types=1); + +use App\Models\{User, Product}; +use Livewire\Volt\Volt; + +test('product form creates product', function () { + $user = User::factory()->create(); + + Volt::test('pages.products.create') + ->actingAs($user) + ->set('form.name', 'Test Product') + ->set('form.description', 'Test Description') + ->set('form.price', 99.99) + ->call('create') + ->assertHasNoErrors(); + + expect(Product::where('name', 'Test Product')->exists())->toBeTrue(); +}); + + +### Common Patterns + + + null, 'search' => '']); + +$products = computed(fn() => Product::when($this->search, + fn($q) => $q->where('name', 'like', "%{$this->search}%") +)->get()); + +$edit = fn(Product $product) => $this->editing = $product->id; +$delete = fn(Product $product) => $product->delete(); + +?> + + + + + + + + + + + Save + Saving... + + + +=== pint/core rules === + +## Laravel Pint Code Formatter + +- You must run `vendor/bin/pint --dirty` before finalizing changes to ensure your code matches the project's expected style. +- Do not run `vendor/bin/pint --test`, simply run `vendor/bin/pint` to fix any formatting issues. + +=== pest/core rules === + +## Pest +### Testing +- If you need to verify a feature is working, write or update a Unit / Feature test. + +### Pest Tests +- All tests must be written using Pest. Use `php artisan make:test --pest {name}`. +- You must not remove any tests or test files from the tests directory without approval. These are not temporary or helper files - these are core to the application. +- Tests should test all of the happy paths, failure paths, and weird paths. +- Tests live in the `tests/Feature` and `tests/Unit` directories. +- Pest tests look and behave like this: + +it('is true', function () { + expect(true)->toBeTrue(); +}); + + +### Running Tests +- Run the minimal number of tests using an appropriate filter before finalizing code edits. +- To run all tests: `php artisan test --compact`. +- To run all tests in a file: `php artisan test --compact tests/Feature/ExampleTest.php`. +- To filter on a particular test name: `php artisan test --compact --filter=testName` (recommended after making a change to a related file). +- When the tests relating to your changes are passing, ask the user if they would like to run the entire test suite to ensure everything is still passing. + +### Pest Assertions +- When asserting status codes on a response, use the specific method like `assertForbidden` and `assertNotFound` instead of using `assertStatus(403)` or similar, e.g.: + +it('returns all', function () { + $response = $this->postJson('/api/docs', []); + + $response->assertSuccessful(); +}); + + +### Mocking +- Mocking can be very helpful when appropriate. +- When mocking, you can use the `Pest\Laravel\mock` Pest function, but always import it via `use function Pest\Laravel\mock;` before using it. Alternatively, you can use `$this->mock()` if existing tests do. +- You can also create partial mocks using the same import or self method. + +### Datasets +- Use datasets in Pest to simplify tests that have a lot of duplicated data. This is often the case when testing validation rules, so consider this solution when writing tests for validation rules. + + +it('has emails', function (string $email) { + expect($email)->not->toBeEmpty(); +})->with([ + 'james' => 'james@laravel.com', + 'taylor' => 'taylor@laravel.com', +]); + + +=== pest/v4 rules === + +## Pest 4 + +- Pest 4 is a huge upgrade to Pest and offers: browser testing, smoke testing, visual regression testing, test sharding, and faster type coverage. +- Browser testing is incredibly powerful and useful for this project. +- Browser tests should live in `tests/Browser/`. +- Use the `search-docs` tool for detailed guidance on utilizing these features. + +### Browser Testing +- You can use Laravel features like `Event::fake()`, `assertAuthenticated()`, and model factories within Pest 4 browser tests, as well as `RefreshDatabase` (when needed) to ensure a clean state for each test. +- Interact with the page (click, type, scroll, select, submit, drag-and-drop, touch gestures, etc.) when appropriate to complete the test. +- If requested, test on multiple browsers (Chrome, Firefox, Safari). +- If requested, test on different devices and viewports (like iPhone 14 Pro, tablets, or custom breakpoints). +- Switch color schemes (light/dark mode) when appropriate. +- Take screenshots or pause tests for debugging when appropriate. + +### Example Tests + + +it('may reset the password', function () { + Notification::fake(); + + $this->actingAs(User::factory()->create()); + + $page = visit('/sign-in'); // Visit on a real browser... + + $page->assertSee('Sign In') + ->assertNoJavascriptErrors() // or ->assertNoConsoleLogs() + ->click('Forgot Password?') + ->fill('email', 'nuno@laravel.com') + ->click('Send Reset Link') + ->assertSee('We have emailed your password reset link!') + + Notification::assertSent(ResetPassword::class); +}); + + + +$pages = visit(['/', '/about', '/contact']); + +$pages->assertNoJavascriptErrors()->assertNoConsoleLogs(); + + +=== tailwindcss/core rules === + +## Tailwind CSS + +- Use Tailwind CSS classes to style HTML; check and use existing Tailwind conventions within the project before writing your own. +- Offer to extract repeated patterns into components that match the project's conventions (i.e. Blade, JSX, Vue, etc.). +- Think through class placement, order, priority, and defaults. Remove redundant classes, add classes to parent or child carefully to limit repetition, and group elements logically. +- You can use the `search-docs` tool to get exact examples from the official documentation when needed. + +### Spacing +- When listing items, use gap utilities for spacing; don't use margins. + + +
+
Superior
+
Michigan
+
Erie
+
+
+ +### Dark Mode +- If existing pages and components support dark mode, new pages and components must support dark mode in a similar way, typically using `dark:`. + +=== tailwindcss/v4 rules === + +## Tailwind CSS 4 + +- Always use Tailwind CSS v4; do not use the deprecated utilities. +- `corePlugins` is not supported in Tailwind v4. +- In Tailwind v4, configuration is CSS-first using the `@theme` directive — no separate `tailwind.config.js` file is needed. + + +@theme { + --color-brand: oklch(0.72 0.11 178); +} + + +- In Tailwind v4, you import Tailwind using a regular CSS `@import` statement, not using the `@tailwind` directives used in v3: + + + - @tailwind base; + - @tailwind components; + - @tailwind utilities; + + @import "tailwindcss"; + + +### Replaced Utilities +- Tailwind v4 removed deprecated utilities. Do not use the deprecated option; use the replacement. +- Opacity values are still numeric. + +| Deprecated | Replacement | +|------------+--------------| +| bg-opacity-* | bg-black/* | +| text-opacity-* | text-black/* | +| border-opacity-* | border-black/* | +| divide-opacity-* | divide-black/* | +| ring-opacity-* | ring-black/* | +| placeholder-opacity-* | placeholder-black/* | +| flex-shrink-* | shrink-* | +| flex-grow-* | grow-* | +| overflow-ellipsis | text-ellipsis | +| decoration-slice | box-decoration-slice | +| decoration-clone | box-decoration-clone | +
diff --git a/app/Console/Commands/GenerateDefaultSitemap.php b/app/Console/Commands/GenerateDefaultSitemap.php new file mode 100644 index 0000000..910204e --- /dev/null +++ b/app/Console/Commands/GenerateDefaultSitemap.php @@ -0,0 +1,71 @@ +getUrl(); + $this->domainManager->setSlug(AppProject::LaravelCore->value); + $projectId = $this->domainManager->getProjectId(); + config(['app.project_id' => $projectId]); + Log:info('Generating martinvach.com sitemap...'); + + // Manually create sitemap + $sitemap = Sitemap::create(); + // Home page + $sitemap->add(Url::create($baseUrl)->setLastModificationDate(Carbon::yesterday())); + + // Static pages + $sitemap->add(Url::create("{$baseUrl}/pages/about")->setLastModificationDate(Carbon::yesterday())); + $sitemap->add(Url::create("{$baseUrl}/pages/contact")->setLastModificationDate(Carbon::yesterday())); + + // Dynamic pages + $categories = Category::withoutGlobalScopes()->where('project_id', $projectId)->publishedByType + (ContentContentType::Article)->get(); + + foreach ($categories as $category) { + $sitemap->add(Url::create("{$baseUrl}/blog?category={$category->slug}")->setLastModificationDate(Carbon::yesterday())); + } + $articles = Content::withoutGlobalScopes()->where('project_id', $projectId)->publishedByType + (ContentContentType::Article)->get(); + foreach ($articles as $item) { + $sitemap->add(Url::create("{$baseUrl}/blog/{$item->slug}")->setLastModificationDate(Carbon::yesterday())); + } + + $sitemap->writeToFile(public_path('sitemap.xml')); + } +} \ No newline at end of file diff --git a/app/Enums/AppProject.php b/app/Enums/AppProject.php index fe433c0..3d49e5e 100644 --- a/app/Enums/AppProject.php +++ b/app/Enums/AppProject.php @@ -4,10 +4,29 @@ enum AppProject: string { - case Ivnbg = 'ivnbg'; - case MartinVach = 'martinvach'; - case MyPrompties = 'myprompties'; - case Vades = 'vades'; - case Aitomatix = 'aitomatix'; - case LaravelCore = 'laravel-core'; + case Ivnbg = 'ivnbg-com'; + case MartinVach = 'martinvach-com'; + case MyPrompties = 'myprompties-com'; + case Vades = 'vades-dev'; + case Aitomatix = 'aitomatix-com'; + case AitomatixCz = 'aitomatix-cz'; + case LaravelCore = 'laravel-core-test'; + + /** + * Get the project URL by enum case. + * + * @return string + */ + public function getUrl(): string + { + return match ($this) { + self::Ivnbg => 'https://www.ivnbg.com', + self::MartinVach => 'https://www.martinvach.com', + self::MyPrompties => 'https://www.myprompties.com', + self::Vades => 'https://www.vades.dev', + self::Aitomatix => 'https://www.aitomatix.com', + self::AitomatixCz => 'https://www.aitomatix.cz', + self::LaravelCore => 'http://laravel-core.test', + }; + } } \ No newline at end of file diff --git a/app/Enums/ContentContentType.php b/app/Enums/ContentContentType.php index cabb44b..54985c7 100644 --- a/app/Enums/ContentContentType.php +++ b/app/Enums/ContentContentType.php @@ -6,7 +6,26 @@ enum ContentContentType: string { case Article = 'article'; case Page = 'page'; + case Meta = 'meta'; case Place = 'place'; case Tutorial = 'tutorial'; + + case Guide= 'guide'; case Aiprompt = 'aiprompt'; + + /** + * Get all enum values as array + */ + public static function values(): array + { + return array_column(self::cases(), 'value'); + } + + /** + * Get all enum names as array + */ + public static function names(): array + { + return array_column(self::cases(), 'name'); + } } \ No newline at end of file diff --git a/app/Http/Controllers/Web/Default/ArticleController.php b/app/Http/Controllers/Web/Default/ArticleController.php new file mode 100644 index 0000000..1f52dab --- /dev/null +++ b/app/Http/Controllers/Web/Default/ArticleController.php @@ -0,0 +1,60 @@ +path()); + $meta = Content::publishedByType(ContentContentType::Meta)->where('slug',$contentType)->firstOrFail(); + + $contents = Content::publishedByType()->filter($request)->orderBy('created_at','desc') + ->paginate(20); + + return view( + 'article.index', + [ + 'page' => $meta, + 'articles' => $contents ?? [], + ] + ); + } + + + /** + * Display the specified resource. + */ + public function show(string $slug): View + { + $article = Content::publishedByType()->where('slug', $slug)->with('user')->firstOrFail(); + $nextContent= $article->nextPublishedByType(ContentContentType::Article); + $viewMode=$article['viewMode'] ?? 'default'; + $postImages = null; + /* if($content['eventDirectory'] !== null){ + $postImages = collect(AlbumService::fetchPostImages())->where('directory', $content['eventDirectory'])->values() + ->toArray(); + }*/ + + $previousContent= $article->previousPublishedByType(ContentContentType::Article); + return view('article.show-' .$viewMode, [ + 'markdown' => Str::of($article->content)->markdown(), + 'page' => $article, + 'nextContent' => $nextContent? route('articleShow', ['slug'=>$nextContent->slug]) : null, + 'previousContent' => $previousContent? route('articleShow', ['slug'=>$previousContent->slug]) : null, + 'postImages' => $postImages + ]); + } +} \ No newline at end of file diff --git a/app/Http/Controllers/Web/Default/HomeController.php b/app/Http/Controllers/Web/Default/HomeController.php new file mode 100644 index 0000000..32c73b5 --- /dev/null +++ b/app/Http/Controllers/Web/Default/HomeController.php @@ -0,0 +1,19 @@ +where('slug', $slug)->firstOrFail(); + $viewData = [ + 'typee' =>'test', // This maps to :pcontentType="$typee" + 'user' => auth()->user(), // This would map to :user="$user" + 'now' => now(), + ]; + return view('page.index', [ + 'markdown' => Str::of($page->content)->markdown(), + 'renderedBody' => $page->renderContent($viewData), + 'page' => $page, + ]); + } +} \ No newline at end of file diff --git a/app/Http/Controllers/Web/Default/TagController.php b/app/Http/Controllers/Web/Default/TagController.php new file mode 100644 index 0000000..5d0d7b9 --- /dev/null +++ b/app/Http/Controllers/Web/Default/TagController.php @@ -0,0 +1,27 @@ +path()); + $meta = Content::publishedByType(ContentContentType::Meta)->where('slug','tags-'. $contentType)->firstOrFail(); + $tags = Tag::ByContentType($contentType)->withCount('contents')->where('contents_count','>',0)->get(); + return view('tag.index', [ + 'page' => $meta, + 'tags' => $tags ?? [], + 'routeName' => $contentType . 'Index', + ]); + } +} \ No newline at end of file diff --git a/app/Models/Content.php b/app/Models/Content.php index c3f7098..84d04f3 100644 --- a/app/Models/Content.php +++ b/app/Models/Content.php @@ -7,6 +7,7 @@ use App\Enums\ContentVisibility; use App\Enums\Language; use App\Traits\FilterByProject; +use App\Traits\HasDynamicContent; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Factories\HasFactory; @@ -52,7 +53,7 @@ class Content extends Model use HasFactory; use SoftDeletes; use FilterByProject; - + use HasDynamicContent; /** * The attributes that are mass assignable. * @@ -145,16 +146,36 @@ public function getSlugOptions() : SlugOptions ->saveSlugsTo('slug') ->doNotGenerateSlugsOnUpdate(); } + + /** + * Get the cover image URL from metadata. + */ + protected function coverImageUrl(): Attribute + { + return Attribute::make( + get: fn () => $this->metadata['coverImage'] ?? null, + ); + } /** * Get the featured image URL from metadata. */ - protected function imageUrl(): Attribute + protected function featuredImageUrl(): Attribute { return Attribute::make( get: fn () => $this->metadata['featuredImage'] ?? null, ); } + /** + * Get the featured image URL from metadata. + */ + protected function livewireWidget(): Attribute + { + return Attribute::make( + get: fn () => $this->metadata['livewireWidget'] ?? null, + ); + } + /** * Get the address from metadata. */ diff --git a/app/Models/Inquiry.php b/app/Models/Inquiry.php index 92e3ed1..22ba0e5 100644 --- a/app/Models/Inquiry.php +++ b/app/Models/Inquiry.php @@ -43,6 +43,7 @@ class Inquiry extends Model * @var array */ protected $fillable = [ + 'project_id', 'is_read', 'is_spam', 'is_archived', diff --git a/app/Models/Tag.php b/app/Models/Tag.php index 3e772fb..126a61a 100644 --- a/app/Models/Tag.php +++ b/app/Models/Tag.php @@ -2,8 +2,11 @@ namespace App\Models; +use App\Enums\ContentContentType; +use App\Enums\ContentStatus; use App\Enums\Language; use App\Traits\FilterByProject; +use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\SoftDeletes; @@ -73,4 +76,10 @@ public function contents() { return $this->belongsToMany(Content::class); } + + public function scopeByContentType(Builder $query, string|ContentContentType $contentType =ContentContentType::Article->value): void + { + $value = $contentType instanceof ContentContentType ? $contentType->value : $contentType; + $query->where('content_type',$value); + } } \ No newline at end of file diff --git a/app/Models/User.php b/app/Models/User.php index b923c96..a00d8b9 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -3,16 +3,16 @@ namespace App\Models; // use Illuminate\Contracts\Auth\MustVerifyEmail; +use Database\Factories\UserFactory; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; use Illuminate\Support\Str; -use Laravel\Fortify\TwoFactorAuthenticatable; class User extends Authenticatable { - /** @use HasFactory<\Database\Factories\UserFactory> */ - use HasFactory, Notifiable, TwoFactorAuthenticatable; + /** @use HasFactory */ + use HasFactory, Notifiable; /** * The attributes that are mass assignable. @@ -70,4 +70,4 @@ public function initials(): string ->map(fn ($word) => Str::substr($word, 0, 1)) ->implode(''); } -} +} \ No newline at end of file diff --git a/app/Providers/MultiDomainServiceProvider.php b/app/Providers/MultiDomainServiceProvider.php index 05d1060..0006d70 100644 --- a/app/Providers/MultiDomainServiceProvider.php +++ b/app/Providers/MultiDomainServiceProvider.php @@ -10,44 +10,139 @@ class MultiDomainServiceProvider extends ServiceProvider { + private string $slug; + private string $siteViewPath; + private string $defaultViewPath; + public function register(): void + { + $this->registerDomainManagerService(); + } + + public function boot(DomainManagerService $domainManager): void + { + $this->initializePaths($domainManager); + + $this->configureViewCascade(); + $this->configureViteBuildDirectory(); + $this->shareGlobalCssPath(); + $this->shareGlobalNavigation(); + + // Routing is disabled due to double-loading issues + // $this->configureRouting(); + } + + /** + * Register the DomainManagerService as a singleton + */ + private function registerDomainManagerService(): void { $this->app->singleton(DomainManagerService::class, function ($app) { return new DomainManagerService($app->request); }); } - public function boot(DomainManagerService $domainManager): void + /** + * Initialize common paths used throughout the provider + */ + private function initializePaths(DomainManagerService $domainManager): void { - $slug = $domainManager->getSlug(); - - // 1. View System Cascade - // Look in sites/{slug} first, then default/, then standard resources/views - $siteViewPath = resource_path("views/sites/{$slug}"); - $defaultViewPath = resource_path("views/default"); + $this->slug = $domainManager->getSlug(); + $this->siteViewPath = resource_path("views/components/{$this->slug}"); + $this->defaultViewPath = resource_path("views/components/default"); + } - if (is_dir($siteViewPath)) { - View::getFinder()->prependLocation($siteViewPath); + /** + * Configure view cascade: site-specific → default → standard resources/views + */ + private function configureViewCascade(): void + { + // Add site-specific views first (highest priority) + if (is_dir($this->siteViewPath)) { + View::share('globalViewPath', $this->siteViewPath); + View::getFinder()->prependLocation($this->siteViewPath); } - if (is_dir($defaultViewPath)) { - View::getFinder()->addLocation($defaultViewPath); + + // Add default views as fallback + if (is_dir($this->defaultViewPath)) { + View::share('globalViewPath', $this->defaultViewPath); + View::getFinder()->addLocation($this->defaultViewPath); } + } - // 2. Vite Build Directory - // Assets are served from the domain's specific build folder + /** + * Configure Vite to use the appropriate build directory + */ + private function configureViteBuildDirectory(): void + { Vite::useBuildDirectory('build'); + } - // 3. Routing + /** + * Share the appropriate CSS path with all views + */ + private function shareGlobalCssPath(): void + { + $cssPath = $this->resolveCssPath(); + View::share('globalCssPath', $cssPath); + } + + /** + * Determine which CSS file to use (site-specific or default) + */ + private function resolveCssPath(): string + { + $customCssPath = "resources/css/{$this->slug}/app.css"; + $defaultCssPath = "resources/css/default/app.css"; + + return file_exists(resource_path("css/{$this->slug}/app.css")) + ? $customCssPath + : $defaultCssPath; + } + + /** + * Share navigation data with all views + */ + private function shareGlobalNavigation(): void + { + $navigation = $this->loadNavigationData(); + View::share('globalNav', $navigation); + } + + /** + * Load navigation data from site-specific or default location + */ + private function loadNavigationData(): array + { + $siteNavPath = $this->siteViewPath . '/data/nav.php'; + $defaultNavPath = $this->defaultViewPath . '/data/nav.php'; + + $navPath = file_exists($siteNavPath) ? $siteNavPath : $defaultNavPath; + + return require_once $navPath; + } + + /** + * Configure domain-specific routing + * + * TODO: Currently disabled - routes are loaded twice causing conflicts + * Need to implement proper route caching or registration guard + */ + private function configureRouting(): void + { // Prevent double-loading of routes - /*if (!app()->has('routes_loaded_by_multidomain')) { - $this->registerRoutes($slug); + if (!app()->has('routes_loaded_by_multidomain')) { + $this->registerRoutes(); app()->instance('routes_loaded_by_multidomain', true); - }*/ + } } - //TODO: Does not work as expected, routes are loaded twice causing route conflicts - protected function registerRoutes(string $slug): void + + /** + * Register routes from domain-specific file or fallback to web.php + */ + private function registerRoutes(): void { - $routeFile = base_path("routes/{$slug}.php"); + $routeFile = base_path("routes/{$this->slug}.php"); if (file_exists($routeFile)) { ds("Loading domain route file: {$routeFile}"); @@ -57,4 +152,4 @@ protected function registerRoutes(string $slug): void Route::middleware('web')->group(base_path('routes/web.php')); } } -} +} \ No newline at end of file diff --git a/app/Services/DomainManagerService.php b/app/Services/DomainManagerService.php index 226fc12..c58f0a1 100644 --- a/app/Services/DomainManagerService.php +++ b/app/Services/DomainManagerService.php @@ -5,78 +5,189 @@ use Illuminate\Http\Request; use Illuminate\Support\Str; use Illuminate\Support\Facades\Cache; +use Illuminate\Support\Facades\Config; use App\Models\Project; class DomainManagerService { + private const DEFAULT_SLUG = 'default'; + private const CACHE_KEY_PREFIX = 'project_id_map_'; + protected ?string $currentHost = null; - protected string $slug = 'default'; + protected string $slug = self::DEFAULT_SLUG; protected ?int $projectId = null; public function __construct(Request $request) { - // In CLI mode, getHost() might return 'localhost' or an empty string. + $this->initializeFromRequest($request); + } + + /** + * Initialize the service from the incoming request + */ + private function initializeFromRequest(Request $request): void + { $this->currentHost = $request->getHost(); - // Initial detection - $this->detectSlug(); - $this->resolveProjectId(); + $this->slug = $this->determineSlug(); + $this->projectId = $this->resolveProjectId($this->slug); + + $this->updateApplicationConfig(); } /** - * Manually set the slug (e.g., from an Artisan command argument). - * This will automatically re-resolve the project ID. + * Determine the appropriate slug from environment or host */ - public function setSlug(string $slug): self + private function determineSlug(): string { - $this->slug = $slug; - $this->resolveProjectId(); + // Environment variable takes precedence + $envSlug = env('MY_PROJECT_SLUG'); + if (!empty($envSlug)) { + return $envSlug; + } - return $this; + // Otherwise, detect from host + return $this->detectSlugFromHost(); } /** - * Detect slug from host. + * Extract slug from the current host * Logic: ivnbg.com -> ivnbg, www.ivnbg.com -> ivnbg */ - protected function detectSlug(): void + private function detectSlugFromHost(): string + { + if ($this->isLocalOrEmptyHost()) { + return self::DEFAULT_SLUG; + } + + $normalizedHost = $this->normalizeHost($this->currentHost); + + return $this->extractSlugFromHost($normalizedHost); + } + + /** + * Check if running in CLI mode or localhost + */ + private function isLocalOrEmptyHost(): bool + { + return empty($this->currentHost) || $this->currentHost === 'localhost'; + } + + /** + * Normalize host by removing www prefix + */ + private function normalizeHost(string $host): string + { + return Str::replace('www.', '', $host); + } + + /** + * Extract the slug from the host with extension + * Replaces all dots with hyphens (e.g., domain-name.com -> domain-name-com) + */ + private function extractSlugFromHost(string $host): string { - if (empty($this->currentHost) || $this->currentHost === 'localhost') { - return; + if (empty($host)) { + return self::DEFAULT_SLUG; } - $host = Str::replace('www.', '', $this->currentHost); - $parts = explode('.', $host); - $this->slug = $parts[0] ?? 'default'; + return Str::replace('.', '-', $host); } /** - * Resolve the project ID based on the current slug. + * Resolve the project ID from the database using the slug */ - protected function resolveProjectId(): void + private function resolveProjectId(string $slug): ?int { - // We use the slug as the cache key. - $this->projectId = Cache::rememberForever("project_id_map_{$this->slug}", function () { - return Project::where('slug', $this->slug)->value('id'); + $cacheKey = $this->getCacheKey($slug); + + return Cache::rememberForever($cacheKey, function () use ($slug) { + return $this->fetchProjectIdFromDatabase($slug); }); } + /** + * Fetch project ID from the database + */ + private function fetchProjectIdFromDatabase(string $slug): ?int + { + return Project::where('slug', $slug)->value('id'); + } + + /** + * Generate cache key for a given slug + */ + private function getCacheKey(string $slug): string + { + return self::CACHE_KEY_PREFIX . $slug; + } + + /** + * Update application configuration with the current slug + */ + private function updateApplicationConfig(): void + { + Config::set('myapp.projectSlug', $this->slug); + } + + /** + * Get the current slug + */ public function getSlug(): string { return $this->slug; } + /** + * Get the current project ID + */ public function getProjectId(): ?int { return $this->projectId; } /** - * Allows manual override of the Project ID if needed. + * Manually set the slug (e.g., from an Artisan command) + * This automatically re-resolves the project ID and updates config + */ + public function setSlug(string $slug): self + { + $this->slug = $slug; + $this->projectId = $this->resolveProjectId($slug); + $this->updateApplicationConfig(); + + return $this; + } + + /** + * Manually override the project ID if needed */ public function setProjectId(int $projectId): self { $this->projectId = $projectId; + + return $this; + } + + /** + * Clear the cached project ID for a specific slug + */ + public function clearCache(?string $slug = null): void + { + $targetSlug = $slug ?? $this->slug; + $cacheKey = $this->getCacheKey($targetSlug); + + Cache::forget($cacheKey); + } + + /** + * Refresh the project ID from the database + */ + public function refresh(): self + { + $this->clearCache(); + $this->projectId = $this->resolveProjectId($this->slug); + return $this; } } \ No newline at end of file diff --git a/app/Services/Import/ProjectContentService.php b/app/Services/Import/ProjectContentService.php index 1963f61..fbe9868 100644 --- a/app/Services/Import/ProjectContentService.php +++ b/app/Services/Import/ProjectContentService.php @@ -102,14 +102,14 @@ private function processProject(string $projectName, string $projectPath): void foreach ($contentTypes as $typePath) { $contentTypeStr = basename($typePath); - $this->processContentType($projectId, $contentTypeStr, $typePath); + $this->processContentType($projectId, $contentTypeStr, $typePath, $projectName); } } /** * Process subdirectories like 'articles', 'categories', 'tags'. */ - private function processContentType(int $projectId, string $contentTypeStr, string $path): void + private function processContentType(int $projectId, string $contentTypeStr, string $path,string $projectSlug): void { $files = File::files($path); @@ -119,7 +119,7 @@ private function processContentType(int $projectId, string $contentTypeStr, stri } try { - $this->importFile($projectId, $contentTypeStr, $file->getPathname()); + $this->importFile($projectId, $contentTypeStr, $file->getPathname(), $projectSlug); } catch (Exception $e) { $this->errors[] = "File error [{$file->getFilename()}]: " . $e->getMessage(); } @@ -129,7 +129,7 @@ private function processContentType(int $projectId, string $contentTypeStr, stri /** * Parse the Markdown file and store it using the appropriate DTO. */ - private function importFile(int $projectId, string $contentTypeStr, string $filePath): void + private function importFile(int $projectId, string $contentTypeStr, string $filePath, string $projectSlug): void { $fileContent = file_get_contents($filePath); if ($fileContent === false) { @@ -143,7 +143,7 @@ private function importFile(int $projectId, string $contentTypeStr, string $file throw new Exception("Missing required YAML front matter (title or slug)."); } - $content = $this->handleContentImport($projectId, $contentTypeStr, $object); + $content = $this->handleContentImport($projectId, $contentTypeStr, $object, $projectSlug); if(!$content) { return; } @@ -162,7 +162,7 @@ private function importFile(int $projectId, string $contentTypeStr, string $file /** * Handle generic content (articles, posts, etc.) */ - private function handleContentImport(int $projectId, string $contentTypeStr, Document $object): ?Content + private function handleContentImport(int $projectId, string $contentTypeStr, Document $object,string $projectSlug): ?Content { $content = null; try { @@ -193,10 +193,15 @@ private function handleContentImport(int $projectId, string $contentTypeStr, Doc 'publishedAt' => $object->matter('published_at') ? Carbon::parse($object->matter('published_at')) : null, ]; $data['metadata'] = $this->extractMetadata($object, array_keys($data), ['categories', 'tags', 'parent']); + $data['metadata']['coverImage'] =$this->getContentImageUrl($projectSlug,$contentTypeStr, ($object->matter + ('imageDirectory') ?? '').'/'. + config('myapp.image.cover')); + $data['metadata']['featuredImage'] = $this->getContentImageUrl($projectSlug,$contentTypeStr, ($object->matter + ('imageDirectory') ?? '').'/'. + config('myapp.image.featured')); $dto = ContentData::from($data); - $content = Content::updateOrCreate( ['slug' => $dto->slug, 'project_id' => $dto->projectId], $dto->toArray() @@ -209,6 +214,16 @@ private function handleContentImport(int $projectId, string $contentTypeStr, Doc return $content; } + private function getContentImageUrl(string $projectSlug,string $contentType,string $filename): ?string + { + $imagePath = storage_path('app/public/' . $projectSlug . '/images/' . $contentType . '/' . $filename); + if (File::exists($imagePath)) { + return 'storage/' . $projectSlug . '/images/' . $contentType . '/' . $filename; + } + return null; + + } + private function getParentId(string|null $parentSlug, string $contentType): ?int { if (empty($parentSlug)) { diff --git a/app/Traits/HasDynamicContent.php b/app/Traits/HasDynamicContent.php new file mode 100644 index 0000000..2087599 --- /dev/null +++ b/app/Traits/HasDynamicContent.php @@ -0,0 +1,38 @@ +{$column}; + + if (empty($raw)) { + return ''; + } + + // 1. Render the Blade tags first + $renderedBlade = Blade::render($raw, $data); + + /** + * 2. Fix: Remove leading indentation. + * We use regex to remove spaces/tabs from the start of every line. + * This prevents Markdown from turning indented HTML into
 blocks.
+         */
+        $cleanedHtml = preg_replace('/^[ \t]+/m', '', $renderedBlade);
+
+        // 3. Render as Markdown
+        return Str::markdown($cleanedHtml);
+    }
+}
\ No newline at end of file
diff --git a/app/Utils/ImageUtil.php b/app/Utils/ImageUtil.php
new file mode 100644
index 0000000..9e39a5c
--- /dev/null
+++ b/app/Utils/ImageUtil.php
@@ -0,0 +1,15 @@
+=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/deprecations",
+            "version": "1.1.5",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/doctrine/deprecations.git",
+                "reference": "459c2f5dd3d6a4633d3b5f46ee2b1c40f57d3f38"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/doctrine/deprecations/zipball/459c2f5dd3d6a4633d3b5f46ee2b1c40f57d3f38",
+                "reference": "459c2f5dd3d6a4633d3b5f46ee2b1c40f57d3f38",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.1 || ^8.0"
+            },
+            "conflict": {
+                "phpunit/phpunit": "<=7.5 || >=13"
+            },
+            "require-dev": {
+                "doctrine/coding-standard": "^9 || ^12 || ^13",
+                "phpstan/phpstan": "1.4.10 || 2.1.11",
+                "phpstan/phpstan-phpunit": "^1.0 || ^2",
+                "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6 || ^10.5 || ^11.5 || ^12",
+                "psr/log": "^1 || ^2 || ^3"
+            },
+            "suggest": {
+                "psr/log": "Allows logging deprecations via PSR-3 logger implementation"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Doctrine\\Deprecations\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.",
+            "homepage": "https://www.doctrine-project.org/",
+            "support": {
+                "issues": "https://github.com/doctrine/deprecations/issues",
+                "source": "https://github.com/doctrine/deprecations/tree/1.1.5"
+            },
+            "time": "2025-04-07T20:06:18+00:00"
+        },
+        {
+            "name": "doctrine/inflector",
+            "version": "2.1.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/doctrine/inflector.git",
+                "reference": "6d6c96277ea252fc1304627204c3d5e6e15faa3b"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/doctrine/inflector/zipball/6d6c96277ea252fc1304627204c3d5e6e15faa3b",
+                "reference": "6d6c96277ea252fc1304627204c3d5e6e15faa3b",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.2 || ^8.0"
+            },
+            "require-dev": {
+                "doctrine/coding-standard": "^12.0 || ^13.0",
+                "phpstan/phpstan": "^1.12 || ^2.0",
+                "phpstan/phpstan-phpunit": "^1.4 || ^2.0",
+                "phpstan/phpstan-strict-rules": "^1.6 || ^2.0",
+                "phpunit/phpunit": "^8.5 || ^12.2"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Doctrine\\Inflector\\": "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": "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.1.0"
+            },
+            "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": "2025-08-10T19:31:58+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": "dragonmantank/cron-expression",
+            "version": "v3.6.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/dragonmantank/cron-expression.git",
+                "reference": "d61a8a9604ec1f8c3d150d09db6ce98b32675013"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/dragonmantank/cron-expression/zipball/d61a8a9604ec1f8c3d150d09db6ce98b32675013",
+                "reference": "d61a8a9604ec1f8c3d150d09db6ce98b32675013",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^8.2|^8.3|^8.4|^8.5"
+            },
+            "replace": {
+                "mtdowling/cron-expression": "^1.0"
+            },
+            "require-dev": {
+                "phpstan/extension-installer": "^1.4.3",
+                "phpstan/phpstan": "^1.12.32|^2.1.31",
+                "phpunit/phpunit": "^8.5.48|^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.6.0"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/dragonmantank",
+                    "type": "github"
+                }
+            ],
+            "time": "2025-10-31T18:51:33+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.4.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/fruitcake/php-cors.git",
+                "reference": "38aaa6c3fd4c157ffe2a4d10aa8b9b16ba8de379"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/fruitcake/php-cors/zipball/38aaa6c3fd4c157ffe2a4d10aa8b9b16ba8de379",
+                "reference": "38aaa6c3fd4c157ffe2a4d10aa8b9b16ba8de379",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^8.1",
+                "symfony/http-foundation": "^5.4|^6.4|^7.3|^8"
+            },
+            "require-dev": {
+                "phpstan/phpstan": "^2",
+                "phpunit/phpunit": "^9",
+                "squizlabs/php_codesniffer": "^4"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.3-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.4.0"
+            },
+            "funding": [
+                {
+                    "url": "https://fruitcake.nl",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/barryvdh",
+                    "type": "github"
+                }
+            ],
+            "time": "2025-12-03T09:33:47+00:00"
+        },
+        {
+            "name": "graham-campbell/result-type",
+            "version": "v1.1.4",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/GrahamCampbell/Result-Type.git",
+                "reference": "e01f4a821471308ba86aa202fed6698b6b695e3b"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/e01f4a821471308ba86aa202fed6698b6b695e3b",
+                "reference": "e01f4a821471308ba86aa202fed6698b6b695e3b",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.2.5 || ^8.0",
+                "phpoption/phpoption": "^1.9.5"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^8.5.41 || ^9.6.22 || ^10.5.45 || ^11.5.7"
+            },
+            "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.4"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/GrahamCampbell",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/graham-campbell/result-type",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2025-12-27T19:43:20+00:00"
+        },
+        {
+            "name": "guzzlehttp/guzzle",
+            "version": "7.10.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/guzzle/guzzle.git",
+                "reference": "b51ac707cfa420b7bfd4e4d5e510ba8008e822b4"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/guzzle/guzzle/zipball/b51ac707cfa420b7bfd4e4d5e510ba8008e822b4",
+                "reference": "b51ac707cfa420b7bfd4e4d5e510ba8008e822b4",
+                "shasum": ""
+            },
+            "require": {
+                "ext-json": "*",
+                "guzzlehttp/promises": "^2.3",
+                "guzzlehttp/psr7": "^2.8",
+                "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.10.0"
+            },
+            "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-08-23T22:36:01+00:00"
+        },
+        {
+            "name": "guzzlehttp/promises",
+            "version": "2.3.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/guzzle/promises.git",
+                "reference": "481557b130ef3790cf82b713667b43030dc9c957"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/guzzle/promises/zipball/481557b130ef3790cf82b713667b43030dc9c957",
+                "reference": "481557b130ef3790cf82b713667b43030dc9c957",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.2.5 || ^8.0"
+            },
+            "require-dev": {
+                "bamarni/composer-bin-plugin": "^1.8.2",
+                "phpunit/phpunit": "^8.5.44 || ^9.6.25"
+            },
+            "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.3.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-08-22T14:34:08+00:00"
+        },
+        {
+            "name": "guzzlehttp/psr7",
+            "version": "2.8.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/guzzle/psr7.git",
+                "reference": "21dc724a0583619cd1652f673303492272778051"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/guzzle/psr7/zipball/21dc724a0583619cd1652f673303492272778051",
+                "reference": "21dc724a0583619cd1652f673303492272778051",
+                "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.44 || ^9.6.25"
+            },
+            "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.8.0"
+            },
+            "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-08-23T21:21:41+00:00"
+        },
+        {
+            "name": "guzzlehttp/uri-template",
+            "version": "v1.0.5",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/guzzle/uri-template.git",
+                "reference": "4f4bbd4e7172148801e76e3decc1e559bdee34e1"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/guzzle/uri-template/zipball/4f4bbd4e7172148801e76e3decc1e559bdee34e1",
+                "reference": "4f4bbd4e7172148801e76e3decc1e559bdee34e1",
+                "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.44 || ^9.6.25",
+                "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.5"
+            },
+            "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-08-22T14:27:06+00:00"
+        },
+        {
+            "name": "laravel/framework",
+            "version": "v12.49.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/laravel/framework.git",
+                "reference": "4bde4530545111d8bdd1de6f545fa8824039fcb5"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/laravel/framework/zipball/4bde4530545111d8bdd1de6f545fa8824039fcb5",
+                "reference": "4bde4530545111d8bdd1de6f545fa8824039fcb5",
+                "shasum": ""
+            },
+            "require": {
+                "brick/math": "^0.11|^0.12|^0.13|^0.14",
+                "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.33",
+                "symfony/polyfill-php84": "^1.33",
+                "symfony/polyfill-php85": "^1.33",
+                "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/json-schema": "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/reflection": "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",
+                "opis/json-schema": "^2.4.1",
+                "orchestra/testbench-core": "^10.9.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|^1.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 generate fake data using the fake() helper (^1.23).",
+                "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|^1.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/Reflection/helpers.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/",
+                        "src/Illuminate/Reflection/"
+                    ]
+                }
+            },
+            "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": "2026-01-28T03:40:49+00:00"
+        },
+        {
+            "name": "laravel/prompts",
+            "version": "v0.3.11",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/laravel/prompts.git",
+                "reference": "dd2a2ed95acacbcccd32fd98dee4c946ae7a7217"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/laravel/prompts/zipball/dd2a2ed95acacbcccd32fd98dee4c946ae7a7217",
+                "reference": "dd2a2ed95acacbcccd32fd98dee4c946ae7a7217",
+                "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|^4.0",
+                "phpstan/phpstan": "^1.12.28",
+                "phpstan/phpstan-mockery": "^1.1.3"
+            },
+            "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.11"
+            },
+            "time": "2026-01-27T02:55:06+00:00"
+        },
+        {
+            "name": "laravel/serializable-closure",
+            "version": "v2.0.8",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/laravel/serializable-closure.git",
+                "reference": "7581a4407012f5f53365e11bafc520fd7f36bc9b"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/7581a4407012f5f53365e11bafc520fd7f36bc9b",
+                "reference": "7581a4407012f5f53365e11bafc520fd7f36bc9b",
+                "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|^4.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": "2026-01-08T16:22:46+00:00"
+        },
+        {
+            "name": "laravel/telescope",
+            "version": "v5.16.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/laravel/telescope.git",
+                "reference": "dc114b94f025b8c16b5eb3194b4ddc0e46d5310c"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/laravel/telescope/zipball/dc114b94f025b8c16b5eb3194b4ddc0e46d5310c",
+                "reference": "dc114b94f025b8c16b5eb3194b4ddc0e46d5310c",
+                "shasum": ""
+            },
+            "require": {
+                "ext-json": "*",
+                "laravel/framework": "^8.37|^9.0|^10.0|^11.0|^12.0",
+                "php": "^8.0",
+                "symfony/console": "^5.3|^6.0|^7.0",
+                "symfony/var-dumper": "^5.0|^6.0|^7.0"
+            },
+            "require-dev": {
+                "ext-gd": "*",
+                "guzzlehttp/guzzle": "^6.0|^7.0",
+                "laravel/octane": "^1.4|^2.0",
+                "orchestra/testbench": "^6.47.1|^7.55|^8.36|^9.15|^10.8",
+                "phpstan/phpstan": "^1.10"
+            },
+            "type": "library",
+            "extra": {
+                "laravel": {
+                    "providers": [
+                        "Laravel\\Telescope\\TelescopeServiceProvider"
+                    ]
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Laravel\\Telescope\\": "src/",
+                    "Laravel\\Telescope\\Database\\Factories\\": "database/factories/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Taylor Otwell",
+                    "email": "taylor@laravel.com"
+                },
+                {
+                    "name": "Mohamed Said",
+                    "email": "mohamed@laravel.com"
+                }
+            ],
+            "description": "An elegant debug assistant for the Laravel framework.",
+            "keywords": [
+                "debugging",
+                "laravel",
+                "monitoring"
+            ],
+            "support": {
+                "issues": "https://github.com/laravel/telescope/issues",
+                "source": "https://github.com/laravel/telescope/tree/v5.16.1"
+            },
+            "time": "2025-12-30T17:31:31+00:00"
+        },
+        {
+            "name": "laravel/tinker",
+            "version": "v2.11.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/laravel/tinker.git",
+                "reference": "3d34b97c9a1747a81a3fde90482c092bd8b66468"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/laravel/tinker/zipball/3d34b97c9a1747a81a3fde90482c092bd8b66468",
+                "reference": "3d34b97c9a1747a81a3fde90482c092bd8b66468",
+                "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|^8.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.11.0"
+            },
+            "time": "2025-12-19T19:16:45+00:00"
+        },
+        {
+            "name": "league/commonmark",
+            "version": "2.8.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/thephpleague/commonmark.git",
+                "reference": "4efa10c1e56488e658d10adf7b7b7dcd19940bfb"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/4efa10c1e56488e658d10adf7b7b7dcd19940bfb",
+                "reference": "4efa10c1e56488e658d10adf7b7b7dcd19940bfb",
+                "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.9-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-11-26T21:48:24+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.31.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/thephpleague/flysystem.git",
+                "reference": "1717e0b3642b0df65ecb0cc89cdd99fa840672ff"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/1717e0b3642b0df65ecb0cc89cdd99fa840672ff",
+                "reference": "1717e0b3642b0df65ecb0cc89cdd99fa840672ff",
+                "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.31.0"
+            },
+            "time": "2026-01-23T15:38:47+00:00"
+        },
+        {
+            "name": "league/flysystem-local",
+            "version": "3.31.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/thephpleague/flysystem-local.git",
+                "reference": "2f669db18a4c20c755c2bb7d3a7b0b2340488079"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/thephpleague/flysystem-local/zipball/2f669db18a4c20c755c2bb7d3a7b0b2340488079",
+                "reference": "2f669db18a4c20c755c2bb7d3a7b0b2340488079",
+                "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.31.0"
+            },
+            "time": "2026-01-23T15:30:45+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.8.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/thephpleague/uri.git",
+                "reference": "4436c6ec8d458e4244448b069cc572d088230b76"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/thephpleague/uri/zipball/4436c6ec8d458e4244448b069cc572d088230b76",
+                "reference": "4436c6ec8d458e4244448b069cc572d088230b76",
+                "shasum": ""
+            },
+            "require": {
+                "league/uri-interfaces": "^7.8",
+                "php": "^8.1",
+                "psr/http-factory": "^1"
+            },
+            "conflict": {
+                "league/uri-schemes": "^1.0"
+            },
+            "suggest": {
+                "ext-bcmath": "to improve IPV4 host parsing",
+                "ext-dom": "to convert the URI into an HTML anchor tag",
+                "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",
+                "ext-uri": "to use the PHP native URI class",
+                "jeremykendall/php-domain-parser": "to further parse the URI host and resolve its Public Suffix and Top Level Domain",
+                "league/uri-components": "to provide additional tools to manipulate URI objects components",
+                "league/uri-polyfill": "to backport the PHP URI extension for older versions of PHP",
+                "php-64bit": "to improve IPV4 host parsing",
+                "rowbot/url": "to handle URLs using the WHATWG URL Living Standard specification",
+                "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": [
+                "URN",
+                "data-uri",
+                "file-uri",
+                "ftp",
+                "hostname",
+                "http",
+                "https",
+                "middleware",
+                "parse_str",
+                "parse_url",
+                "psr-7",
+                "query-string",
+                "querystring",
+                "rfc2141",
+                "rfc3986",
+                "rfc3987",
+                "rfc6570",
+                "rfc8141",
+                "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.8.0"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/sponsors/nyamsprod",
+                    "type": "github"
+                }
+            ],
+            "time": "2026-01-14T17:24:56+00:00"
+        },
+        {
+            "name": "league/uri-interfaces",
+            "version": "7.8.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/thephpleague/uri-interfaces.git",
+                "reference": "c5c5cd056110fc8afaba29fa6b72a43ced42acd4"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/thephpleague/uri-interfaces/zipball/c5c5cd056110fc8afaba29fa6b72a43ced42acd4",
+                "reference": "c5c5cd056110fc8afaba29fa6b72a43ced42acd4",
+                "shasum": ""
+            },
+            "require": {
+                "ext-filter": "*",
+                "php": "^8.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",
+                "rowbot/url": "to handle URLs using the WHATWG URL Living Standard specification",
+                "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 tools for parsing and resolving RFC3987/RFC3986 URI",
+            "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.8.0"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/sponsors/nyamsprod",
+                    "type": "github"
+                }
+            ],
+            "time": "2026-01-15T06:54:53+00:00"
+        },
+        {
+            "name": "livewire/livewire",
+            "version": "v4.1.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/livewire/livewire.git",
+                "reference": "4ae4ee18448f8e9d97b68c8c091b2b597f852a6f"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/livewire/livewire/zipball/4ae4ee18448f8e9d97b68c8c091b2b597f852a6f",
+                "reference": "4ae4ee18448f8e9d97b68c8c091b2b597f852a6f",
+                "shasum": ""
+            },
+            "require": {
+                "illuminate/database": "^10.0|^11.0|^12.0",
+                "illuminate/routing": "^10.0|^11.0|^12.0",
+                "illuminate/support": "^10.0|^11.0|^12.0",
+                "illuminate/validation": "^10.0|^11.0|^12.0",
+                "laravel/prompts": "^0.1.24|^0.2|^0.3",
+                "league/mime-type-detection": "^1.9",
+                "php": "^8.1",
+                "symfony/console": "^6.0|^7.0",
+                "symfony/http-kernel": "^6.2|^7.0"
+            },
+            "require-dev": {
+                "calebporzio/sushi": "^2.1",
+                "laravel/framework": "^10.15.0|^11.0|^12.0",
+                "mockery/mockery": "^1.3.1",
+                "orchestra/testbench": "^8.21.0|^9.0|^10.0",
+                "orchestra/testbench-dusk": "^8.24|^9.1|^10.0",
+                "phpunit/phpunit": "^10.4|^11.5",
+                "psy/psysh": "^0.11.22|^0.12"
+            },
+            "type": "library",
+            "extra": {
+                "laravel": {
+                    "aliases": {
+                        "Livewire": "Livewire\\Livewire"
+                    },
+                    "providers": [
+                        "Livewire\\LivewireServiceProvider"
+                    ]
+                }
+            },
+            "autoload": {
+                "files": [
+                    "src/helpers.php"
+                ],
+                "psr-4": {
+                    "Livewire\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Caleb Porzio",
+                    "email": "calebporzio@gmail.com"
+                }
+            ],
+            "description": "A front-end framework for Laravel.",
+            "support": {
+                "issues": "https://github.com/livewire/livewire/issues",
+                "source": "https://github.com/livewire/livewire/tree/v4.1.0"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/livewire",
+                    "type": "github"
+                }
+            ],
+            "time": "2026-01-27T02:21:37+00:00"
+        },
+        {
+            "name": "livewire/volt",
+            "version": "v1.10.2",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/livewire/volt.git",
+                "reference": "4aa52b9adbdcb0f58af9cdb1ebabfbcbee32fac9"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/livewire/volt/zipball/4aa52b9adbdcb0f58af9cdb1ebabfbcbee32fac9",
+                "reference": "4aa52b9adbdcb0f58af9cdb1ebabfbcbee32fac9",
+                "shasum": ""
+            },
+            "require": {
+                "laravel/framework": "^10.38.2|^11.0|^12.0",
+                "livewire/livewire": "^3.6.1|^4.0",
+                "php": "^8.1"
+            },
+            "require-dev": {
+                "laravel/folio": "^1.1",
+                "orchestra/testbench": "^8.36|^9.15|^10.8",
+                "pestphp/pest": "^2.9.5|^3.0|^4.0",
+                "phpstan/phpstan": "^1.10"
+            },
+            "type": "library",
+            "extra": {
+                "laravel": {
+                    "providers": [
+                        "Livewire\\Volt\\VoltServiceProvider"
+                    ]
+                },
+                "branch-alias": {
+                    "dev-master": "1.x-dev"
+                }
+            },
+            "autoload": {
+                "files": [
+                    "functions.php"
+                ],
+                "psr-4": {
+                    "Livewire\\Volt\\": "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": "An elegantly crafted functional API for Laravel Livewire.",
+            "homepage": "https://github.com/livewire/volt",
+            "keywords": [
+                "laravel",
+                "livewire",
+                "volt"
+            ],
+            "support": {
+                "issues": "https://github.com/livewire/volt/issues",
+                "source": "https://github.com/livewire/volt"
+            },
+            "time": "2026-01-28T03:03:30+00:00"
+        },
+        {
+            "name": "monolog/monolog",
+            "version": "3.10.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/Seldaek/monolog.git",
+                "reference": "b321dd6749f0bf7189444158a3ce785cc16d69b0"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/Seldaek/monolog/zipball/b321dd6749f0bf7189444158a3ce785cc16d69b0",
+                "reference": "b321dd6749f0bf7189444158a3ce785cc16d69b0",
+                "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 || ^2.0",
+                "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.10.0"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/Seldaek",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/monolog/monolog",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2026-01-02T08:56:05+00:00"
+        },
+        {
+            "name": "nesbot/carbon",
+            "version": "3.11.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/CarbonPHP/carbon.git",
+                "reference": "f438fcc98f92babee98381d399c65336f3a3827f"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/CarbonPHP/carbon/zipball/f438fcc98f92babee98381d399c65336f3a3827f",
+                "reference": "f438fcc98f92babee98381d399c65336f3a3827f",
+                "shasum": ""
+            },
+            "require": {
+                "carbonphp/carbon-doctrine-types": "<100.0",
+                "ext-json": "*",
+                "php": "^8.1",
+                "psr/clock": "^1.0",
+                "symfony/clock": "^6.3.12 || ^7.0 || ^8.0",
+                "symfony/polyfill-mbstring": "^1.0",
+                "symfony/translation": "^4.4.18 || ^5.2.1 || ^6.0 || ^7.0 || ^8.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": "^v3.87.1",
+                "kylekatarnls/multi-tester": "^2.5.3",
+                "phpmd/phpmd": "^2.15.0",
+                "phpstan/extension-installer": "^1.4.3",
+                "phpstan/phpstan": "^2.1.22",
+                "phpunit/phpunit": "^10.5.53",
+                "squizlabs/php_codesniffer": "^3.13.4 || ^4.0.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://carbonphp.github.io/carbon/",
+            "keywords": [
+                "date",
+                "datetime",
+                "time"
+            ],
+            "support": {
+                "docs": "https://carbonphp.github.io/carbon/guide/getting-started/introduction.html",
+                "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": "2026-01-29T09:26:29+00:00"
+        },
+        {
+            "name": "nette/schema",
+            "version": "v1.3.3",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/nette/schema.git",
+                "reference": "2befc2f42d7c715fd9d95efc31b1081e5d765004"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/nette/schema/zipball/2befc2f42d7c715fd9d95efc31b1081e5d765004",
+                "reference": "2befc2f42d7c715fd9d95efc31b1081e5d765004",
+                "shasum": ""
+            },
+            "require": {
+                "nette/utils": "^4.0",
+                "php": "8.1 - 8.5"
+            },
+            "require-dev": {
+                "nette/tester": "^2.5.2",
+                "phpstan/phpstan-nette": "^2.0@stable",
+                "tracy/tracy": "^2.8"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.3-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 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.3"
+            },
+            "time": "2025-10-30T22:57:59+00:00"
+        },
+        {
+            "name": "nette/utils",
+            "version": "v4.1.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/nette/utils.git",
+                "reference": "c99059c0315591f1a0db7ad6002000288ab8dc72"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/nette/utils/zipball/c99059c0315591f1a0db7ad6002000288ab8dc72",
+                "reference": "c99059c0315591f1a0db7ad6002000288ab8dc72",
+                "shasum": ""
+            },
+            "require": {
+                "php": "8.2 - 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.1-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.1.1"
+            },
+            "time": "2025-12-22T12:14:32+00:00"
+        },
+        {
+            "name": "nicmart/tree",
+            "version": "0.10.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/nicmart/Tree.git",
+                "reference": "2ef11e329d26005ef49dbacd0223bcfd2515b6cc"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/nicmart/Tree/zipball/2ef11e329d26005ef49dbacd0223bcfd2515b6cc",
+                "reference": "2ef11e329d26005ef49dbacd0223bcfd2515b6cc",
+                "shasum": ""
+            },
+            "require": {
+                "php": "~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0"
+            },
+            "require-dev": {
+                "ergebnis/composer-normalize": "^2.48.2",
+                "ergebnis/license": "^2.7.0",
+                "ergebnis/php-cs-fixer-config": "^6.28.1",
+                "fakerphp/faker": "^1.24.1",
+                "infection/infection": "~0.26.19",
+                "phpunit/phpunit": "^9.6.19",
+                "psalm/plugin-phpunit": "~0.19.0",
+                "vimeo/psalm": "^5.26.1"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Tree\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Nicolò Martini",
+                    "email": "nicmartnic@gmail.com"
+                },
+                {
+                    "name": "Andreas Möller",
+                    "email": "am@localheinz.com"
+                }
+            ],
+            "description": "A basic but flexible php tree data structure and a fluent tree builder implementation.",
+            "support": {
+                "issues": "https://github.com/nicmart/Tree/issues",
+                "source": "https://github.com/nicmart/Tree/tree/0.10.1"
+            },
+            "time": "2025-11-25T08:51:01+00:00"
+        },
+        {
+            "name": "nikic/php-parser",
+            "version": "v5.7.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/nikic/PHP-Parser.git",
+                "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/dca41cd15c2ac9d055ad70dbfd011130757d1f82",
+                "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82",
+                "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.x-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.7.0"
+            },
+            "time": "2025-12-06T11:56:16+00:00"
+        },
+        {
+            "name": "nunomaduro/termwind",
+            "version": "v2.3.3",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/nunomaduro/termwind.git",
+                "reference": "6fb2a640ff502caace8e05fd7be3b503a7e1c017"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/nunomaduro/termwind/zipball/6fb2a640ff502caace8e05fd7be3b503a7e1c017",
+                "reference": "6fb2a640ff502caace8e05fd7be3b503a7e1c017",
+                "shasum": ""
+            },
+            "require": {
+                "ext-mbstring": "*",
+                "php": "^8.2",
+                "symfony/console": "^7.3.6"
+            },
+            "require-dev": {
+                "illuminate/console": "^11.46.1",
+                "laravel/pint": "^1.25.1",
+                "mockery/mockery": "^1.6.12",
+                "pestphp/pest": "^2.36.0 || ^3.8.4 || ^4.1.3",
+                "phpstan/phpstan": "^1.12.32",
+                "phpstan/phpstan-strict-rules": "^1.6.2",
+                "symfony/var-dumper": "^7.3.5",
+                "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.3"
+            },
+            "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-11-20T02:34:59+00:00"
+        },
+        {
+            "name": "phpdocumentor/reflection",
+            "version": "6.4.4",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/phpDocumentor/Reflection.git",
+                "reference": "5e5db15b34e6eae755cb97beaa7fe076ae9e8d4c"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/phpDocumentor/Reflection/zipball/5e5db15b34e6eae755cb97beaa7fe076ae9e8d4c",
+                "reference": "5e5db15b34e6eae755cb97beaa7fe076ae9e8d4c",
+                "shasum": ""
+            },
+            "require": {
+                "composer-runtime-api": "^2",
+                "nikic/php-parser": "~4.18 || ^5.0",
+                "php": "8.1.*|8.2.*|8.3.*|8.4.*|8.5.*",
+                "phpdocumentor/reflection-common": "^2.1",
+                "phpdocumentor/reflection-docblock": "^5",
+                "phpdocumentor/type-resolver": "^1.4",
+                "symfony/polyfill-php80": "^1.28",
+                "webmozart/assert": "^1.7"
+            },
+            "require-dev": {
+                "dealerdirect/phpcodesniffer-composer-installer": "^1.0",
+                "doctrine/coding-standard": "^13.0",
+                "eliashaeussler/phpunit-attributes": "^1.8",
+                "mikey179/vfsstream": "~1.2",
+                "mockery/mockery": "~1.6.0",
+                "phpspec/prophecy-phpunit": "^2.4",
+                "phpstan/extension-installer": "^1.1",
+                "phpstan/phpstan": "^1.8",
+                "phpstan/phpstan-webmozart-assert": "^1.2",
+                "phpunit/phpunit": "^10.5.53",
+                "psalm/phar": "^6.0",
+                "rector/rector": "^1.0.0",
+                "squizlabs/php_codesniffer": "^3.8"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-5.x": "5.3.x-dev",
+                    "dev-6.x": "6.0.x-dev"
+                }
+            },
+            "autoload": {
+                "files": [
+                    "src/php-parser/Modifiers.php"
+                ],
+                "psr-4": {
+                    "phpDocumentor\\": "src/phpDocumentor"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "description": "Reflection library to do Static Analysis for PHP Projects",
+            "homepage": "http://www.phpdoc.org",
+            "keywords": [
+                "phpDocumentor",
+                "phpdoc",
+                "reflection",
+                "static analysis"
+            ],
+            "support": {
+                "issues": "https://github.com/phpDocumentor/Reflection/issues",
+                "source": "https://github.com/phpDocumentor/Reflection/tree/6.4.4"
+            },
+            "time": "2025-11-25T21:21:18+00:00"
+        },
+        {
+            "name": "phpdocumentor/reflection-common",
+            "version": "2.2.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/phpDocumentor/ReflectionCommon.git",
+                "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b",
+                "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.2 || ^8.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-2.x": "2.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "phpDocumentor\\Reflection\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Jaap van Otterdijk",
+                    "email": "opensource@ijaap.nl"
+                }
+            ],
+            "description": "Common reflection classes used by phpdocumentor to reflect the code structure",
+            "homepage": "http://www.phpdoc.org",
+            "keywords": [
+                "FQSEN",
+                "phpDocumentor",
+                "phpdoc",
+                "reflection",
+                "static analysis"
+            ],
+            "support": {
+                "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues",
+                "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x"
+            },
+            "time": "2020-06-27T09:03:43+00:00"
+        },
+        {
+            "name": "phpdocumentor/reflection-docblock",
+            "version": "5.6.6",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
+                "reference": "5cee1d3dfc2d2aa6599834520911d246f656bcb8"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/5cee1d3dfc2d2aa6599834520911d246f656bcb8",
+                "reference": "5cee1d3dfc2d2aa6599834520911d246f656bcb8",
+                "shasum": ""
+            },
+            "require": {
+                "doctrine/deprecations": "^1.1",
+                "ext-filter": "*",
+                "php": "^7.4 || ^8.0",
+                "phpdocumentor/reflection-common": "^2.2",
+                "phpdocumentor/type-resolver": "^1.7",
+                "phpstan/phpdoc-parser": "^1.7|^2.0",
+                "webmozart/assert": "^1.9.1 || ^2"
+            },
+            "require-dev": {
+                "mockery/mockery": "~1.3.5 || ~1.6.0",
+                "phpstan/extension-installer": "^1.1",
+                "phpstan/phpstan": "^1.8",
+                "phpstan/phpstan-mockery": "^1.1",
+                "phpstan/phpstan-webmozart-assert": "^1.2",
+                "phpunit/phpunit": "^9.5",
+                "psalm/phar": "^5.26"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "5.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "phpDocumentor\\Reflection\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Mike van Riel",
+                    "email": "me@mikevanriel.com"
+                },
+                {
+                    "name": "Jaap van Otterdijk",
+                    "email": "opensource@ijaap.nl"
+                }
+            ],
+            "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
+            "support": {
+                "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues",
+                "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.6.6"
+            },
+            "time": "2025-12-22T21:13:58+00:00"
+        },
+        {
+            "name": "phpdocumentor/type-resolver",
+            "version": "1.12.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/phpDocumentor/TypeResolver.git",
+                "reference": "92a98ada2b93d9b201a613cb5a33584dde25f195"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/92a98ada2b93d9b201a613cb5a33584dde25f195",
+                "reference": "92a98ada2b93d9b201a613cb5a33584dde25f195",
+                "shasum": ""
+            },
+            "require": {
+                "doctrine/deprecations": "^1.0",
+                "php": "^7.3 || ^8.0",
+                "phpdocumentor/reflection-common": "^2.0",
+                "phpstan/phpdoc-parser": "^1.18|^2.0"
+            },
+            "require-dev": {
+                "ext-tokenizer": "*",
+                "phpbench/phpbench": "^1.2",
+                "phpstan/extension-installer": "^1.1",
+                "phpstan/phpstan": "^1.8",
+                "phpstan/phpstan-phpunit": "^1.1",
+                "phpunit/phpunit": "^9.5",
+                "rector/rector": "^0.13.9",
+                "vimeo/psalm": "^4.25"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-1.x": "1.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "phpDocumentor\\Reflection\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Mike van Riel",
+                    "email": "me@mikevanriel.com"
+                }
+            ],
+            "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names",
+            "support": {
+                "issues": "https://github.com/phpDocumentor/TypeResolver/issues",
+                "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.12.0"
+            },
+            "time": "2025-11-21T15:09:14+00:00"
+        },
+        {
+            "name": "phpoption/phpoption",
+            "version": "1.9.5",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/schmittjoh/php-option.git",
+                "reference": "75365b91986c2405cf5e1e012c5595cd487a98be"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/75365b91986c2405cf5e1e012c5595cd487a98be",
+                "reference": "75365b91986c2405cf5e1e012c5595cd487a98be",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.2.5 || ^8.0"
+            },
+            "require-dev": {
+                "bamarni/composer-bin-plugin": "^1.8.2",
+                "phpunit/phpunit": "^8.5.44 || ^9.6.25 || ^10.5.53 || ^11.5.34"
+            },
+            "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.5"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/GrahamCampbell",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/phpoption/phpoption",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2025-12-27T19:41:33+00:00"
+        },
+        {
+            "name": "phpstan/phpdoc-parser",
+            "version": "2.3.2",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/phpstan/phpdoc-parser.git",
+                "reference": "a004701b11273a26cd7955a61d67a7f1e525a45a"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/a004701b11273a26cd7955a61d67a7f1e525a45a",
+                "reference": "a004701b11273a26cd7955a61d67a7f1e525a45a",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.4 || ^8.0"
+            },
+            "require-dev": {
+                "doctrine/annotations": "^2.0",
+                "nikic/php-parser": "^5.3.0",
+                "php-parallel-lint/php-parallel-lint": "^1.2",
+                "phpstan/extension-installer": "^1.0",
+                "phpstan/phpstan": "^2.0",
+                "phpstan/phpstan-phpunit": "^2.0",
+                "phpstan/phpstan-strict-rules": "^2.0",
+                "phpunit/phpunit": "^9.6",
+                "symfony/process": "^5.2"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "PHPStan\\PhpDocParser\\": [
+                        "src/"
+                    ]
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "description": "PHPDoc parser with support for nullable, intersection and generic types",
+            "support": {
+                "issues": "https://github.com/phpstan/phpdoc-parser/issues",
+                "source": "https://github.com/phpstan/phpdoc-parser/tree/2.3.2"
+            },
+            "time": "2026-01-25T14:56:51+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.18",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/bobthecow/psysh.git",
+                "reference": "ddff0ac01beddc251786fe70367cd8bbdb258196"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/bobthecow/psysh/zipball/ddff0ac01beddc251786fe70367cd8bbdb258196",
+                "reference": "ddff0ac01beddc251786fe70367cd8bbdb258196",
+                "shasum": ""
+            },
+            "require": {
+                "ext-json": "*",
+                "ext-tokenizer": "*",
+                "nikic/php-parser": "^5.0 || ^4.0",
+                "php": "^8.0 || ^7.4",
+                "symfony/console": "^8.0 || ^7.0 || ^6.0 || ^5.0 || ^4.0 || ^3.4",
+                "symfony/var-dumper": "^8.0 || ^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",
+                "composer/class-map-generator": "^1.6"
+            },
+            "suggest": {
+                "composer/class-map-generator": "Improved tab completion performance with better class discovery.",
+                "ext-pcntl": "Enabling the PCNTL extension makes PsySH a lot happier :)",
+                "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.18"
+            },
+            "time": "2025-12-17T14:35:46+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.2",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/ramsey/uuid.git",
+                "reference": "8429c78ca35a09f27565311b98101e2826affde0"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/ramsey/uuid/zipball/8429c78ca35a09f27565311b98101e2826affde0",
+                "reference": "8429c78ca35a09f27565311b98101e2826affde0",
+                "shasum": ""
+            },
+            "require": {
+                "brick/math": "^0.8.16 || ^0.9 || ^0.10 || ^0.11 || ^0.12 || ^0.13 || ^0.14",
+                "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.2"
+            },
+            "time": "2025-12-14T04:43:48+00:00"
+        },
+        {
+            "name": "spatie/browsershot",
+            "version": "5.2.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/spatie/browsershot.git",
+                "reference": "9bc6b8d67175810d7a399b2588c3401efe2d02a8"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/spatie/browsershot/zipball/9bc6b8d67175810d7a399b2588c3401efe2d02a8",
+                "reference": "9bc6b8d67175810d7a399b2588c3401efe2d02a8",
+                "shasum": ""
+            },
+            "require": {
+                "ext-fileinfo": "*",
+                "ext-json": "*",
+                "php": "^8.2",
+                "spatie/temporary-directory": "^2.0",
+                "symfony/process": "^6.0|^7.0|^8.0"
+            },
+            "require-dev": {
+                "pestphp/pest": "^3.0|^4.0",
+                "spatie/image": "^3.6",
+                "spatie/pdf-to-text": "^1.52",
+                "spatie/phpunit-snapshot-assertions": "^5.0"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Spatie\\Browsershot\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Freek Van der Herten",
+                    "email": "freek@spatie.be",
+                    "homepage": "https://github.com/freekmurze",
+                    "role": "Developer"
+                }
+            ],
+            "description": "Convert a webpage to an image or pdf using headless Chrome",
+            "homepage": "https://github.com/spatie/browsershot",
+            "keywords": [
+                "chrome",
+                "convert",
+                "headless",
+                "image",
+                "pdf",
+                "puppeteer",
+                "screenshot",
+                "webpage"
+            ],
+            "support": {
+                "source": "https://github.com/spatie/browsershot/tree/5.2.0"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/spatie",
+                    "type": "github"
+                }
+            ],
+            "time": "2025-12-22T10:02:16+00:00"
+        },
+        {
+            "name": "spatie/crawler",
+            "version": "8.4.7",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/spatie/crawler.git",
+                "reference": "67cbd569437d0e35b1332c5f21d009cac8b4a37b"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/spatie/crawler/zipball/67cbd569437d0e35b1332c5f21d009cac8b4a37b",
+                "reference": "67cbd569437d0e35b1332c5f21d009cac8b4a37b",
+                "shasum": ""
+            },
+            "require": {
+                "guzzlehttp/guzzle": "^7.3",
+                "guzzlehttp/psr7": "^2.0",
+                "illuminate/collections": "^10.0|^11.0|^12.0",
+                "nicmart/tree": "^0.10",
+                "php": "^8.2",
+                "spatie/browsershot": "^5.0.5",
+                "spatie/robots-txt": "^2.0",
+                "symfony/dom-crawler": "^6.0|^7.0|^8.0"
+            },
+            "require-dev": {
+                "pestphp/pest": "^2.0|^3.0",
+                "spatie/ray": "^1.37"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Spatie\\Crawler\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Freek Van der Herten",
+                    "email": "freek@spatie.be"
+                }
+            ],
+            "description": "Crawl all internal links found on a website",
+            "homepage": "https://github.com/spatie/crawler",
+            "keywords": [
+                "crawler",
+                "link",
+                "spatie",
+                "website"
+            ],
+            "support": {
+                "issues": "https://github.com/spatie/crawler/issues",
+                "source": "https://github.com/spatie/crawler/tree/8.4.7"
+            },
+            "funding": [
+                {
+                    "url": "https://spatie.be/open-source/support-us",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/spatie",
+                    "type": "github"
+                }
+            ],
+            "time": "2025-11-26T17:35:15+00:00"
+        },
+        {
+            "name": "spatie/laravel-data",
+            "version": "4.19.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/spatie/laravel-data.git",
+                "reference": "41ed0472250676f19440fb24d7b62a8d43abdb89"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/spatie/laravel-data/zipball/41ed0472250676f19440fb24d7b62a8d43abdb89",
+                "reference": "41ed0472250676f19440fb24d7b62a8d43abdb89",
+                "shasum": ""
+            },
+            "require": {
+                "illuminate/contracts": "^10.0|^11.0|^12.0",
+                "php": "^8.1",
+                "phpdocumentor/reflection": "^6.0",
+                "spatie/laravel-package-tools": "^1.9.0",
+                "spatie/php-structure-discoverer": "^2.0"
+            },
+            "require-dev": {
+                "fakerphp/faker": "^1.14",
+                "friendsofphp/php-cs-fixer": "^3.0",
+                "inertiajs/inertia-laravel": "^2.0",
+                "livewire/livewire": "^3.0",
+                "mockery/mockery": "^1.6",
+                "nesbot/carbon": "^2.63|^3.0",
+                "orchestra/testbench": "^8.37.0|^9.16|^10.9",
+                "pestphp/pest": "^2.36|^3.8|^4.3",
+                "pestphp/pest-plugin-laravel": "^2.4|^3.0|^4.0",
+                "pestphp/pest-plugin-livewire": "^2.1|^3.0|^4.0",
+                "phpbench/phpbench": "^1.2",
+                "phpstan/extension-installer": "^1.1",
+                "spatie/invade": "^1.0",
+                "spatie/laravel-typescript-transformer": "^2.5",
+                "spatie/pest-plugin-snapshots": "^2.1",
+                "spatie/test-time": "^1.2"
+            },
+            "type": "library",
+            "extra": {
+                "laravel": {
+                    "providers": [
+                        "Spatie\\LaravelData\\LaravelDataServiceProvider"
+                    ]
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Spatie\\LaravelData\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Ruben Van Assche",
+                    "email": "ruben@spatie.be",
+                    "role": "Developer"
+                }
+            ],
+            "description": "Create unified resources and data transfer objects",
+            "homepage": "https://github.com/spatie/laravel-data",
+            "keywords": [
+                "laravel",
+                "laravel-data",
+                "spatie"
+            ],
+            "support": {
+                "issues": "https://github.com/spatie/laravel-data/issues",
+                "source": "https://github.com/spatie/laravel-data/tree/4.19.1"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/spatie",
+                    "type": "github"
+                }
+            ],
+            "time": "2026-01-28T13:10:20+00:00"
+        },
+        {
+            "name": "spatie/laravel-package-tools",
+            "version": "1.92.7",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/spatie/laravel-package-tools.git",
+                "reference": "f09a799850b1ed765103a4f0b4355006360c49a5"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/spatie/laravel-package-tools/zipball/f09a799850b1ed765103a4f0b4355006360c49a5",
+                "reference": "f09a799850b1ed765103a4f0b4355006360c49a5",
+                "shasum": ""
+            },
+            "require": {
+                "illuminate/contracts": "^9.28|^10.0|^11.0|^12.0",
+                "php": "^8.0"
+            },
+            "require-dev": {
+                "mockery/mockery": "^1.5",
+                "orchestra/testbench": "^7.7|^8.0|^9.0|^10.0",
+                "pestphp/pest": "^1.23|^2.1|^3.1",
+                "phpunit/php-code-coverage": "^9.0|^10.0|^11.0",
+                "phpunit/phpunit": "^9.5.24|^10.5|^11.5",
+                "spatie/pest-plugin-test-time": "^1.1|^2.2"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Spatie\\LaravelPackageTools\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Freek Van der Herten",
+                    "email": "freek@spatie.be",
+                    "role": "Developer"
+                }
+            ],
+            "description": "Tools for creating Laravel packages",
+            "homepage": "https://github.com/spatie/laravel-package-tools",
+            "keywords": [
+                "laravel-package-tools",
+                "spatie"
+            ],
+            "support": {
+                "issues": "https://github.com/spatie/laravel-package-tools/issues",
+                "source": "https://github.com/spatie/laravel-package-tools/tree/1.92.7"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/spatie",
+                    "type": "github"
+                }
+            ],
+            "time": "2025-07-17T15:46:43+00:00"
+        },
+        {
+            "name": "spatie/laravel-sitemap",
+            "version": "7.3.8",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/spatie/laravel-sitemap.git",
+                "reference": "9ff614d4834ada564aed5ed88507c9e5baab8e51"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/spatie/laravel-sitemap/zipball/9ff614d4834ada564aed5ed88507c9e5baab8e51",
+                "reference": "9ff614d4834ada564aed5ed88507c9e5baab8e51",
+                "shasum": ""
+            },
+            "require": {
+                "guzzlehttp/guzzle": "^7.8",
+                "illuminate/support": "^11.0|^12.0",
+                "nesbot/carbon": "^2.71|^3.0",
+                "php": "^8.2||^8.3||^8.4",
+                "spatie/crawler": "^8.0.1",
+                "spatie/laravel-package-tools": "^1.16.1",
+                "symfony/dom-crawler": "^6.3.4|^7.0|^8.0"
+            },
+            "require-dev": {
+                "mockery/mockery": "^1.6.6",
+                "orchestra/testbench": "^9.0|^10.0",
+                "pestphp/pest": "^3.7.4",
+                "spatie/pest-plugin-snapshots": "^2.1",
+                "spatie/phpunit-snapshot-assertions": "^5.1.2",
+                "spatie/temporary-directory": "^2.2"
+            },
+            "type": "library",
+            "extra": {
+                "laravel": {
+                    "providers": [
+                        "Spatie\\Sitemap\\SitemapServiceProvider"
+                    ]
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Spatie\\Sitemap\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Freek Van der Herten",
+                    "email": "freek@spatie.be",
+                    "homepage": "https://spatie.be",
+                    "role": "Developer"
+                }
+            ],
+            "description": "Create and generate sitemaps with ease",
+            "homepage": "https://github.com/spatie/laravel-sitemap",
+            "keywords": [
+                "laravel-sitemap",
+                "spatie"
+            ],
+            "support": {
+                "source": "https://github.com/spatie/laravel-sitemap/tree/7.3.8"
+            },
+            "funding": [
+                {
+                    "url": "https://spatie.be/open-source/support-us",
+                    "type": "custom"
+                }
+            ],
+            "time": "2025-11-25T21:06:08+00:00"
+        },
+        {
+            "name": "spatie/laravel-sluggable",
+            "version": "3.7.5",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/spatie/laravel-sluggable.git",
+                "reference": "e4fdd519e043a2af02b52eec2c3be2dd2e262e27"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/spatie/laravel-sluggable/zipball/e4fdd519e043a2af02b52eec2c3be2dd2e262e27",
+                "reference": "e4fdd519e043a2af02b52eec2c3be2dd2e262e27",
+                "shasum": ""
+            },
+            "require": {
+                "illuminate/database": "^8.0|^9.0|^10.0|^11.0|^12.0",
+                "illuminate/support": "^8.0|^9.0|^10.0|^11.0|^12.0",
+                "php": "^8.0"
+            },
+            "require-dev": {
+                "orchestra/testbench": "^6.23|^7.0|^8.0|^9.0|^10.0",
+                "pestphp/pest": "^1.20|^2.0|^3.7",
+                "spatie/laravel-translatable": "^5.0|^6.0"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Spatie\\Sluggable\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Freek Van der Herten",
+                    "email": "freek@spatie.be",
+                    "homepage": "https://spatie.be",
+                    "role": "Developer"
+                }
+            ],
+            "description": "Generate slugs when saving Eloquent models",
+            "homepage": "https://github.com/spatie/laravel-sluggable",
+            "keywords": [
+                "laravel-sluggable",
+                "spatie"
+            ],
+            "support": {
+                "source": "https://github.com/spatie/laravel-sluggable/tree/3.7.5"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/spatie",
+                    "type": "github"
+                }
+            ],
+            "time": "2025-04-24T09:21:00+00:00"
+        },
+        {
+            "name": "spatie/php-structure-discoverer",
+            "version": "2.3.3",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/spatie/php-structure-discoverer.git",
+                "reference": "552a5b974a9853a32e5677a66e85ae615a96a90b"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/spatie/php-structure-discoverer/zipball/552a5b974a9853a32e5677a66e85ae615a96a90b",
+                "reference": "552a5b974a9853a32e5677a66e85ae615a96a90b",
+                "shasum": ""
+            },
+            "require": {
+                "illuminate/collections": "^11.0|^12.0",
+                "php": "^8.3",
+                "spatie/laravel-package-tools": "^1.92.7",
+                "symfony/finder": "^6.0|^7.3.5|^8.0"
+            },
+            "require-dev": {
+                "amphp/parallel": "^2.3.2",
+                "illuminate/console": "^11.0|^12.0",
+                "nunomaduro/collision": "^7.0|^8.8.3",
+                "orchestra/testbench": "^9.5|^10.8",
+                "pestphp/pest": "^3.8|^4.0",
+                "pestphp/pest-plugin-laravel": "^3.2|^4.0",
+                "phpstan/extension-installer": "^1.4.3",
+                "phpstan/phpstan-deprecation-rules": "^1.2.1",
+                "phpstan/phpstan-phpunit": "^1.4.2",
+                "spatie/laravel-ray": "^1.43.1"
+            },
+            "suggest": {
+                "amphp/parallel": "When you want to use the Parallel discover worker"
+            },
+            "type": "library",
+            "extra": {
+                "laravel": {
+                    "providers": [
+                        "Spatie\\StructureDiscoverer\\StructureDiscovererServiceProvider"
+                    ]
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Spatie\\StructureDiscoverer\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Ruben Van Assche",
+                    "email": "ruben@spatie.be",
+                    "role": "Developer"
+                }
+            ],
+            "description": "Automatically discover structures within your PHP application",
+            "homepage": "https://github.com/spatie/php-structure-discoverer",
+            "keywords": [
+                "discover",
+                "laravel",
+                "php",
+                "php-structure-discoverer"
+            ],
+            "support": {
+                "issues": "https://github.com/spatie/php-structure-discoverer/issues",
+                "source": "https://github.com/spatie/php-structure-discoverer/tree/2.3.3"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/LaravelAutoDiscoverer",
+                    "type": "github"
+                }
+            ],
+            "time": "2025-11-24T16:41:01+00:00"
+        },
+        {
+            "name": "spatie/robots-txt",
+            "version": "2.5.3",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/spatie/robots-txt.git",
+                "reference": "edb91c798ec70583d41c131019da45fa167af5e8"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/spatie/robots-txt/zipball/edb91c798ec70583d41c131019da45fa167af5e8",
+                "reference": "edb91c798ec70583d41c131019da45fa167af5e8",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^8.1"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^11.5.2"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Spatie\\Robots\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Brent Roose",
+                    "email": "brent@spatie.be",
+                    "homepage": "https://spatie.be",
+                    "role": "Developer"
+                }
+            ],
+            "description": "Determine if a page may be crawled from robots.txt and robots meta tags",
+            "homepage": "https://github.com/spatie/robots-txt",
+            "keywords": [
+                "robots-txt",
+                "spatie"
+            ],
+            "support": {
+                "issues": "https://github.com/spatie/robots-txt/issues",
+                "source": "https://github.com/spatie/robots-txt/tree/2.5.3"
+            },
+            "funding": [
+                {
+                    "url": "https://spatie.be/open-source/support-us",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/spatie",
+                    "type": "github"
+                }
+            ],
+            "time": "2025-11-20T13:00:33+00:00"
+        },
+        {
+            "name": "spatie/temporary-directory",
+            "version": "2.3.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/spatie/temporary-directory.git",
+                "reference": "662e481d6ec07ef29fd05010433428851a42cd07"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/spatie/temporary-directory/zipball/662e481d6ec07ef29fd05010433428851a42cd07",
+                "reference": "662e481d6ec07ef29fd05010433428851a42cd07",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^8.0"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^9.5"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Spatie\\TemporaryDirectory\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Alex Vanderbist",
+                    "email": "alex@spatie.be",
+                    "homepage": "https://spatie.be",
+                    "role": "Developer"
+                }
+            ],
+            "description": "Easily create, use and destroy temporary directories",
+            "homepage": "https://github.com/spatie/temporary-directory",
+            "keywords": [
+                "php",
+                "spatie",
+                "temporary-directory"
+            ],
+            "support": {
+                "issues": "https://github.com/spatie/temporary-directory/issues",
+                "source": "https://github.com/spatie/temporary-directory/tree/2.3.1"
+            },
+            "funding": [
+                {
+                    "url": "https://spatie.be/open-source/support-us",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/spatie",
+                    "type": "github"
+                }
+            ],
+            "time": "2026-01-12T07:42:22+00:00"
+        },
+        {
+            "name": "spatie/yaml-front-matter",
+            "version": "2.1.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/spatie/yaml-front-matter.git",
+                "reference": "3066996d0e4ed74bcc22c261084a9df727bf7e36"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/spatie/yaml-front-matter/zipball/3066996d0e4ed74bcc22c261084a9df727bf7e36",
+                "reference": "3066996d0e4ed74bcc22c261084a9df727bf7e36",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^8.0",
+                "symfony/yaml": "^6.0|^7.0|^8.0"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^9.0"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Spatie\\YamlFrontMatter\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian De Deyne",
+                    "email": "sebastian@spatie.be",
+                    "homepage": "https://spatie.be",
+                    "role": "Developer"
+                }
+            ],
+            "description": "A to the point yaml front matter parser",
+            "homepage": "https://github.com/sebastiandedeyne/yaml-front-matter",
+            "keywords": [
+                "front matter",
+                "jekyll",
+                "spatie",
+                "yaml"
+            ],
+            "support": {
+                "source": "https://github.com/spatie/yaml-front-matter/tree/2.1.1"
+            },
+            "funding": [
+                {
+                    "url": "https://spatie.be/open-source/support-us",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/spatie",
+                    "type": "github"
+                }
+            ],
+            "time": "2025-11-24T16:17:28+00:00"
+        },
+        {
+            "name": "symfony/clock",
+            "version": "v8.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/clock.git",
+                "reference": "832119f9b8dbc6c8e6f65f30c5969eca1e88764f"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/clock/zipball/832119f9b8dbc6c8e6f65f30c5969eca1e88764f",
+                "reference": "832119f9b8dbc6c8e6f65f30c5969eca1e88764f",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=8.4",
+                "psr/clock": "^1.0"
+            },
+            "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/v8.0.0"
+            },
+            "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-11-12T15:46:48+00:00"
+        },
+        {
+            "name": "symfony/console",
+            "version": "v7.4.4",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/console.git",
+                "reference": "41e38717ac1dd7a46b6bda7d6a82af2d98a78894"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/console/zipball/41e38717ac1dd7a46b6bda7d6a82af2d98a78894",
+                "reference": "41e38717ac1dd7a46b6bda7d6a82af2d98a78894",
+                "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|^8.0"
+            },
+            "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|^8.0",
+                "symfony/dependency-injection": "^6.4|^7.0|^8.0",
+                "symfony/event-dispatcher": "^6.4|^7.0|^8.0",
+                "symfony/http-foundation": "^6.4|^7.0|^8.0",
+                "symfony/http-kernel": "^6.4|^7.0|^8.0",
+                "symfony/lock": "^6.4|^7.0|^8.0",
+                "symfony/messenger": "^6.4|^7.0|^8.0",
+                "symfony/process": "^6.4|^7.0|^8.0",
+                "symfony/stopwatch": "^6.4|^7.0|^8.0",
+                "symfony/var-dumper": "^6.4|^7.0|^8.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.4.4"
+            },
+            "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": "2026-01-13T11:36:38+00:00"
+        },
+        {
+            "name": "symfony/css-selector",
+            "version": "v8.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/css-selector.git",
+                "reference": "6225bd458c53ecdee056214cb4a2ffaf58bd592b"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/css-selector/zipball/6225bd458c53ecdee056214cb4a2ffaf58bd592b",
+                "reference": "6225bd458c53ecdee056214cb4a2ffaf58bd592b",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=8.4"
+            },
+            "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/v8.0.0"
+            },
+            "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-10-30T14:17:19+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/dom-crawler",
+            "version": "v8.0.4",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/dom-crawler.git",
+                "reference": "fd78228fa362b41729173183493f46b1df49485f"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/fd78228fa362b41729173183493f46b1df49485f",
+                "reference": "fd78228fa362b41729173183493f46b1df49485f",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=8.4",
+                "symfony/polyfill-ctype": "^1.8",
+                "symfony/polyfill-mbstring": "^1.0"
+            },
+            "require-dev": {
+                "symfony/css-selector": "^7.4|^8.0"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Symfony\\Component\\DomCrawler\\": ""
+                },
+                "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 DOM navigation for HTML and XML documents",
+            "homepage": "https://symfony.com",
+            "support": {
+                "source": "https://github.com/symfony/dom-crawler/tree/v8.0.4"
+            },
+            "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": "2026-01-05T09:27:50+00:00"
+        },
+        {
+            "name": "symfony/error-handler",
+            "version": "v7.4.4",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/error-handler.git",
+                "reference": "8da531f364ddfee53e36092a7eebbbd0b775f6b8"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/error-handler/zipball/8da531f364ddfee53e36092a7eebbbd0b775f6b8",
+                "reference": "8da531f364ddfee53e36092a7eebbbd0b775f6b8",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=8.2",
+                "psr/log": "^1|^2|^3",
+                "symfony/polyfill-php85": "^1.32",
+                "symfony/var-dumper": "^6.4|^7.0|^8.0"
+            },
+            "conflict": {
+                "symfony/deprecation-contracts": "<2.5",
+                "symfony/http-kernel": "<6.4"
+            },
+            "require-dev": {
+                "symfony/console": "^6.4|^7.0|^8.0",
+                "symfony/deprecation-contracts": "^2.5|^3",
+                "symfony/http-kernel": "^6.4|^7.0|^8.0",
+                "symfony/serializer": "^6.4|^7.0|^8.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.4.4"
+            },
+            "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": "2026-01-20T16:42:42+00:00"
+        },
+        {
+            "name": "symfony/event-dispatcher",
+            "version": "v8.0.4",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/event-dispatcher.git",
+                "reference": "99301401da182b6cfaa4700dbe9987bb75474b47"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/99301401da182b6cfaa4700dbe9987bb75474b47",
+                "reference": "99301401da182b6cfaa4700dbe9987bb75474b47",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=8.4",
+                "symfony/event-dispatcher-contracts": "^2.5|^3"
+            },
+            "conflict": {
+                "symfony/security-http": "<7.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": "^7.4|^8.0",
+                "symfony/dependency-injection": "^7.4|^8.0",
+                "symfony/error-handler": "^7.4|^8.0",
+                "symfony/expression-language": "^7.4|^8.0",
+                "symfony/framework-bundle": "^7.4|^8.0",
+                "symfony/http-foundation": "^7.4|^8.0",
+                "symfony/service-contracts": "^2.5|^3",
+                "symfony/stopwatch": "^7.4|^8.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/v8.0.4"
+            },
+            "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": "2026-01-05T11:45:55+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.4.5",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/finder.git",
+                "reference": "ad4daa7c38668dcb031e63bc99ea9bd42196a2cb"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/finder/zipball/ad4daa7c38668dcb031e63bc99ea9bd42196a2cb",
+                "reference": "ad4daa7c38668dcb031e63bc99ea9bd42196a2cb",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=8.2"
+            },
+            "require-dev": {
+                "symfony/filesystem": "^6.4|^7.0|^8.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.4.5"
+            },
+            "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": "2026-01-26T15:07:59+00:00"
+        },
+        {
+            "name": "symfony/http-foundation",
+            "version": "v7.4.5",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/http-foundation.git",
+                "reference": "446d0db2b1f21575f1284b74533e425096abdfb6"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/http-foundation/zipball/446d0db2b1f21575f1284b74533e425096abdfb6",
+                "reference": "446d0db2b1f21575f1284b74533e425096abdfb6",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=8.2",
+                "symfony/deprecation-contracts": "^2.5|^3",
+                "symfony/polyfill-mbstring": "^1.1"
+            },
+            "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|^8.0",
+                "symfony/clock": "^6.4|^7.0|^8.0",
+                "symfony/dependency-injection": "^6.4|^7.0|^8.0",
+                "symfony/expression-language": "^6.4|^7.0|^8.0",
+                "symfony/http-kernel": "^6.4|^7.0|^8.0",
+                "symfony/mime": "^6.4|^7.0|^8.0",
+                "symfony/rate-limiter": "^6.4|^7.0|^8.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.4.5"
+            },
+            "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": "2026-01-27T16:16:02+00:00"
+        },
+        {
+            "name": "symfony/http-kernel",
+            "version": "v7.4.5",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/http-kernel.git",
+                "reference": "229eda477017f92bd2ce7615d06222ec0c19e82a"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/http-kernel/zipball/229eda477017f92bd2ce7615d06222ec0c19e82a",
+                "reference": "229eda477017f92bd2ce7615d06222ec0c19e82a",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=8.2",
+                "psr/log": "^1|^2|^3",
+                "symfony/deprecation-contracts": "^2.5|^3",
+                "symfony/error-handler": "^6.4|^7.0|^8.0",
+                "symfony/event-dispatcher": "^7.3|^8.0",
+                "symfony/http-foundation": "^7.4|^8.0",
+                "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/flex": "<2.10",
+                "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|^8.0",
+                "symfony/clock": "^6.4|^7.0|^8.0",
+                "symfony/config": "^6.4|^7.0|^8.0",
+                "symfony/console": "^6.4|^7.0|^8.0",
+                "symfony/css-selector": "^6.4|^7.0|^8.0",
+                "symfony/dependency-injection": "^6.4|^7.0|^8.0",
+                "symfony/dom-crawler": "^6.4|^7.0|^8.0",
+                "symfony/expression-language": "^6.4|^7.0|^8.0",
+                "symfony/finder": "^6.4|^7.0|^8.0",
+                "symfony/http-client-contracts": "^2.5|^3",
+                "symfony/process": "^6.4|^7.0|^8.0",
+                "symfony/property-access": "^7.1|^8.0",
+                "symfony/routing": "^6.4|^7.0|^8.0",
+                "symfony/serializer": "^7.1|^8.0",
+                "symfony/stopwatch": "^6.4|^7.0|^8.0",
+                "symfony/translation": "^6.4|^7.0|^8.0",
+                "symfony/translation-contracts": "^2.5|^3",
+                "symfony/uid": "^6.4|^7.0|^8.0",
+                "symfony/validator": "^6.4|^7.0|^8.0",
+                "symfony/var-dumper": "^6.4|^7.0|^8.0",
+                "symfony/var-exporter": "^6.4|^7.0|^8.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.4.5"
+            },
+            "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": "2026-01-28T10:33:42+00:00"
+        },
+        {
+            "name": "symfony/mailer",
+            "version": "v7.4.4",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/mailer.git",
+                "reference": "7b750074c40c694ceb34cb926d6dffee231c5cd6"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/mailer/zipball/7b750074c40c694ceb34cb926d6dffee231c5cd6",
+                "reference": "7b750074c40c694ceb34cb926d6dffee231c5cd6",
+                "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|^8.0",
+                "symfony/mime": "^7.2|^8.0",
+                "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|^8.0",
+                "symfony/http-client": "^6.4|^7.0|^8.0",
+                "symfony/messenger": "^6.4|^7.0|^8.0",
+                "symfony/twig-bridge": "^6.4|^7.0|^8.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.4.4"
+            },
+            "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": "2026-01-08T08:25:11+00:00"
+        },
+        {
+            "name": "symfony/mime",
+            "version": "v7.4.5",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/mime.git",
+                "reference": "b18c7e6e9eee1e19958138df10412f3c4c316148"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/mime/zipball/b18c7e6e9eee1e19958138df10412f3c4c316148",
+                "reference": "b18c7e6e9eee1e19958138df10412f3c4c316148",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=8.2",
+                "symfony/deprecation-contracts": "^2.5|^3",
+                "symfony/polyfill-intl-idn": "^1.10",
+                "symfony/polyfill-mbstring": "^1.0"
+            },
+            "conflict": {
+                "egulias/email-validator": "~3.0.0",
+                "phpdocumentor/reflection-docblock": "<5.2|>=6",
+                "phpdocumentor/type-resolver": "<1.5.1",
+                "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": "^5.2",
+                "symfony/dependency-injection": "^6.4|^7.0|^8.0",
+                "symfony/process": "^6.4|^7.0|^8.0",
+                "symfony/property-access": "^6.4|^7.0|^8.0",
+                "symfony/property-info": "^6.4|^7.0|^8.0",
+                "symfony/serializer": "^6.4.3|^7.0.3|^8.0"
+            },
+            "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.4.5"
+            },
+            "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": "2026-01-27T08:59:58+00:00"
+        },
+        {
+            "name": "symfony/polyfill-ctype",
+            "version": "v1.33.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.33.0"
+            },
+            "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": "2024-09-09T11:45:10+00:00"
+        },
+        {
+            "name": "symfony/polyfill-intl-grapheme",
+            "version": "v1.33.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/polyfill-intl-grapheme.git",
+                "reference": "380872130d3a5dd3ace2f4010d95125fde5d5c70"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/380872130d3a5dd3ace2f4010d95125fde5d5c70",
+                "reference": "380872130d3a5dd3ace2f4010d95125fde5d5c70",
+                "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.33.0"
+            },
+            "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-06-27T09:58:17+00:00"
+        },
+        {
+            "name": "symfony/polyfill-intl-idn",
+            "version": "v1.33.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.33.0"
+            },
+            "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": "2024-09-10T14:38:51+00:00"
+        },
+        {
+            "name": "symfony/polyfill-intl-normalizer",
+            "version": "v1.33.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.33.0"
+            },
+            "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": "2024-09-09T11:45:10+00:00"
+        },
+        {
+            "name": "symfony/polyfill-mbstring",
+            "version": "v1.33.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.33.0"
+            },
+            "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": "2024-12-23T08:48:59+00:00"
+        },
+        {
+            "name": "symfony/polyfill-php80",
+            "version": "v1.33.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.33.0"
+            },
+            "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-01-02T08:10:11+00:00"
+        },
+        {
+            "name": "symfony/polyfill-php83",
+            "version": "v1.33.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/polyfill-php83.git",
+                "reference": "17f6f9a6b1735c0f163024d959f700cfbc5155e5"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/17f6f9a6b1735c0f163024d959f700cfbc5155e5",
+                "reference": "17f6f9a6b1735c0f163024d959f700cfbc5155e5",
+                "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.33.0"
+            },
+            "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-08T02:45:35+00:00"
+        },
+        {
+            "name": "symfony/polyfill-php84",
+            "version": "v1.33.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/polyfill-php84.git",
+                "reference": "d8ced4d875142b6a7426000426b8abc631d6b191"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/polyfill-php84/zipball/d8ced4d875142b6a7426000426b8abc631d6b191",
+                "reference": "d8ced4d875142b6a7426000426b8abc631d6b191",
+                "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\\Php84\\": ""
+                },
+                "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.4+ features to lower PHP versions",
+            "homepage": "https://symfony.com",
+            "keywords": [
+                "compatibility",
+                "polyfill",
+                "portable",
+                "shim"
+            ],
+            "support": {
+                "source": "https://github.com/symfony/polyfill-php84/tree/v1.33.0"
+            },
+            "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-06-24T13:30:11+00:00"
+        },
+        {
+            "name": "symfony/polyfill-php85",
+            "version": "v1.33.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/polyfill-php85.git",
+                "reference": "d4e5fcd4ab3d998ab16c0db48e6cbb9a01993f91"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/polyfill-php85/zipball/d4e5fcd4ab3d998ab16c0db48e6cbb9a01993f91",
+                "reference": "d4e5fcd4ab3d998ab16c0db48e6cbb9a01993f91",
+                "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\\Php85\\": ""
+                },
+                "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.5+ features to lower PHP versions",
+            "homepage": "https://symfony.com",
+            "keywords": [
+                "compatibility",
+                "polyfill",
+                "portable",
+                "shim"
+            ],
+            "support": {
+                "source": "https://github.com/symfony/polyfill-php85/tree/v1.33.0"
+            },
+            "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-06-23T16:12:55+00:00"
+        },
+        {
+            "name": "symfony/polyfill-uuid",
+            "version": "v1.33.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.33.0"
+            },
+            "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": "2024-09-09T11:45:10+00:00"
+        },
+        {
+            "name": "symfony/process",
+            "version": "v7.4.5",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/process.git",
+                "reference": "608476f4604102976d687c483ac63a79ba18cc97"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/process/zipball/608476f4604102976d687c483ac63a79ba18cc97",
+                "reference": "608476f4604102976d687c483ac63a79ba18cc97",
+                "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.4.5"
+            },
+            "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": "2026-01-26T15:07:59+00:00"
+        },
+        {
+            "name": "symfony/routing",
+            "version": "v7.4.4",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/routing.git",
+                "reference": "0798827fe2c79caeed41d70b680c2c3507d10147"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/routing/zipball/0798827fe2c79caeed41d70b680c2c3507d10147",
+                "reference": "0798827fe2c79caeed41d70b680c2c3507d10147",
+                "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|^8.0",
+                "symfony/dependency-injection": "^6.4|^7.0|^8.0",
+                "symfony/expression-language": "^6.4|^7.0|^8.0",
+                "symfony/http-foundation": "^6.4|^7.0|^8.0",
+                "symfony/yaml": "^6.4|^7.0|^8.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.4.4"
+            },
+            "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": "2026-01-12T12:19:02+00:00"
+        },
+        {
+            "name": "symfony/service-contracts",
+            "version": "v3.6.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/service-contracts.git",
+                "reference": "45112560a3ba2d715666a509a0bc9521d10b6c43"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/service-contracts/zipball/45112560a3ba2d715666a509a0bc9521d10b6c43",
+                "reference": "45112560a3ba2d715666a509a0bc9521d10b6c43",
+                "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.1"
+            },
+            "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:30:57+00:00"
+        },
+        {
+            "name": "symfony/string",
+            "version": "v8.0.4",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/string.git",
+                "reference": "758b372d6882506821ed666032e43020c4f57194"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/string/zipball/758b372d6882506821ed666032e43020c4f57194",
+                "reference": "758b372d6882506821ed666032e43020c4f57194",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=8.4",
+                "symfony/polyfill-ctype": "^1.8",
+                "symfony/polyfill-intl-grapheme": "^1.33",
+                "symfony/polyfill-intl-normalizer": "^1.0",
+                "symfony/polyfill-mbstring": "^1.0"
+            },
+            "conflict": {
+                "symfony/translation-contracts": "<2.5"
+            },
+            "require-dev": {
+                "symfony/emoji": "^7.4|^8.0",
+                "symfony/http-client": "^7.4|^8.0",
+                "symfony/intl": "^7.4|^8.0",
+                "symfony/translation-contracts": "^2.5|^3.0",
+                "symfony/var-exporter": "^7.4|^8.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/v8.0.4"
+            },
+            "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": "2026-01-12T12:37:40+00:00"
+        },
+        {
+            "name": "symfony/translation",
+            "version": "v8.0.4",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/translation.git",
+                "reference": "db70c8ce7db74fd2da7b1d268db46b2a8ce32c10"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/translation/zipball/db70c8ce7db74fd2da7b1d268db46b2a8ce32c10",
+                "reference": "db70c8ce7db74fd2da7b1d268db46b2a8ce32c10",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=8.4",
+                "symfony/polyfill-mbstring": "^1.0",
+                "symfony/translation-contracts": "^3.6.1"
+            },
+            "conflict": {
+                "nikic/php-parser": "<5.0",
+                "symfony/http-client-contracts": "<2.5",
+                "symfony/service-contracts": "<2.5"
+            },
+            "provide": {
+                "symfony/translation-implementation": "2.3|3.0"
+            },
+            "require-dev": {
+                "nikic/php-parser": "^5.0",
+                "psr/log": "^1|^2|^3",
+                "symfony/config": "^7.4|^8.0",
+                "symfony/console": "^7.4|^8.0",
+                "symfony/dependency-injection": "^7.4|^8.0",
+                "symfony/finder": "^7.4|^8.0",
+                "symfony/http-client-contracts": "^2.5|^3.0",
+                "symfony/http-kernel": "^7.4|^8.0",
+                "symfony/intl": "^7.4|^8.0",
+                "symfony/polyfill-intl-icu": "^1.21",
+                "symfony/routing": "^7.4|^8.0",
+                "symfony/service-contracts": "^2.5|^3",
+                "symfony/yaml": "^7.4|^8.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/v8.0.4"
+            },
+            "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": "2026-01-13T13:06:50+00:00"
+        },
+        {
+            "name": "symfony/translation-contracts",
+            "version": "v3.6.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/translation-contracts.git",
+                "reference": "65a8bc82080447fae78373aa10f8d13b38338977"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/65a8bc82080447fae78373aa10f8d13b38338977",
+                "reference": "65a8bc82080447fae78373aa10f8d13b38338977",
+                "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.1"
+            },
+            "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/uid",
+            "version": "v7.4.4",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/uid.git",
+                "reference": "7719ce8aba76be93dfe249192f1fbfa52c588e36"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/uid/zipball/7719ce8aba76be93dfe249192f1fbfa52c588e36",
+                "reference": "7719ce8aba76be93dfe249192f1fbfa52c588e36",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=8.2",
+                "symfony/polyfill-uuid": "^1.15"
+            },
+            "require-dev": {
+                "symfony/console": "^6.4|^7.0|^8.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.4.4"
+            },
+            "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": "2026-01-03T23:30:35+00:00"
+        },
+        {
+            "name": "symfony/var-dumper",
+            "version": "v7.4.4",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/var-dumper.git",
+                "reference": "0e4769b46a0c3c62390d124635ce59f66874b282"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/var-dumper/zipball/0e4769b46a0c3c62390d124635ce59f66874b282",
+                "reference": "0e4769b46a0c3c62390d124635ce59f66874b282",
+                "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|^8.0",
+                "symfony/http-kernel": "^6.4|^7.0|^8.0",
+                "symfony/process": "^6.4|^7.0|^8.0",
+                "symfony/uid": "^6.4|^7.0|^8.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.4.4"
+            },
+            "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": "2026-01-01T22:13:48+00:00"
+        },
+        {
+            "name": "symfony/yaml",
+            "version": "v7.4.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/yaml.git",
+                "reference": "24dd4de28d2e3988b311751ac49e684d783e2345"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/yaml/zipball/24dd4de28d2e3988b311751ac49e684d783e2345",
+                "reference": "24dd4de28d2e3988b311751ac49e684d783e2345",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=8.2",
+                "symfony/deprecation-contracts": "^2.5|^3",
+                "symfony/polyfill-ctype": "^1.8"
+            },
+            "conflict": {
+                "symfony/console": "<6.4"
+            },
+            "require-dev": {
+                "symfony/console": "^6.4|^7.0|^8.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.4.1"
+            },
+            "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-12-04T18:11:45+00:00"
+        },
+        {
+            "name": "tijsverkoyen/css-to-inline-styles",
+            "version": "v2.4.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/tijsverkoyen/CssToInlineStyles.git",
+                "reference": "f0292ccf0ec75843d65027214426b6b163b48b41"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/tijsverkoyen/CssToInlineStyles/zipball/f0292ccf0ec75843d65027214426b6b163b48b41",
+                "reference": "f0292ccf0ec75843d65027214426b6b163b48b41",
+                "shasum": ""
+            },
+            "require": {
+                "ext-dom": "*",
+                "ext-libxml": "*",
+                "php": "^7.4 || ^8.0",
+                "symfony/css-selector": "^5.4 || ^6.0 || ^7.0 || ^8.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.4.0"
+            },
+            "time": "2025-12-02T11:56:42+00:00"
+        },
+        {
+            "name": "vlucas/phpdotenv",
+            "version": "v5.6.3",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/vlucas/phpdotenv.git",
+                "reference": "955e7815d677a3eaa7075231212f2110983adecc"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/955e7815d677a3eaa7075231212f2110983adecc",
+                "reference": "955e7815d677a3eaa7075231212f2110983adecc",
+                "shasum": ""
+            },
+            "require": {
+                "ext-pcre": "*",
+                "graham-campbell/result-type": "^1.1.4",
+                "php": "^7.2.5 || ^8.0",
+                "phpoption/phpoption": "^1.9.5",
+                "symfony/polyfill-ctype": "^1.26",
+                "symfony/polyfill-mbstring": "^1.26",
+                "symfony/polyfill-php80": "^1.26"
+            },
+            "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.3"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/GrahamCampbell",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/vlucas/phpdotenv",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2025-12-27T19:49:13+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.12.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/webmozarts/assert.git",
+                "reference": "9be6926d8b485f55b9229203f962b51ed377ba68"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/webmozarts/assert/zipball/9be6926d8b485f55b9229203f962b51ed377ba68",
+                "reference": "9be6926d8b485f55b9229203f962b51ed377ba68",
+                "shasum": ""
+            },
+            "require": {
+                "ext-ctype": "*",
+                "ext-date": "*",
+                "ext-filter": "*",
+                "php": "^7.2 || ^8.0"
+            },
+            "suggest": {
+                "ext-intl": "",
+                "ext-simplexml": "",
+                "ext-spl": ""
+            },
+            "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.12.1"
+            },
+            "time": "2025-10-29T15:56:20+00:00"
+        }
+    ],
+    "packages-dev": [
+        {
+            "name": "brianium/paratest",
+            "version": "v7.16.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/paratestphp/paratest.git",
+                "reference": "f0fdfd8e654e0d38bc2ba756a6cabe7be287390b"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/paratestphp/paratest/zipball/f0fdfd8e654e0d38bc2ba756a6cabe7be287390b",
+                "reference": "f0fdfd8e654e0d38bc2ba756a6cabe7be287390b",
+                "shasum": ""
+            },
+            "require": {
+                "ext-dom": "*",
+                "ext-pcre": "*",
+                "ext-reflection": "*",
+                "ext-simplexml": "*",
+                "fidry/cpu-core-counter": "^1.3.0",
+                "jean85/pretty-package-versions": "^2.1.1",
+                "php": "~8.3.0 || ~8.4.0 || ~8.5.0",
+                "phpunit/php-code-coverage": "^12.5.2",
+                "phpunit/php-file-iterator": "^6",
+                "phpunit/php-timer": "^8",
+                "phpunit/phpunit": "^12.5.4",
+                "sebastian/environment": "^8.0.3",
+                "symfony/console": "^7.3.4 || ^8.0.0",
+                "symfony/process": "^7.3.4 || ^8.0.0"
+            },
+            "require-dev": {
+                "doctrine/coding-standard": "^14.0.0",
+                "ext-pcntl": "*",
+                "ext-pcov": "*",
+                "ext-posix": "*",
+                "phpstan/phpstan": "^2.1.33",
+                "phpstan/phpstan-deprecation-rules": "^2.0.3",
+                "phpstan/phpstan-phpunit": "^2.0.11",
+                "phpstan/phpstan-strict-rules": "^2.0.7",
+                "symfony/filesystem": "^7.3.2 || ^8.0.0"
+            },
+            "bin": [
+                "bin/paratest",
+                "bin/paratest_for_phpstorm"
+            ],
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "ParaTest\\": [
+                        "src/"
+                    ]
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Brian Scaturro",
+                    "email": "scaturrob@gmail.com",
+                    "role": "Developer"
+                },
+                {
+                    "name": "Filippo Tessarotto",
+                    "email": "zoeslam@gmail.com",
+                    "role": "Developer"
+                }
+            ],
+            "description": "Parallel testing for PHP",
+            "homepage": "https://github.com/paratestphp/paratest",
+            "keywords": [
+                "concurrent",
+                "parallel",
+                "phpunit",
+                "testing"
+            ],
+            "support": {
+                "issues": "https://github.com/paratestphp/paratest/issues",
+                "source": "https://github.com/paratestphp/paratest/tree/v7.16.1"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/sponsors/Slamdunk",
+                    "type": "github"
+                },
+                {
+                    "url": "https://paypal.me/filippotessarotto",
+                    "type": "paypal"
+                }
+            ],
+            "time": "2026-01-08T07:23:06+00:00"
+        },
+        {
+            "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": "fidry/cpu-core-counter",
+            "version": "1.3.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/theofidry/cpu-core-counter.git",
+                "reference": "db9508f7b1474469d9d3c53b86f817e344732678"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/db9508f7b1474469d9d3c53b86f817e344732678",
+                "reference": "db9508f7b1474469d9d3c53b86f817e344732678",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.2 || ^8.0"
+            },
+            "require-dev": {
+                "fidry/makefile": "^0.2.0",
+                "fidry/php-cs-fixer-config": "^1.1.2",
+                "phpstan/extension-installer": "^1.2.0",
+                "phpstan/phpstan": "^2.0",
+                "phpstan/phpstan-deprecation-rules": "^2.0.0",
+                "phpstan/phpstan-phpunit": "^2.0",
+                "phpstan/phpstan-strict-rules": "^2.0",
+                "phpunit/phpunit": "^8.5.31 || ^9.5.26",
+                "webmozarts/strict-phpunit": "^7.5"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Fidry\\CpuCoreCounter\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Théo FIDRY",
+                    "email": "theo.fidry@gmail.com"
+                }
+            ],
+            "description": "Tiny utility to get the number of CPU cores.",
+            "keywords": [
+                "CPU",
+                "core"
+            ],
+            "support": {
+                "issues": "https://github.com/theofidry/cpu-core-counter/issues",
+                "source": "https://github.com/theofidry/cpu-core-counter/tree/1.3.0"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/theofidry",
+                    "type": "github"
+                }
+            ],
+            "time": "2025-08-14T07:29:31+00:00"
+        },
+        {
+            "name": "filp/whoops",
+            "version": "2.18.4",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/filp/whoops.git",
+                "reference": "d2102955e48b9fd9ab24280a7ad12ed552752c4d"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/filp/whoops/zipball/d2102955e48b9fd9ab24280a7ad12ed552752c4d",
+                "reference": "d2102955e48b9fd9ab24280a7ad12ed552752c4d",
+                "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.4"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/denis-sokolov",
+                    "type": "github"
+                }
+            ],
+            "time": "2025-08-08T12:00:00+00:00"
+        },
+        {
+            "name": "fruitcake/laravel-debugbar",
+            "version": "v4.0.6",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/fruitcake/laravel-debugbar.git",
+                "reference": "0cbf2986de59f66870cee565491b81eb89f8d25e"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/fruitcake/laravel-debugbar/zipball/0cbf2986de59f66870cee565491b81eb89f8d25e",
+                "reference": "0cbf2986de59f66870cee565491b81eb89f8d25e",
+                "shasum": ""
+            },
+            "require": {
+                "illuminate/routing": "^11|^12",
+                "illuminate/session": "^11|^12",
+                "illuminate/support": "^11|^12",
+                "php": "^8.2",
+                "php-debugbar/php-debugbar": "^3.1",
+                "php-debugbar/symfony-bridge": "^1.1"
+            },
+            "replace": {
+                "barryvdh/laravel-debugbar": "self.version"
+            },
+            "require-dev": {
+                "larastan/larastan": "^3",
+                "laravel/octane": "^2",
+                "laravel/pennant": "^1",
+                "laravel/pint": "^1",
+                "laravel/telescope": "^5.16",
+                "livewire/livewire": "^3.7|^4",
+                "mockery/mockery": "^1.3.3",
+                "orchestra/testbench-dusk": "^9|^10",
+                "php-debugbar/twig-bridge": "^2.0",
+                "phpstan/phpstan-phpunit": "^2",
+                "phpstan/phpstan-strict-rules": "^2.0",
+                "phpunit/phpunit": "^11",
+                "shipmonk/phpstan-rules": "^4.3"
+            },
+            "type": "library",
+            "extra": {
+                "laravel": {
+                    "aliases": {
+                        "Debugbar": "Fruitcake\\LaravelDebugbar\\Facades\\Debugbar"
+                    },
+                    "providers": [
+                        "Fruitcake\\LaravelDebugbar\\ServiceProvider"
+                    ]
+                },
+                "branch-alias": {
+                    "dev-master": "4.0-dev"
+                }
+            },
+            "autoload": {
+                "files": [
+                    "src/helpers.php"
+                ],
+                "psr-4": {
+                    "Fruitcake\\LaravelDebugbar\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Fruitcake",
+                    "homepage": "https://fruitcake.nl"
+                },
+                {
+                    "name": "Barry vd. Heuvel",
+                    "email": "barryvdh@gmail.com"
+                }
+            ],
+            "description": "PHP Debugbar integration for Laravel",
+            "keywords": [
+                "barryvdh",
+                "debug",
+                "debugbar",
+                "dev",
+                "laravel",
+                "profiler",
+                "webprofiler"
+            ],
+            "support": {
+                "issues": "https://github.com/fruitcake/laravel-debugbar/issues",
+                "source": "https://github.com/fruitcake/laravel-debugbar/tree/v4.0.6"
+            },
+            "funding": [
+                {
+                    "url": "https://fruitcake.nl",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/barryvdh",
+                    "type": "github"
+                }
+            ],
+            "time": "2026-02-04T11:48:53+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": "jean85/pretty-package-versions",
+            "version": "2.1.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/Jean85/pretty-package-versions.git",
+                "reference": "4d7aa5dab42e2a76d99559706022885de0e18e1a"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/Jean85/pretty-package-versions/zipball/4d7aa5dab42e2a76d99559706022885de0e18e1a",
+                "reference": "4d7aa5dab42e2a76d99559706022885de0e18e1a",
+                "shasum": ""
+            },
+            "require": {
+                "composer-runtime-api": "^2.1.0",
+                "php": "^7.4|^8.0"
+            },
+            "require-dev": {
+                "friendsofphp/php-cs-fixer": "^3.2",
+                "jean85/composer-provided-replaced-stub-package": "^1.0",
+                "phpstan/phpstan": "^2.0",
+                "phpunit/phpunit": "^7.5|^8.5|^9.6",
+                "rector/rector": "^2.0",
+                "vimeo/psalm": "^4.3 || ^5.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Jean85\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Alessandro Lai",
+                    "email": "alessandro.lai85@gmail.com"
+                }
+            ],
+            "description": "A library to get pretty versions strings of installed dependencies",
+            "keywords": [
+                "composer",
+                "package",
+                "release",
+                "versions"
+            ],
+            "support": {
+                "issues": "https://github.com/Jean85/pretty-package-versions/issues",
+                "source": "https://github.com/Jean85/pretty-package-versions/tree/2.1.1"
+            },
+            "time": "2025-03-19T14:43:43+00:00"
+        },
+        {
+            "name": "laradumps/laradumps",
+            "version": "v5.0.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/laradumps/laradumps.git",
+                "reference": "e7b3119b50124942cb1062fcbbd0036a27312d6e"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/laradumps/laradumps/zipball/e7b3119b50124942cb1062fcbbd0036a27312d6e",
+                "reference": "e7b3119b50124942cb1062fcbbd0036a27312d6e",
+                "shasum": ""
+            },
+            "require": {
+                "illuminate/mail": "^11.0|^12.0",
+                "illuminate/support": "^11.0|^12.0",
+                "laradumps/laradumps-core": "^4.0.1",
+                "php": "^8.2"
+            },
+            "require-dev": {
+                "larastan/larastan": "^3.8",
+                "laravel/framework": "^11.0|^12.0",
+                "laravel/pint": "^1.26.0",
+                "livewire/livewire": "^3.7.1|^4.0",
+                "mockery/mockery": "^1.6.12",
+                "orchestra/testbench-core": "^9.4|^10.0",
+                "pestphp/pest": "^3.7.0|^4.0.0",
+                "symfony/var-dumper": "^7.1.3|^8.0"
+            },
+            "type": "library",
+            "extra": {
+                "laravel": {
+                    "providers": [
+                        "LaraDumps\\LaraDumps\\LaraDumpsServiceProvider"
+                    ]
+                }
+            },
+            "autoload": {
+                "files": [
+                    "src/functions.php"
+                ],
+                "psr-4": {
+                    "LaraDumps\\LaraDumps\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Luan Freitas",
+                    "email": "luanfreitas10@protonmail.com",
+                    "role": "Developer"
+                }
+            ],
+            "description": "LaraDumps is a friendly app designed to boost your Laravel PHP coding and debugging experience.",
+            "homepage": "https://github.com/laradumps/laradumps",
+            "support": {
+                "issues": "https://github.com/laradumps/laradumps/issues",
+                "source": "https://github.com/laradumps/laradumps/tree/v5.0.1"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/luanfreitasdev",
+                    "type": "github"
+                }
+            ],
+            "time": "2026-01-15T18:01:57+00:00"
+        },
+        {
+            "name": "laradumps/laradumps-core",
+            "version": "v4.0.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/laradumps/laradumps-core.git",
+                "reference": "162ceebac8e7253332270421b74a12a94a6f28b8"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/laradumps/laradumps-core/zipball/162ceebac8e7253332270421b74a12a94a6f28b8",
+                "reference": "162ceebac8e7253332270421b74a12a94a6f28b8",
+                "shasum": ""
+            },
+            "require": {
+                "ext-curl": "*",
+                "php": "^8.2",
+                "ramsey/uuid": "^4.9.1",
+                "spatie/backtrace": "^1.5",
+                "symfony/console": "^6.4|^7.0|^8.0",
+                "symfony/finder": "^6.4|^7.0|^8.0",
+                "symfony/process": "^6.4|^7.0|^8.0",
+                "symfony/var-dumper": "^6.4|^7.0|^8.0",
+                "symfony/yaml": "^6.4|^7.0|^8.0"
+            },
+            "require-dev": {
+                "illuminate/support": "^12",
+                "laravel/pint": "^1.26.0",
+                "pestphp/pest": "^3.0|^4.0",
+                "phpstan/phpstan": "^1.10.50"
+            },
+            "suggest": {
+                "nunomaduro/termwind": "For a better terminal experience"
+            },
+            "bin": [
+                "bin/laradumps"
+            ],
+            "type": "library",
+            "autoload": {
+                "files": [
+                    "src/functions.php"
+                ],
+                "psr-4": {
+                    "LaraDumps\\LaraDumpsCore\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Luan Freitas",
+                    "email": "luanfreitas10@protonmail.com",
+                    "role": "Developer"
+                }
+            ],
+            "description": "LaraDumps is a friendly app designed to boost your Laravel / PHP coding and debugging experience.",
+            "homepage": "https://github.com/laradumps/laradumps-core",
+            "support": {
+                "issues": "https://github.com/laradumps/laradumps-core/issues",
+                "source": "https://github.com/laradumps/laradumps-core/tree/v4.0.1"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/luanfreitasdev",
+                    "type": "github"
+                }
+            ],
+            "time": "2026-01-15T17:33:27+00:00"
+        },
+        {
+            "name": "laravel/boost",
+            "version": "v2.0.4",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/laravel/boost.git",
+                "reference": "6f7a9f70c1b2cc5fcef1585e8aa04b8546f150e9"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/laravel/boost/zipball/6f7a9f70c1b2cc5fcef1585e8aa04b8546f150e9",
+                "reference": "6f7a9f70c1b2cc5fcef1585e8aa04b8546f150e9",
+                "shasum": ""
+            },
+            "require": {
+                "guzzlehttp/guzzle": "^7.9",
+                "illuminate/console": "^11.45.3|^12.41.1",
+                "illuminate/contracts": "^11.45.3|^12.41.1",
+                "illuminate/routing": "^11.45.3|^12.41.1",
+                "illuminate/support": "^11.45.3|^12.41.1",
+                "laravel/mcp": "^0.5.1",
+                "laravel/prompts": "^0.3.10",
+                "laravel/roster": "^0.2.9",
+                "php": "^8.2"
+            },
+            "require-dev": {
+                "laravel/pint": "^1.27.0",
+                "mockery/mockery": "^1.6.12",
+                "orchestra/testbench": "^9.15.0|^10.6",
+                "pestphp/pest": "^2.36.0|^3.8.4|^4.1.5",
+                "phpstan/phpstan": "^2.1.27",
+                "rector/rector": "^2.1"
+            },
+            "type": "library",
+            "extra": {
+                "laravel": {
+                    "providers": [
+                        "Laravel\\Boost\\BoostServiceProvider"
+                    ]
+                },
+                "branch-alias": {
+                    "dev-master": "1.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Laravel\\Boost\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "description": "Laravel Boost accelerates AI-assisted development by providing the essential context and structure that AI needs to generate high-quality, Laravel-specific code.",
+            "homepage": "https://github.com/laravel/boost",
+            "keywords": [
+                "ai",
+                "dev",
+                "laravel"
+            ],
+            "support": {
+                "issues": "https://github.com/laravel/boost/issues",
+                "source": "https://github.com/laravel/boost"
+            },
+            "time": "2026-01-28T13:53:50+00:00"
+        },
+        {
+            "name": "laravel/mcp",
+            "version": "v0.5.3",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/laravel/mcp.git",
+                "reference": "39b9791b989927642137dd5b55dde0529f1614f9"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/laravel/mcp/zipball/39b9791b989927642137dd5b55dde0529f1614f9",
+                "reference": "39b9791b989927642137dd5b55dde0529f1614f9",
+                "shasum": ""
+            },
+            "require": {
+                "ext-json": "*",
+                "ext-mbstring": "*",
+                "illuminate/console": "^10.49.0|^11.45.3|^12.41.1",
+                "illuminate/container": "^10.49.0|^11.45.3|^12.41.1",
+                "illuminate/contracts": "^10.49.0|^11.45.3|^12.41.1",
+                "illuminate/http": "^10.49.0|^11.45.3|^12.41.1",
+                "illuminate/json-schema": "^12.41.1",
+                "illuminate/routing": "^10.49.0|^11.45.3|^12.41.1",
+                "illuminate/support": "^10.49.0|^11.45.3|^12.41.1",
+                "illuminate/validation": "^10.49.0|^11.45.3|^12.41.1",
+                "php": "^8.1"
+            },
+            "require-dev": {
+                "laravel/pint": "^1.20",
+                "orchestra/testbench": "^8.36|^9.15|^10.8",
+                "pestphp/pest": "^2.36.0|^3.8.4|^4.1.0",
+                "phpstan/phpstan": "^2.1.27",
+                "rector/rector": "^2.2.4"
+            },
+            "type": "library",
+            "extra": {
+                "laravel": {
+                    "aliases": {
+                        "Mcp": "Laravel\\Mcp\\Server\\Facades\\Mcp"
+                    },
+                    "providers": [
+                        "Laravel\\Mcp\\Server\\McpServiceProvider"
+                    ]
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Laravel\\Mcp\\": "src/",
+                    "Laravel\\Mcp\\Server\\": "src/Server/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Taylor Otwell",
+                    "email": "taylor@laravel.com"
+                }
+            ],
+            "description": "Rapidly build MCP servers for your Laravel applications.",
+            "homepage": "https://github.com/laravel/mcp",
+            "keywords": [
+                "laravel",
+                "mcp"
+            ],
+            "support": {
+                "issues": "https://github.com/laravel/mcp/issues",
+                "source": "https://github.com/laravel/mcp"
+            },
+            "time": "2026-01-26T10:25:21+00:00"
+        },
+        {
+            "name": "laravel/pint",
+            "version": "v1.27.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/laravel/pint.git",
+                "reference": "c67b4195b75491e4dfc6b00b1c78b68d86f54c90"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/laravel/pint/zipball/c67b4195b75491e4dfc6b00b1c78b68d86f54c90",
+                "reference": "c67b4195b75491e4dfc6b00b1c78b68d86f54c90",
+                "shasum": ""
+            },
+            "require": {
+                "ext-json": "*",
+                "ext-mbstring": "*",
+                "ext-tokenizer": "*",
+                "ext-xml": "*",
+                "php": "^8.2.0"
+            },
+            "require-dev": {
+                "friendsofphp/php-cs-fixer": "^3.92.4",
+                "illuminate/view": "^12.44.0",
+                "larastan/larastan": "^3.8.1",
+                "laravel-zero/framework": "^12.0.4",
+                "mockery/mockery": "^1.6.12",
+                "nunomaduro/termwind": "^2.3.3",
+                "pestphp/pest": "^3.8.4"
+            },
+            "bin": [
+                "builds/pint"
+            ],
+            "type": "project",
+            "autoload": {
+                "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": [
+                "dev",
+                "format",
+                "formatter",
+                "lint",
+                "linter",
+                "php"
+            ],
+            "support": {
+                "issues": "https://github.com/laravel/pint/issues",
+                "source": "https://github.com/laravel/pint"
+            },
+            "time": "2026-01-05T16:49:17+00:00"
+        },
+        {
+            "name": "laravel/roster",
+            "version": "v0.2.9",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/laravel/roster.git",
+                "reference": "82bbd0e2de614906811aebdf16b4305956816fa6"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/laravel/roster/zipball/82bbd0e2de614906811aebdf16b4305956816fa6",
+                "reference": "82bbd0e2de614906811aebdf16b4305956816fa6",
+                "shasum": ""
+            },
+            "require": {
+                "illuminate/console": "^10.0|^11.0|^12.0",
+                "illuminate/contracts": "^10.0|^11.0|^12.0",
+                "illuminate/routing": "^10.0|^11.0|^12.0",
+                "illuminate/support": "^10.0|^11.0|^12.0",
+                "php": "^8.1|^8.2",
+                "symfony/yaml": "^6.4|^7.2"
+            },
+            "require-dev": {
+                "laravel/pint": "^1.14",
+                "mockery/mockery": "^1.6",
+                "orchestra/testbench": "^8.22.0|^9.0|^10.0",
+                "pestphp/pest": "^2.0|^3.0",
+                "phpstan/phpstan": "^2.0"
+            },
+            "type": "library",
+            "extra": {
+                "laravel": {
+                    "providers": [
+                        "Laravel\\Roster\\RosterServiceProvider"
+                    ]
+                },
+                "branch-alias": {
+                    "dev-master": "1.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Laravel\\Roster\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "description": "Detect packages & approaches in use within a Laravel project",
+            "homepage": "https://github.com/laravel/roster",
+            "keywords": [
+                "dev",
+                "laravel"
+            ],
+            "support": {
+                "issues": "https://github.com/laravel/roster/issues",
+                "source": "https://github.com/laravel/roster"
+            },
+            "time": "2025-10-20T09:56:46+00:00"
+        },
+        {
+            "name": "laravel/sail",
+            "version": "v1.52.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/laravel/sail.git",
+                "reference": "64ac7d8abb2dbcf2b76e61289451bae79066b0b3"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/laravel/sail/zipball/64ac7d8abb2dbcf2b76e61289451bae79066b0b3",
+                "reference": "64ac7d8abb2dbcf2b76e61289451bae79066b0b3",
+                "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": "^2.0"
+            },
+            "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": "2026-01-01T02:46:03+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.3",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/nunomaduro/collision.git",
+                "reference": "1dc9e88d105699d0fee8bb18890f41b274f6b4c4"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/nunomaduro/collision/zipball/1dc9e88d105699d0fee8bb18890f41b274f6b4c4",
+                "reference": "1dc9e88d105699d0fee8bb18890f41b274f6b4c4",
+                "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 || ^4.0.0",
+                "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-11-20T02:55:25+00:00"
+        },
+        {
+            "name": "pestphp/pest",
+            "version": "v4.3.2",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/pestphp/pest.git",
+                "reference": "3a4329ddc7a2b67c19fca8342a668b39be3ae398"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/pestphp/pest/zipball/3a4329ddc7a2b67c19fca8342a668b39be3ae398",
+                "reference": "3a4329ddc7a2b67c19fca8342a668b39be3ae398",
+                "shasum": ""
+            },
+            "require": {
+                "brianium/paratest": "^7.16.1",
+                "nunomaduro/collision": "^8.8.3",
+                "nunomaduro/termwind": "^2.3.3",
+                "pestphp/pest-plugin": "^4.0.0",
+                "pestphp/pest-plugin-arch": "^4.0.0",
+                "pestphp/pest-plugin-mutate": "^4.0.1",
+                "pestphp/pest-plugin-profanity": "^4.2.1",
+                "php": "^8.3.0",
+                "phpunit/phpunit": "^12.5.8",
+                "symfony/process": "^7.4.4|^8.0.0"
+            },
+            "conflict": {
+                "filp/whoops": "<2.18.3",
+                "phpunit/phpunit": ">12.5.8",
+                "sebastian/exporter": "<7.0.0",
+                "webmozart/assert": "<1.11.0"
+            },
+            "require-dev": {
+                "pestphp/pest-dev-tools": "^4.0.0",
+                "pestphp/pest-plugin-browser": "^4.2.1",
+                "pestphp/pest-plugin-type-coverage": "^4.0.3",
+                "psy/psysh": "^0.12.18"
+            },
+            "bin": [
+                "bin/pest"
+            ],
+            "type": "library",
+            "extra": {
+                "pest": {
+                    "plugins": [
+                        "Pest\\Mutate\\Plugins\\Mutate",
+                        "Pest\\Plugins\\Configuration",
+                        "Pest\\Plugins\\Bail",
+                        "Pest\\Plugins\\Cache",
+                        "Pest\\Plugins\\Coverage",
+                        "Pest\\Plugins\\Init",
+                        "Pest\\Plugins\\Environment",
+                        "Pest\\Plugins\\Help",
+                        "Pest\\Plugins\\Memory",
+                        "Pest\\Plugins\\Only",
+                        "Pest\\Plugins\\Printer",
+                        "Pest\\Plugins\\ProcessIsolation",
+                        "Pest\\Plugins\\Profile",
+                        "Pest\\Plugins\\Retry",
+                        "Pest\\Plugins\\Snapshot",
+                        "Pest\\Plugins\\Verbose",
+                        "Pest\\Plugins\\Version",
+                        "Pest\\Plugins\\Shard",
+                        "Pest\\Plugins\\Parallel"
+                    ]
+                },
+                "phpstan": {
+                    "includes": [
+                        "extension.neon"
+                    ]
+                }
+            },
+            "autoload": {
+                "files": [
+                    "src/Functions.php",
+                    "src/Pest.php"
+                ],
+                "psr-4": {
+                    "Pest\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Nuno Maduro",
+                    "email": "enunomaduro@gmail.com"
+                }
+            ],
+            "description": "The elegant PHP Testing Framework.",
+            "keywords": [
+                "framework",
+                "pest",
+                "php",
+                "test",
+                "testing",
+                "unit"
+            ],
+            "support": {
+                "issues": "https://github.com/pestphp/pest/issues",
+                "source": "https://github.com/pestphp/pest/tree/v4.3.2"
+            },
+            "funding": [
+                {
+                    "url": "https://www.paypal.com/paypalme/enunomaduro",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/nunomaduro",
+                    "type": "github"
+                }
+            ],
+            "time": "2026-01-28T01:01:19+00:00"
+        },
+        {
+            "name": "pestphp/pest-plugin",
+            "version": "v4.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/pestphp/pest-plugin.git",
+                "reference": "9d4b93d7f73d3f9c3189bb22c220fef271cdf568"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/pestphp/pest-plugin/zipball/9d4b93d7f73d3f9c3189bb22c220fef271cdf568",
+                "reference": "9d4b93d7f73d3f9c3189bb22c220fef271cdf568",
+                "shasum": ""
+            },
+            "require": {
+                "composer-plugin-api": "^2.0.0",
+                "composer-runtime-api": "^2.2.2",
+                "php": "^8.3"
+            },
+            "conflict": {
+                "pestphp/pest": "<4.0.0"
+            },
+            "require-dev": {
+                "composer/composer": "^2.8.10",
+                "pestphp/pest": "^4.0.0",
+                "pestphp/pest-dev-tools": "^4.0.0"
+            },
+            "type": "composer-plugin",
+            "extra": {
+                "class": "Pest\\Plugin\\Manager"
+            },
+            "autoload": {
+                "psr-4": {
+                    "Pest\\Plugin\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "description": "The Pest plugin manager",
+            "keywords": [
+                "framework",
+                "manager",
+                "pest",
+                "php",
+                "plugin",
+                "test",
+                "testing",
+                "unit"
+            ],
+            "support": {
+                "source": "https://github.com/pestphp/pest-plugin/tree/v4.0.0"
+            },
+            "funding": [
+                {
+                    "url": "https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=66BYDWAT92N6L",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/nunomaduro",
+                    "type": "github"
+                },
+                {
+                    "url": "https://www.patreon.com/nunomaduro",
+                    "type": "patreon"
+                }
+            ],
+            "time": "2025-08-20T12:35:58+00:00"
+        },
+        {
+            "name": "pestphp/pest-plugin-arch",
+            "version": "v4.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/pestphp/pest-plugin-arch.git",
+                "reference": "25bb17e37920ccc35cbbcda3b00d596aadf3e58d"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/pestphp/pest-plugin-arch/zipball/25bb17e37920ccc35cbbcda3b00d596aadf3e58d",
+                "reference": "25bb17e37920ccc35cbbcda3b00d596aadf3e58d",
+                "shasum": ""
+            },
+            "require": {
+                "pestphp/pest-plugin": "^4.0.0",
+                "php": "^8.3",
+                "ta-tikoma/phpunit-architecture-test": "^0.8.5"
+            },
+            "require-dev": {
+                "pestphp/pest": "^4.0.0",
+                "pestphp/pest-dev-tools": "^4.0.0"
+            },
+            "type": "library",
+            "extra": {
+                "pest": {
+                    "plugins": [
+                        "Pest\\Arch\\Plugin"
+                    ]
+                }
+            },
+            "autoload": {
+                "files": [
+                    "src/Autoload.php"
+                ],
+                "psr-4": {
+                    "Pest\\Arch\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "description": "The Arch plugin for Pest PHP.",
+            "keywords": [
+                "arch",
+                "architecture",
+                "framework",
+                "pest",
+                "php",
+                "plugin",
+                "test",
+                "testing",
+                "unit"
+            ],
+            "support": {
+                "source": "https://github.com/pestphp/pest-plugin-arch/tree/v4.0.0"
+            },
+            "funding": [
+                {
+                    "url": "https://www.paypal.com/paypalme/enunomaduro",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/nunomaduro",
+                    "type": "github"
+                }
+            ],
+            "time": "2025-08-20T13:10:51+00:00"
+        },
+        {
+            "name": "pestphp/pest-plugin-laravel",
+            "version": "v4.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/pestphp/pest-plugin-laravel.git",
+                "reference": "e12a07046b826a40b1c8632fd7b80d6b8d7b628e"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/pestphp/pest-plugin-laravel/zipball/e12a07046b826a40b1c8632fd7b80d6b8d7b628e",
+                "reference": "e12a07046b826a40b1c8632fd7b80d6b8d7b628e",
+                "shasum": ""
+            },
+            "require": {
+                "laravel/framework": "^11.45.2|^12.25.0",
+                "pestphp/pest": "^4.0.0",
+                "php": "^8.3.0"
+            },
+            "require-dev": {
+                "laravel/dusk": "^8.3.3",
+                "orchestra/testbench": "^9.13.0|^10.5.0",
+                "pestphp/pest-dev-tools": "^4.0.0"
+            },
+            "type": "library",
+            "extra": {
+                "pest": {
+                    "plugins": [
+                        "Pest\\Laravel\\Plugin"
+                    ]
+                },
+                "laravel": {
+                    "providers": [
+                        "Pest\\Laravel\\PestServiceProvider"
+                    ]
+                }
+            },
+            "autoload": {
+                "files": [
+                    "src/Autoload.php"
+                ],
+                "psr-4": {
+                    "Pest\\Laravel\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "description": "The Pest Laravel Plugin",
+            "keywords": [
+                "framework",
+                "laravel",
+                "pest",
+                "php",
+                "test",
+                "testing",
+                "unit"
+            ],
+            "support": {
+                "source": "https://github.com/pestphp/pest-plugin-laravel/tree/v4.0.0"
+            },
+            "funding": [
+                {
+                    "url": "https://www.paypal.com/paypalme/enunomaduro",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/nunomaduro",
+                    "type": "github"
+                }
+            ],
+            "time": "2025-08-20T12:46:37+00:00"
+        },
+        {
+            "name": "pestphp/pest-plugin-mutate",
+            "version": "v4.0.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/pestphp/pest-plugin-mutate.git",
+                "reference": "d9b32b60b2385e1688a68cc227594738ec26d96c"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/pestphp/pest-plugin-mutate/zipball/d9b32b60b2385e1688a68cc227594738ec26d96c",
+                "reference": "d9b32b60b2385e1688a68cc227594738ec26d96c",
+                "shasum": ""
+            },
+            "require": {
+                "nikic/php-parser": "^5.6.1",
+                "pestphp/pest-plugin": "^4.0.0",
+                "php": "^8.3",
+                "psr/simple-cache": "^3.0.0"
+            },
+            "require-dev": {
+                "pestphp/pest": "^4.0.0",
+                "pestphp/pest-dev-tools": "^4.0.0",
+                "pestphp/pest-plugin-type-coverage": "^4.0.0"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Pest\\Mutate\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Nuno Maduro",
+                    "email": "enunomaduro@gmail.com"
+                },
+                {
+                    "name": "Sandro Gehri",
+                    "email": "sandrogehri@gmail.com"
+                }
+            ],
+            "description": "Mutates your code to find untested cases",
+            "keywords": [
+                "framework",
+                "mutate",
+                "mutation",
+                "pest",
+                "php",
+                "plugin",
+                "test",
+                "testing",
+                "unit"
+            ],
+            "support": {
+                "source": "https://github.com/pestphp/pest-plugin-mutate/tree/v4.0.1"
+            },
+            "funding": [
+                {
+                    "url": "https://www.paypal.com/paypalme/enunomaduro",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/gehrisandro",
+                    "type": "github"
+                },
+                {
+                    "url": "https://github.com/nunomaduro",
+                    "type": "github"
+                }
+            ],
+            "time": "2025-08-21T20:19:25+00:00"
+        },
+        {
+            "name": "pestphp/pest-plugin-profanity",
+            "version": "v4.2.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/pestphp/pest-plugin-profanity.git",
+                "reference": "343cfa6f3564b7e35df0ebb77b7fa97039f72b27"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/pestphp/pest-plugin-profanity/zipball/343cfa6f3564b7e35df0ebb77b7fa97039f72b27",
+                "reference": "343cfa6f3564b7e35df0ebb77b7fa97039f72b27",
+                "shasum": ""
+            },
+            "require": {
+                "pestphp/pest-plugin": "^4.0.0",
+                "php": "^8.3"
+            },
+            "require-dev": {
+                "faissaloux/pest-plugin-inside": "^1.9",
+                "pestphp/pest": "^4.0.0",
+                "pestphp/pest-dev-tools": "^4.0.0"
+            },
+            "type": "library",
+            "extra": {
+                "pest": {
+                    "plugins": [
+                        "Pest\\Profanity\\Plugin"
+                    ]
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Pest\\Profanity\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "description": "The Pest Profanity Plugin",
+            "keywords": [
+                "framework",
+                "pest",
+                "php",
+                "plugin",
+                "profanity",
+                "test",
+                "testing",
+                "unit"
+            ],
+            "support": {
+                "source": "https://github.com/pestphp/pest-plugin-profanity/tree/v4.2.1"
+            },
+            "time": "2025-12-08T00:13:17+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": "php-debugbar/php-debugbar",
+            "version": "v3.3.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/php-debugbar/php-debugbar.git",
+                "reference": "e22287890107602af6a113dc7975b3d77c542e5f"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/php-debugbar/php-debugbar/zipball/e22287890107602af6a113dc7975b3d77c542e5f",
+                "reference": "e22287890107602af6a113dc7975b3d77c542e5f",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^8.2",
+                "psr/log": "^1|^2|^3",
+                "symfony/var-dumper": "^5.4|^6|^7|^8"
+            },
+            "replace": {
+                "maximebf/debugbar": "self.version"
+            },
+            "require-dev": {
+                "dbrekelmans/bdi": "^1.4",
+                "friendsofphp/php-cs-fixer": "^3.92",
+                "monolog/monolog": "^3.9",
+                "php-debugbar/doctrine-bridge": "^3@dev",
+                "php-debugbar/monolog-bridge": "^1@dev",
+                "php-debugbar/symfony-bridge": "^1@dev",
+                "php-debugbar/twig-bridge": "^2@dev",
+                "phpstan/phpstan": "^2.1",
+                "phpstan/phpstan-phpunit": "^2.0",
+                "phpstan/phpstan-strict-rules": "^2.0",
+                "phpunit/phpunit": "^10",
+                "predis/predis": "^3.3",
+                "shipmonk/phpstan-rules": "^4.3",
+                "symfony/browser-kit": "^6.4|7.0",
+                "symfony/dom-crawler": "^6.4|^7",
+                "symfony/event-dispatcher": "^5.4|^6.4|^7.3|^8.0",
+                "symfony/http-foundation": "^5.4|^6.4|^7.3|^8.0",
+                "symfony/mailer": "^5.4|^6.4|^7.3|^8.0",
+                "symfony/panther": "^1|^2.1",
+                "twig/twig": "^3.11.2"
+            },
+            "suggest": {
+                "php-debugbar/doctrine-bridge": "To integrate Doctrine with php-debugbar.",
+                "php-debugbar/monolog-bridge": "To integrate Monolog with php-debugbar.",
+                "php-debugbar/symfony-bridge": "To integrate Symfony with php-debugbar.",
+                "php-debugbar/twig-bridge": "To integrate Twig with php-debugbar."
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "3.0-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "DebugBar\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Maxime Bouroumeau-Fuseau",
+                    "email": "maxime.bouroumeau@gmail.com",
+                    "homepage": "http://maximebf.com"
+                },
+                {
+                    "name": "Barry vd. Heuvel",
+                    "email": "barryvdh@gmail.com"
+                }
+            ],
+            "description": "Debug bar in the browser for php application",
+            "homepage": "https://github.com/php-debugbar/php-debugbar",
+            "keywords": [
+                "debug",
+                "debug bar",
+                "debugbar",
+                "dev",
+                "profiler",
+                "toolbar"
+            ],
+            "support": {
+                "issues": "https://github.com/php-debugbar/php-debugbar/issues",
+                "source": "https://github.com/php-debugbar/php-debugbar/tree/v3.3.0"
+            },
+            "funding": [
+                {
+                    "url": "https://fruitcake.nl",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/barryvdh",
+                    "type": "github"
+                }
+            ],
+            "time": "2026-01-28T12:57:47+00:00"
+        },
+        {
+            "name": "php-debugbar/symfony-bridge",
+            "version": "v1.1.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/php-debugbar/symfony-bridge.git",
+                "reference": "e37d2debe5d316408b00d0ab2688d9c2cf59b5ad"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/php-debugbar/symfony-bridge/zipball/e37d2debe5d316408b00d0ab2688d9c2cf59b5ad",
+                "reference": "e37d2debe5d316408b00d0ab2688d9c2cf59b5ad",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^8.2",
+                "php-debugbar/php-debugbar": "^3.1",
+                "symfony/http-foundation": "^5.4|^6.4|^7.3|^8.0"
+            },
+            "require-dev": {
+                "dbrekelmans/bdi": "^1.4",
+                "phpunit/phpunit": "^10",
+                "symfony/browser-kit": "^6|^7",
+                "symfony/dom-crawler": "^6|^7",
+                "symfony/mailer": "^5.4|^6.4|^7.3|^8.0",
+                "symfony/panther": "^1|^2.1"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.0-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "DebugBar\\Bridge\\Symfony\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Maxime Bouroumeau-Fuseau",
+                    "email": "maxime.bouroumeau@gmail.com",
+                    "homepage": "http://maximebf.com"
+                },
+                {
+                    "name": "Barry vd. Heuvel",
+                    "email": "barryvdh@gmail.com"
+                }
+            ],
+            "description": "Symfony bridge for PHP Debugbar",
+            "homepage": "https://github.com/php-debugbar/php-debugbar",
+            "keywords": [
+                "debugbar",
+                "dev",
+                "symfony"
+            ],
+            "support": {
+                "issues": "https://github.com/php-debugbar/symfony-bridge/issues",
+                "source": "https://github.com/php-debugbar/symfony-bridge/tree/v1.1.0"
+            },
+            "time": "2026-01-15T14:47:34+00:00"
+        },
+        {
+            "name": "phpunit/php-code-coverage",
+            "version": "12.5.2",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
+                "reference": "4a9739b51cbcb355f6e95659612f92e282a7077b"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/4a9739b51cbcb355f6e95659612f92e282a7077b",
+                "reference": "4a9739b51cbcb355f6e95659612f92e282a7077b",
+                "shasum": ""
+            },
+            "require": {
+                "ext-dom": "*",
+                "ext-libxml": "*",
+                "ext-xmlwriter": "*",
+                "nikic/php-parser": "^5.7.0",
+                "php": ">=8.3",
+                "phpunit/php-file-iterator": "^6.0",
+                "phpunit/php-text-template": "^5.0",
+                "sebastian/complexity": "^5.0",
+                "sebastian/environment": "^8.0.3",
+                "sebastian/lines-of-code": "^4.0",
+                "sebastian/version": "^6.0",
+                "theseer/tokenizer": "^2.0.1"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^12.5.1"
+            },
+            "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": "12.5.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/12.5.2"
+            },
+            "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-12-24T07:03:04+00:00"
+        },
+        {
+            "name": "phpunit/php-file-iterator",
+            "version": "6.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
+                "reference": "961bc913d42fe24a257bfff826a5068079ac7782"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/961bc913d42fe24a257bfff826a5068079ac7782",
+                "reference": "961bc913d42fe24a257bfff826a5068079ac7782",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=8.3"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^12.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",
+                    "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/6.0.0"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/sebastianbergmann",
+                    "type": "github"
+                }
+            ],
+            "time": "2025-02-07T04:58:37+00:00"
+        },
+        {
+            "name": "phpunit/php-invoker",
+            "version": "6.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/php-invoker.git",
+                "reference": "12b54e689b07a25a9b41e57736dfab6ec9ae5406"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/12b54e689b07a25a9b41e57736dfab6ec9ae5406",
+                "reference": "12b54e689b07a25a9b41e57736dfab6ec9ae5406",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=8.3"
+            },
+            "require-dev": {
+                "ext-pcntl": "*",
+                "phpunit/phpunit": "^12.0"
+            },
+            "suggest": {
+                "ext-pcntl": "*"
+            },
+            "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",
+                    "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/6.0.0"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/sebastianbergmann",
+                    "type": "github"
+                }
+            ],
+            "time": "2025-02-07T04:58:58+00:00"
+        },
+        {
+            "name": "phpunit/php-text-template",
+            "version": "5.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/php-text-template.git",
+                "reference": "e1367a453f0eda562eedb4f659e13aa900d66c53"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/e1367a453f0eda562eedb4f659e13aa900d66c53",
+                "reference": "e1367a453f0eda562eedb4f659e13aa900d66c53",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=8.3"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^12.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": "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/5.0.0"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/sebastianbergmann",
+                    "type": "github"
+                }
+            ],
+            "time": "2025-02-07T04:59:16+00:00"
+        },
+        {
+            "name": "phpunit/php-timer",
+            "version": "8.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/php-timer.git",
+                "reference": "f258ce36aa457f3aa3339f9ed4c81fc66dc8c2cc"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/f258ce36aa457f3aa3339f9ed4c81fc66dc8c2cc",
+                "reference": "f258ce36aa457f3aa3339f9ed4c81fc66dc8c2cc",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=8.3"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^12.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-main": "8.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/8.0.0"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/sebastianbergmann",
+                    "type": "github"
+                }
+            ],
+            "time": "2025-02-07T04:59:38+00:00"
+        },
+        {
+            "name": "phpunit/phpunit",
+            "version": "12.5.8",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/phpunit.git",
+                "reference": "37ddb96c14bfee10304825edbb7e66d341ec6889"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/37ddb96c14bfee10304825edbb7e66d341ec6889",
+                "reference": "37ddb96c14bfee10304825edbb7e66d341ec6889",
+                "shasum": ""
+            },
+            "require": {
+                "ext-dom": "*",
+                "ext-json": "*",
+                "ext-libxml": "*",
+                "ext-mbstring": "*",
+                "ext-xml": "*",
+                "ext-xmlwriter": "*",
+                "myclabs/deep-copy": "^1.13.4",
+                "phar-io/manifest": "^2.0.4",
+                "phar-io/version": "^3.2.1",
+                "php": ">=8.3",
+                "phpunit/php-code-coverage": "^12.5.2",
+                "phpunit/php-file-iterator": "^6.0.0",
+                "phpunit/php-invoker": "^6.0.0",
+                "phpunit/php-text-template": "^5.0.0",
+                "phpunit/php-timer": "^8.0.0",
+                "sebastian/cli-parser": "^4.2.0",
+                "sebastian/comparator": "^7.1.4",
+                "sebastian/diff": "^7.0.0",
+                "sebastian/environment": "^8.0.3",
+                "sebastian/exporter": "^7.0.2",
+                "sebastian/global-state": "^8.0.2",
+                "sebastian/object-enumerator": "^7.0.0",
+                "sebastian/type": "^6.0.3",
+                "sebastian/version": "^6.0.0",
+                "staabm/side-effects-detector": "^1.0.5"
+            },
+            "bin": [
+                "phpunit"
+            ],
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-main": "12.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/12.5.8"
+            },
+            "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": "2026-01-27T06:12:29+00:00"
+        },
+        {
+            "name": "sebastian/cli-parser",
+            "version": "4.2.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/cli-parser.git",
+                "reference": "90f41072d220e5c40df6e8635f5dafba2d9d4d04"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/90f41072d220e5c40df6e8635f5dafba2d9d4d04",
+                "reference": "90f41072d220e5c40df6e8635f5dafba2d9d4d04",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=8.3"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^12.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-main": "4.2-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/4.2.0"
+            },
+            "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/cli-parser",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2025-09-14T09:36:45+00:00"
+        },
+        {
+            "name": "sebastian/comparator",
+            "version": "7.1.4",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/comparator.git",
+                "reference": "6a7de5df2e094f9a80b40a522391a7e6022df5f6"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/6a7de5df2e094f9a80b40a522391a7e6022df5f6",
+                "reference": "6a7de5df2e094f9a80b40a522391a7e6022df5f6",
+                "shasum": ""
+            },
+            "require": {
+                "ext-dom": "*",
+                "ext-mbstring": "*",
+                "php": ">=8.3",
+                "sebastian/diff": "^7.0",
+                "sebastian/exporter": "^7.0"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^12.2"
+            },
+            "suggest": {
+                "ext-bcmath": "For comparing BcMath\\Number objects"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-main": "7.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": "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/7.1.4"
+            },
+            "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/comparator",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2026-01-24T09:28:48+00:00"
+        },
+        {
+            "name": "sebastian/complexity",
+            "version": "5.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/complexity.git",
+                "reference": "bad4316aba5303d0221f43f8cee37eb58d384bbb"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/bad4316aba5303d0221f43f8cee37eb58d384bbb",
+                "reference": "bad4316aba5303d0221f43f8cee37eb58d384bbb",
+                "shasum": ""
+            },
+            "require": {
+                "nikic/php-parser": "^5.0",
+                "php": ">=8.3"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^12.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": "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/5.0.0"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/sebastianbergmann",
+                    "type": "github"
+                }
+            ],
+            "time": "2025-02-07T04:55:25+00:00"
+        },
+        {
+            "name": "sebastian/diff",
+            "version": "7.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/diff.git",
+                "reference": "7ab1ea946c012266ca32390913653d844ecd085f"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/7ab1ea946c012266ca32390913653d844ecd085f",
+                "reference": "7ab1ea946c012266ca32390913653d844ecd085f",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=8.3"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^12.0",
+                "symfony/process": "^7.2"
+            },
+            "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"
+                },
+                {
+                    "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/7.0.0"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/sebastianbergmann",
+                    "type": "github"
+                }
+            ],
+            "time": "2025-02-07T04:55:46+00:00"
+        },
+        {
+            "name": "sebastian/environment",
+            "version": "8.0.3",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/environment.git",
+                "reference": "24a711b5c916efc6d6e62aa65aa2ec98fef77f68"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/24a711b5c916efc6d6e62aa65aa2ec98fef77f68",
+                "reference": "24a711b5c916efc6d6e62aa65aa2ec98fef77f68",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=8.3"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^12.0"
+            },
+            "suggest": {
+                "ext-posix": "*"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-main": "8.0-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/8.0.3"
+            },
+            "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-08-12T14:11:56+00:00"
+        },
+        {
+            "name": "sebastian/exporter",
+            "version": "7.0.2",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/exporter.git",
+                "reference": "016951ae10980765e4e7aee491eb288c64e505b7"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/016951ae10980765e4e7aee491eb288c64e505b7",
+                "reference": "016951ae10980765e4e7aee491eb288c64e505b7",
+                "shasum": ""
+            },
+            "require": {
+                "ext-mbstring": "*",
+                "php": ">=8.3",
+                "sebastian/recursion-context": "^7.0"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^12.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"
+                },
+                {
+                    "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/7.0.2"
+            },
+            "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/exporter",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2025-09-24T06:16:11+00:00"
+        },
+        {
+            "name": "sebastian/global-state",
+            "version": "8.0.2",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/global-state.git",
+                "reference": "ef1377171613d09edd25b7816f05be8313f9115d"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/ef1377171613d09edd25b7816f05be8313f9115d",
+                "reference": "ef1377171613d09edd25b7816f05be8313f9115d",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=8.3",
+                "sebastian/object-reflector": "^5.0",
+                "sebastian/recursion-context": "^7.0"
+            },
+            "require-dev": {
+                "ext-dom": "*",
+                "phpunit/phpunit": "^12.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-main": "8.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/8.0.2"
+            },
+            "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/global-state",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2025-08-29T11:29:25+00:00"
+        },
+        {
+            "name": "sebastian/lines-of-code",
+            "version": "4.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/lines-of-code.git",
+                "reference": "97ffee3bcfb5805568d6af7f0f893678fc076d2f"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/97ffee3bcfb5805568d6af7f0f893678fc076d2f",
+                "reference": "97ffee3bcfb5805568d6af7f0f893678fc076d2f",
+                "shasum": ""
+            },
+            "require": {
+                "nikic/php-parser": "^5.0",
+                "php": ">=8.3"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^12.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 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/4.0.0"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/sebastianbergmann",
+                    "type": "github"
+                }
+            ],
+            "time": "2025-02-07T04:57:28+00:00"
+        },
+        {
+            "name": "sebastian/object-enumerator",
+            "version": "7.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/object-enumerator.git",
+                "reference": "1effe8e9b8e068e9ae228e542d5d11b5d16db894"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/1effe8e9b8e068e9ae228e542d5d11b5d16db894",
+                "reference": "1effe8e9b8e068e9ae228e542d5d11b5d16db894",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=8.3",
+                "sebastian/object-reflector": "^5.0",
+                "sebastian/recursion-context": "^7.0"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^12.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": "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/7.0.0"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/sebastianbergmann",
+                    "type": "github"
+                }
+            ],
+            "time": "2025-02-07T04:57:48+00:00"
+        },
+        {
+            "name": "sebastian/object-reflector",
+            "version": "5.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/object-reflector.git",
+                "reference": "4bfa827c969c98be1e527abd576533293c634f6a"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/4bfa827c969c98be1e527abd576533293c634f6a",
+                "reference": "4bfa827c969c98be1e527abd576533293c634f6a",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=8.3"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^12.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"
+                }
+            ],
+            "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/5.0.0"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/sebastianbergmann",
+                    "type": "github"
+                }
+            ],
+            "time": "2025-02-07T04:58:17+00:00"
+        },
+        {
+            "name": "sebastian/recursion-context",
+            "version": "7.0.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/recursion-context.git",
+                "reference": "0b01998a7d5b1f122911a66bebcb8d46f0c82d8c"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/0b01998a7d5b1f122911a66bebcb8d46f0c82d8c",
+                "reference": "0b01998a7d5b1f122911a66bebcb8d46f0c82d8c",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=8.3"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^12.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"
+                },
+                {
+                    "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/7.0.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/recursion-context",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2025-08-13T04:44:59+00:00"
+        },
+        {
+            "name": "sebastian/type",
+            "version": "6.0.3",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/type.git",
+                "reference": "e549163b9760b8f71f191651d22acf32d56d6d4d"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/e549163b9760b8f71f191651d22acf32d56d6d4d",
+                "reference": "e549163b9760b8f71f191651d22acf32d56d6d4d",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=8.3"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^12.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",
+                    "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/6.0.3"
+            },
+            "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/type",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2025-08-09T06:57:12+00:00"
+        },
+        {
+            "name": "sebastian/version",
+            "version": "6.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/version.git",
+                "reference": "3e6ccf7657d4f0a59200564b08cead899313b53c"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/3e6ccf7657d4f0a59200564b08cead899313b53c",
+                "reference": "3e6ccf7657d4f0a59200564b08cead899313b53c",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=8.3"
+            },
+            "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",
+                    "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/6.0.0"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/sebastianbergmann",
+                    "type": "github"
+                }
+            ],
+            "time": "2025-02-07T05:00:38+00:00"
+        },
+        {
+            "name": "spatie/backtrace",
+            "version": "1.8.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/spatie/backtrace.git",
+                "reference": "8c0f16a59ae35ec8c62d85c3c17585158f430110"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/spatie/backtrace/zipball/8c0f16a59ae35ec8c62d85c3c17585158f430110",
+                "reference": "8c0f16a59ae35ec8c62d85c3c17585158f430110",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.3 || ^8.0"
+            },
+            "require-dev": {
+                "ext-json": "*",
+                "laravel/serializable-closure": "^1.3 || ^2.0",
+                "phpunit/phpunit": "^9.3 || ^11.4.3",
+                "spatie/phpunit-snapshot-assertions": "^4.2 || ^5.1.6",
+                "symfony/var-dumper": "^5.1 || ^6.0 || ^7.0"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Spatie\\Backtrace\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Freek Van de Herten",
+                    "email": "freek@spatie.be",
+                    "homepage": "https://spatie.be",
+                    "role": "Developer"
+                }
+            ],
+            "description": "A better backtrace",
+            "homepage": "https://github.com/spatie/backtrace",
+            "keywords": [
+                "Backtrace",
+                "spatie"
+            ],
+            "support": {
+                "issues": "https://github.com/spatie/backtrace/issues",
+                "source": "https://github.com/spatie/backtrace/tree/1.8.1"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/sponsors/spatie",
+                    "type": "github"
+                },
+                {
+                    "url": "https://spatie.be/open-source/support-us",
+                    "type": "other"
+                }
+            ],
+            "time": "2025-08-26T08:22:30+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": "ta-tikoma/phpunit-architecture-test",
+            "version": "0.8.6",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/ta-tikoma/phpunit-architecture-test.git",
+                "reference": "ad48430b92901fd7d003fdaf2d7b139f96c0906e"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/ta-tikoma/phpunit-architecture-test/zipball/ad48430b92901fd7d003fdaf2d7b139f96c0906e",
+                "reference": "ad48430b92901fd7d003fdaf2d7b139f96c0906e",
+                "shasum": ""
+            },
+            "require": {
+                "nikic/php-parser": "^4.18.0 || ^5.0.0",
+                "php": "^8.1.0",
+                "phpdocumentor/reflection-docblock": "^5.3.0 || ^6.0.0",
+                "phpunit/phpunit": "^10.5.5 || ^11.0.0 || ^12.0.0",
+                "symfony/finder": "^6.4.0 || ^7.0.0 || ^8.0.0"
+            },
+            "require-dev": {
+                "laravel/pint": "^1.13.7",
+                "phpstan/phpstan": "^1.10.52"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "PHPUnit\\Architecture\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Ni Shi",
+                    "email": "futik0ma011@gmail.com"
+                },
+                {
+                    "name": "Nuno Maduro",
+                    "email": "enunomaduro@gmail.com"
+                }
+            ],
+            "description": "Methods for testing application architecture",
+            "keywords": [
+                "architecture",
+                "phpunit",
+                "stucture",
+                "test",
+                "testing"
+            ],
+            "support": {
+                "issues": "https://github.com/ta-tikoma/phpunit-architecture-test/issues",
+                "source": "https://github.com/ta-tikoma/phpunit-architecture-test/tree/0.8.6"
+            },
+            "time": "2026-01-30T07:16:00+00:00"
+        },
+        {
+            "name": "theseer/tokenizer",
+            "version": "2.0.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/theseer/tokenizer.git",
+                "reference": "7989e43bf381af0eac72e4f0ca5bcbfa81658be4"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/theseer/tokenizer/zipball/7989e43bf381af0eac72e4f0ca5bcbfa81658be4",
+                "reference": "7989e43bf381af0eac72e4f0ca5bcbfa81658be4",
+                "shasum": ""
+            },
+            "require": {
+                "ext-dom": "*",
+                "ext-tokenizer": "*",
+                "ext-xmlwriter": "*",
+                "php": "^8.1"
+            },
+            "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/2.0.1"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/theseer",
+                    "type": "github"
+                }
+            ],
+            "time": "2025-12-08T11:19:18+00:00"
+        }
+    ],
+    "aliases": [],
+    "minimum-stability": "stable",
+    "stability-flags": {},
+    "prefer-stable": true,
+    "prefer-lowest": false,
+    "platform": {
+        "php": "^8.4"
+    },
+    "platform-dev": {},
+    "plugin-api-version": "2.9.0"
+}
diff --git a/config/app.php b/config/app.php
index 423eed5..80fb5eb 100644
--- a/config/app.php
+++ b/config/app.php
@@ -123,4 +123,4 @@
         'store' => env('APP_MAINTENANCE_STORE', 'database'),
     ],
 
-];
+];
\ No newline at end of file
diff --git a/config/myapp.php b/config/myapp.php
new file mode 100644
index 0000000..8cef448
--- /dev/null
+++ b/config/myapp.php
@@ -0,0 +1,39 @@
+ env('MY_PROJECT_SLUG'),
+    'importDir' => env('MY_IMPORT_DIR'),
+    'imagePlaceholder' => env('MY_IMAGE_PLACEHOLDER'),
+    'image' => [
+        'featured' => 'featured.jpg',
+        'cover' => 'cover.jpg',
+        'placeholder' => [
+            'page' => 'storage/images/placeholders/page.jpg',
+            'article' => 'storage/images/placeholders/article.jpg',
+            'place' => 'storage/images/placeholders/place.jpg',
+        ],
+    ],
+    'album' => [
+        'default' => 'ivnbg',
+        'dir' => [
+            'source' => public_path() . '/storage/albums',
+            'target' => public_path() . '/storage/albums',
+        ],
+        'file' => [
+            'album' => 'albums.json',
+            'event' => 'events.json',
+            'image' => 'images.json',
+
+        ],
+        'url' => env('MY_ALBUM_URL'),
+        'albumsUrl' => env('MY_ALBUM_ALBUMS_URL'),
+        'eventsUrl' => env('MY_ALBUM_EVENTS_URL'),
+        'imagesUrl' => env('MY_ALBUM_IMAGES_URL'),
+        'srcDir' => 'src',
+        'thumbDir' => 'thumb',
+        'thumbWidth' => 200,
+        'featured' => 'featured.jpg',
+        'cover' => 'cover.jpg',
+    ],
+
+];
\ No newline at end of file
diff --git a/database/migrations/2026_01_05_184533_create_projects_table.php b/database/migrations/2026_01_05_184533_create_projects_table.php
index bb04b66..a7972eb 100644
--- a/database/migrations/2026_01_05_184533_create_projects_table.php
+++ b/database/migrations/2026_01_05_184533_create_projects_table.php
@@ -14,6 +14,7 @@ public function up(): void
         Schema::create('projects', function (Blueprint $table) {
             $table->id();
             $table->string('slug')->unique();
+            $table->string('url')->unique();
             $table->text('excerpt')->nullable();
             $table->json('metadata')->nullable();
             $table->timestamps();
@@ -28,4 +29,4 @@ public function down(): void
     {
         Schema::dropIfExists('projects');
     }
-};
+};
\ No newline at end of file
diff --git a/database/seeders/CategorySeederProject.php b/database/seeders/CategorySeederProject.php
index 6c9708a..4890a2f 100644
--- a/database/seeders/CategorySeederProject.php
+++ b/database/seeders/CategorySeederProject.php
@@ -4,6 +4,7 @@
 
 namespace Database\Seeders;
 
+use App\Enums\AppProject;
 use App\Enums\ContentContentType;
 use App\Models\Category;
 use App\Models\Project;
@@ -17,7 +18,7 @@ class CategorySeederProject extends Seeder
      */
     public function run(): void
     {
-        $vadesProjectId = Project::where('slug', 'vades')->first()->id;
+        $vadesProjectId = Project::where('slug', AppProject::Vades)->first()->id;
         $this->storeData('data/vades-article-categories.csv',  $vadesProjectId,ContentContentType::Article->value);
         /*$ivnbgProjectId = Project::where('slug', 'ivnbg')->first()->id;
         $this->storeData('data/ivnbg-categories.csv', $ivnbgProjectId,'place');*/
diff --git a/database/seeders/ProjectSeeder.php b/database/seeders/ProjectSeeder.php
index 50883ce..719cc2c 100644
--- a/database/seeders/ProjectSeeder.php
+++ b/database/seeders/ProjectSeeder.php
@@ -18,32 +18,38 @@ public function run(): void
             [
                 'slug' =>AppProject::Ivnbg->value,
                 'excerpt' => 'ivnbg.com project',
-                'metadata' => ['url' => 'www.ivnbg.com'],
+              'url' => AppProject::Ivnbg->getUrl(),
+                'metadata' => [ ],
             ],
             [
                 'slug' => AppProject::MartinVach->value,
                 'excerpt' => 'martinvach.com project',
-                'metadata' => ['url' => 'www.martinvach.com'],
+                'url' => AppProject::MartinVach->getUrl(),
+                'metadata' => [ ],
             ],
             [
                 'slug' => AppProject::MyPrompties->value,
                 'excerpt' => 'myprompties.com project',
-                'metadata' => ['url' => 'www.myprompties.com'],
+                'url' => AppProject::MyPrompties->getUrl(),
+                'metadata' => [ ],
             ],
             [
                 'slug' => AppProject::Vades->value,
                 'excerpt' => 'vades.dev project',
-                'metadata' => ['url' => 'www.vades.dev'],
+                'url' => AppProject::Vades->getUrl(),
+                'metadata' => [ ],
             ],
             [
                 'slug' => AppProject::Aitomatix->value,
                 'excerpt' => 'aitomatix.com project',
-                'metadata' => ['url' => 'www.aitomatix.com'],
+                'url' => AppProject::Aitomatix->getUrl(),
+                'metadata' => [ ],
             ],
             [
                 'slug' => AppProject::LaravelCore->value,
                 'excerpt' => 'laravel-core.test project. Only for local testing purposes.',
-                'metadata' => null,
+                'url' => AppProject::LaravelCore->getUrl(),
+                    'metadata' => [ ],
             ],
         ];
 
diff --git a/lang/en/app.php b/lang/en/app.php
new file mode 100644
index 0000000..76c1e3f
--- /dev/null
+++ b/lang/en/app.php
@@ -0,0 +1,62 @@
+ [
+        'about' => 'About',
+        'contact' => 'Contact',
+        'home' => 'Home',
+        'categories' => 'Categories',
+        'tags' => 'Tags',
+        'search' => 'Search',
+        'placeCategoryList' => 'Categories',
+        'places' => 'Places',
+        'readMore' => 'Read more',
+        'readMoreAbout' => 'Read more about :about',
+        'articleIndex' => 'Blog',
+        'photoGallery' => 'Photo gallery',
+        'bestPlacesToVisitIn' => 'Best places to visit in :name',
+        'seeMore' => 'See more',
+        'otherPlaces' => 'Other places',
+        'all' => 'All',
+        'all_' => 'All :name',
+        'recentPosts' => 'Recent posts',
+        'listOfPlaces' => 'List of places',
+        'address' => 'Address',
+        'highlights' => 'Highlights',
+        'takeMeHome' => 'Take me home',
+    ],
+
+    'search' => [
+        'blog' => 'Search in blog',
+        'title' => 'Search results for ":query"',
+        'noResults' => 'No results found for ":query"',
+    ],
+
+    'error' => [
+        '404' => [
+            'title' => "Oops! This page isn't available",
+            'message' => "We couldn't locate the page you requested. It might have moved, been deleted, or perhaps there's a typo in the address. Please check the URL and try again.",
+        ],
+        '500' => [
+            'title' => 'Oops! Internal Server Error',
+            'message' => "We're experiencing an unexpected issue with our server. Please try again in a few minutes.",
+        ],
+    ],
+    'form' => [
+        'name' => 'Name',
+        'yourName' => 'Your name',
+        'email' => 'Email',
+        'yourEmail' => 'Your email address',
+        'message' => 'Message',
+        'leaveMessage' => 'Leave us a message',
+        'submit' => 'Submit',
+        'successContactForm' => 'Your message has been sent successfully!',
+        'errorContactForm' => 'An error occurred while sending your message. Please try again.',
+        'contactUs' => 'Contact Us',
+
+        'followUs' => 'Follow us on social media',
+        'phone' => 'Phone',
+        'emailAddress' => 'Email Address',
+        'location' => 'Location',
+    ],
+];
\ No newline at end of file
diff --git a/lang/en/auth.php b/lang/en/auth.php
new file mode 100644
index 0000000..6598e2c
--- /dev/null
+++ b/lang/en/auth.php
@@ -0,0 +1,20 @@
+ 'These credentials do not match our records.',
+    'password' => 'The provided password is incorrect.',
+    'throttle' => 'Too many login attempts. Please try again in :seconds seconds.',
+
+];
diff --git a/lang/en/pagination.php b/lang/en/pagination.php
new file mode 100644
index 0000000..d481411
--- /dev/null
+++ b/lang/en/pagination.php
@@ -0,0 +1,19 @@
+ '« Previous',
+    'next' => 'Next »',
+
+];
diff --git a/lang/en/passwords.php b/lang/en/passwords.php
new file mode 100644
index 0000000..fad3a7d
--- /dev/null
+++ b/lang/en/passwords.php
@@ -0,0 +1,22 @@
+ 'Your password has been reset.',
+    'sent' => 'We have emailed your password reset link.',
+    'throttled' => 'Please wait before retrying.',
+    'token' => 'This password reset token is invalid.',
+    'user' => "We can't find a user with that email address.",
+
+];
diff --git a/lang/en/validation.php b/lang/en/validation.php
new file mode 100644
index 0000000..dddc947
--- /dev/null
+++ b/lang/en/validation.php
@@ -0,0 +1,194 @@
+ 'The :attribute field must be accepted.',
+    'accepted_if' => 'The :attribute field must be accepted when :other is :value.',
+    'active_url' => 'The :attribute field must be a valid URL.',
+    'after' => 'The :attribute field must be a date after :date.',
+    'after_or_equal' => 'The :attribute field must be a date after or equal to :date.',
+    'alpha' => 'The :attribute field must only contain letters.',
+    'alpha_dash' => 'The :attribute field must only contain letters, numbers, dashes, and underscores.',
+    'alpha_num' => 'The :attribute field must only contain letters and numbers.',
+    'array' => 'The :attribute field must be an array.',
+    'ascii' => 'The :attribute field must only contain single-byte alphanumeric characters and symbols.',
+    'before' => 'The :attribute field must be a date before :date.',
+    'before_or_equal' => 'The :attribute field must be a date before or equal to :date.',
+    'between' => [
+        'array' => 'The :attribute field must have between :min and :max items.',
+        'file' => 'The :attribute field must be between :min and :max kilobytes.',
+        'numeric' => 'The :attribute field must be between :min and :max.',
+        'string' => 'The :attribute field must be between :min and :max characters.',
+    ],
+    'boolean' => 'The :attribute field must be true or false.',
+    'can' => 'The :attribute field contains an unauthorized value.',
+    'confirmed' => 'The :attribute field confirmation does not match.',
+    'contains' => 'The :attribute field is missing a required value.',
+    'current_password' => 'The password is incorrect.',
+    'date' => 'The :attribute field must be a valid date.',
+    'date_equals' => 'The :attribute field must be a date equal to :date.',
+    'date_format' => 'The :attribute field must match the format :format.',
+    'decimal' => 'The :attribute field must have :decimal decimal places.',
+    'declined' => 'The :attribute field must be declined.',
+    'declined_if' => 'The :attribute field must be declined when :other is :value.',
+    'different' => 'The :attribute field and :other must be different.',
+    'digits' => 'The :attribute field must be :digits digits.',
+    'digits_between' => 'The :attribute field must be between :min and :max digits.',
+    'dimensions' => 'The :attribute field has invalid image dimensions.',
+    'distinct' => 'The :attribute field has a duplicate value.',
+    'doesnt_end_with' => 'The :attribute field must not end with one of the following: :values.',
+    'doesnt_start_with' => 'The :attribute field must not start with one of the following: :values.',
+    'email' => 'The :attribute field must be a valid email address.',
+    'ends_with' => 'The :attribute field must end with one of the following: :values.',
+    'enum' => 'The selected :attribute is invalid.',
+    'exists' => 'The selected :attribute is invalid.',
+    'extensions' => 'The :attribute field must have one of the following extensions: :values.',
+    'file' => 'The :attribute field must be a file.',
+    'filled' => 'The :attribute field must have a value.',
+    'gt' => [
+        'array' => 'The :attribute field must have more than :value items.',
+        'file' => 'The :attribute field must be greater than :value kilobytes.',
+        'numeric' => 'The :attribute field must be greater than :value.',
+        'string' => 'The :attribute field must be greater than :value characters.',
+    ],
+    'gte' => [
+        'array' => 'The :attribute field must have :value items or more.',
+        'file' => 'The :attribute field must be greater than or equal to :value kilobytes.',
+        'numeric' => 'The :attribute field must be greater than or equal to :value.',
+        'string' => 'The :attribute field must be greater than or equal to :value characters.',
+    ],
+    'hex_color' => 'The :attribute field must be a valid hexadecimal color.',
+    'image' => 'The :attribute field must be an image.',
+    'in' => 'The selected :attribute is invalid.',
+    'in_array' => 'The :attribute field must exist in :other.',
+    'integer' => 'The :attribute field must be an integer.',
+    'ip' => 'The :attribute field must be a valid IP address.',
+    'ipv4' => 'The :attribute field must be a valid IPv4 address.',
+    'ipv6' => 'The :attribute field must be a valid IPv6 address.',
+    'json' => 'The :attribute field must be a valid JSON string.',
+    'list' => 'The :attribute field must be a list.',
+    'lowercase' => 'The :attribute field must be lowercase.',
+    'lt' => [
+        'array' => 'The :attribute field must have less than :value items.',
+        'file' => 'The :attribute field must be less than :value kilobytes.',
+        'numeric' => 'The :attribute field must be less than :value.',
+        'string' => 'The :attribute field must be less than :value characters.',
+    ],
+    'lte' => [
+        'array' => 'The :attribute field must not have more than :value items.',
+        'file' => 'The :attribute field must be less than or equal to :value kilobytes.',
+        'numeric' => 'The :attribute field must be less than or equal to :value.',
+        'string' => 'The :attribute field must be less than or equal to :value characters.',
+    ],
+    'mac_address' => 'The :attribute field must be a valid MAC address.',
+    'max' => [
+        'array' => 'The :attribute field must not have more than :max items.',
+        'file' => 'The :attribute field must not be greater than :max kilobytes.',
+        'numeric' => 'The :attribute field must not be greater than :max.',
+        'string' => 'The :attribute field must not be greater than :max characters.',
+    ],
+    'max_digits' => 'The :attribute field must not have more than :max digits.',
+    'mimes' => 'The :attribute field must be a file of type: :values.',
+    'mimetypes' => 'The :attribute field must be a file of type: :values.',
+    'min' => [
+        'array' => 'The :attribute field must have at least :min items.',
+        'file' => 'The :attribute field must be at least :min kilobytes.',
+        'numeric' => 'The :attribute field must be at least :min.',
+        'string' => 'The :attribute field must be at least :min characters.',
+    ],
+    'min_digits' => 'The :attribute field must have at least :min digits.',
+    'missing' => 'The :attribute field must be missing.',
+    'missing_if' => 'The :attribute field must be missing when :other is :value.',
+    'missing_unless' => 'The :attribute field must be missing unless :other is :value.',
+    'missing_with' => 'The :attribute field must be missing when :values is present.',
+    'missing_with_all' => 'The :attribute field must be missing when :values are present.',
+    'multiple_of' => 'The :attribute field must be a multiple of :value.',
+    'not_in' => 'The selected :attribute is invalid.',
+    'not_regex' => 'The :attribute field format is invalid.',
+    'numeric' => 'The :attribute field must be a number.',
+    'password' => [
+        'letters' => 'The :attribute field must contain at least one letter.',
+        'mixed' => 'The :attribute field must contain at least one uppercase and one lowercase letter.',
+        'numbers' => 'The :attribute field must contain at least one number.',
+        'symbols' => 'The :attribute field must contain at least one symbol.',
+        'uncompromised' => 'The given :attribute has appeared in a data leak. Please choose a different :attribute.',
+    ],
+    'present' => 'The :attribute field must be present.',
+    'present_if' => 'The :attribute field must be present when :other is :value.',
+    'present_unless' => 'The :attribute field must be present unless :other is :value.',
+    'present_with' => 'The :attribute field must be present when :values is present.',
+    'present_with_all' => 'The :attribute field must be present when :values are present.',
+    'prohibited' => 'The :attribute field is prohibited.',
+    'prohibited_if' => 'The :attribute field is prohibited when :other is :value.',
+    'prohibited_unless' => 'The :attribute field is prohibited unless :other is in :values.',
+    'prohibits' => 'The :attribute field prohibits :other from being present.',
+    'regex' => 'The :attribute field format is invalid.',
+    'required' => 'The :attribute field is required.',
+    'required_array_keys' => 'The :attribute field must contain entries for: :values.',
+    'required_if' => 'The :attribute field is required when :other is :value.',
+    'required_if_accepted' => 'The :attribute field is required when :other is accepted.',
+    'required_if_declined' => 'The :attribute field is required when :other is declined.',
+    'required_unless' => 'The :attribute field is required unless :other is in :values.',
+    'required_with' => 'The :attribute field is required when :values is present.',
+    'required_with_all' => 'The :attribute field is required when :values are present.',
+    'required_without' => 'The :attribute field is required when :values is not present.',
+    'required_without_all' => 'The :attribute field is required when none of :values are present.',
+    'same' => 'The :attribute field must match :other.',
+    'size' => [
+        'array' => 'The :attribute field must contain :size items.',
+        'file' => 'The :attribute field must be :size kilobytes.',
+        'numeric' => 'The :attribute field must be :size.',
+        'string' => 'The :attribute field must be :size characters.',
+    ],
+    'starts_with' => 'The :attribute field must start with one of the following: :values.',
+    'string' => 'The :attribute field must be a string.',
+    'timezone' => 'The :attribute field must be a valid timezone.',
+    'unique' => 'The :attribute has already been taken.',
+    'uploaded' => 'The :attribute failed to upload.',
+    'uppercase' => 'The :attribute field must be uppercase.',
+    'url' => 'The :attribute field must be a valid URL.',
+    'ulid' => 'The :attribute field must be a valid ULID.',
+    'uuid' => 'The :attribute field must be a valid UUID.',
+
+    /*
+    |--------------------------------------------------------------------------
+    | Custom Validation Language Lines
+    |--------------------------------------------------------------------------
+    |
+    | Here you may specify custom validation messages for attributes using the
+    | convention "attribute.rule" to name the lines. This makes it quick to
+    | specify a specific custom language line for a given attribute rule.
+    |
+    */
+
+    'custom' => [
+        'attribute-name' => [
+            'rule-name' => 'custom-message',
+        ],
+    ],
+
+    /*
+    |--------------------------------------------------------------------------
+    | Custom Validation Attributes
+    |--------------------------------------------------------------------------
+    |
+    | The following language lines are used to swap our attribute placeholder
+    | with something more reader friendly such as "E-Mail Address" instead
+    | of "email". This simply helps us make our message more expressive.
+    |
+    */
+
+    'attributes' => [],
+
+];
diff --git a/public/sitemap.xml b/public/sitemap.xml
new file mode 100644
index 0000000..cb0e8f3
--- /dev/null
+++ b/public/sitemap.xml
@@ -0,0 +1,255 @@
+
+
+    
+    http://laravel-core.test
+    2026-02-16T00:00:00+00:00
+            
+    
+    http://laravel-core.test/pages/about
+    2026-02-16T00:00:00+00:00
+            
+    
+    http://laravel-core.test/pages/contact
+    2026-02-16T00:00:00+00:00
+            
+    
+    http://laravel-core.test/blog?category=sunt-est-quis-iste-natus-nisi-aliquid-est-porro
+    2026-02-16T00:00:00+00:00
+            
+    
+    http://laravel-core.test/blog?category=maxime-aliquid-blanditiis-a-consequatur-et-eaque-sunt-consectetur
+    2026-02-16T00:00:00+00:00
+            
+    
+    http://laravel-core.test/blog?category=rem-odio-sunt-nihil-ipsum-similique-placeat-vel
+    2026-02-16T00:00:00+00:00
+            
+    
+    http://laravel-core.test/blog?category=non-qui-illo-quia
+    2026-02-16T00:00:00+00:00
+            
+    
+    http://laravel-core.test/blog?category=enim-perferendis-rerum-impedit-alias-id-et-vel-ut
+    2026-02-16T00:00:00+00:00
+            
+    
+    http://laravel-core.test/blog?category=et-esse-et-animi-deleniti-neque-corporis-voluptatibus
+    2026-02-16T00:00:00+00:00
+            
+    
+    http://laravel-core.test/blog?category=alias-provident-autem-blanditiis-vitae
+    2026-02-16T00:00:00+00:00
+            
+    
+    http://laravel-core.test/blog?category=et-et-esse-alias-et-aut
+    2026-02-16T00:00:00+00:00
+            
+    
+    http://laravel-core.test/blog?category=tempore-eum-quos-corrupti-maiores-qui-voluptatem
+    2026-02-16T00:00:00+00:00
+            
+    
+    http://laravel-core.test/blog?category=quaerat-minus-totam-dicta-voluptatibus-asperiores-repellendus
+    2026-02-16T00:00:00+00:00
+            
+    
+    http://laravel-core.test/blog/pariatur-est-occaecati-at-corrupti
+    2026-02-16T00:00:00+00:00
+            
+    
+    http://laravel-core.test/blog/ut-debitis-ratione-sed-et
+    2026-02-16T00:00:00+00:00
+            
+    
+    http://laravel-core.test/blog/consequuntur-voluptas-vero-qui-quaerat-eum-dolores-voluptas
+    2026-02-16T00:00:00+00:00
+            
+    
+    http://laravel-core.test/blog/repudiandae-et-possimus-est-provident-minima-consequatur-labore
+    2026-02-16T00:00:00+00:00
+            
+    
+    http://laravel-core.test/blog/similique-sit-perferendis-expedita-molestias
+    2026-02-16T00:00:00+00:00
+            
+    
+    http://laravel-core.test/blog/mollitia-sit-iusto-vitae-saepe-enim-laudantium
+    2026-02-16T00:00:00+00:00
+            
+    
+    http://laravel-core.test/blog/impedit-incidunt-sint-voluptatem-minima-placeat-saepe-enim-sint
+    2026-02-16T00:00:00+00:00
+            
+    
+    http://laravel-core.test/blog/ex-et-quia-consectetur
+    2026-02-16T00:00:00+00:00
+            
+    
+    http://laravel-core.test/blog/quia-distinctio-eveniet-amet-vitae-velit-omnis-voluptatum
+    2026-02-16T00:00:00+00:00
+            
+    
+    http://laravel-core.test/blog/neque-rerum-quaerat-expedita-natus-rerum
+    2026-02-16T00:00:00+00:00
+            
+    
+    http://laravel-core.test/blog/id-reprehenderit-unde-nihil-dolorem
+    2026-02-16T00:00:00+00:00
+            
+    
+    http://laravel-core.test/blog/quia-dolor-aut-iusto-commodi-voluptates-fugit
+    2026-02-16T00:00:00+00:00
+            
+    
+    http://laravel-core.test/blog/aut-officia-repellat-quia-cumque
+    2026-02-16T00:00:00+00:00
+            
+    
+    http://laravel-core.test/blog/consequatur-laboriosam-nostrum-aut-amet-quos-libero
+    2026-02-16T00:00:00+00:00
+            
+    
+    http://laravel-core.test/blog/et-eos-doloribus-libero-nostrum-impedit-dolorum
+    2026-02-16T00:00:00+00:00
+            
+    
+    http://laravel-core.test/blog/qui-corporis-rerum-tempore-fugit
+    2026-02-16T00:00:00+00:00
+            
+    
+    http://laravel-core.test/blog/quibusdam-voluptates-molestiae-sit
+    2026-02-16T00:00:00+00:00
+            
+    
+    http://laravel-core.test/blog/recusandae-aut-non-unde-ut-sed-eveniet-architecto
+    2026-02-16T00:00:00+00:00
+            
+    
+    http://laravel-core.test/blog/quia-distinctio-quibusdam-laboriosam-laboriosam-quasi-ut-ipsam
+    2026-02-16T00:00:00+00:00
+            
+    
+    http://laravel-core.test/blog/voluptatem-voluptatem-corporis-voluptatem-assumenda-vitae-rerum
+    2026-02-16T00:00:00+00:00
+            
+    
+    http://laravel-core.test/blog/odio-qui-ipsum-facere-et-quam-labore
+    2026-02-16T00:00:00+00:00
+            
+    
+    http://laravel-core.test/blog/quia-ipsa-minus-sed
+    2026-02-16T00:00:00+00:00
+            
+    
+    http://laravel-core.test/blog/accusantium-quaerat-exercitationem-earum-vitae-fugiat
+    2026-02-16T00:00:00+00:00
+            
+    
+    http://laravel-core.test/blog/facilis-pariatur-ut-quis-dolorum-consequatur-debitis-minima-incidunt
+    2026-02-16T00:00:00+00:00
+            
+    
+    http://laravel-core.test/blog/possimus-corporis-alias-quod-vero-culpa-qui
+    2026-02-16T00:00:00+00:00
+            
+    
+    http://laravel-core.test/blog/sint-qui-rerum-deleniti-consequatur-autem
+    2026-02-16T00:00:00+00:00
+            
+    
+    http://laravel-core.test/blog/et-voluptas-aut-et-voluptate-perferendis-voluptatem
+    2026-02-16T00:00:00+00:00
+            
+    
+    http://laravel-core.test/blog/est-unde-expedita-aliquid-ut-illum
+    2026-02-16T00:00:00+00:00
+            
+    
+    http://laravel-core.test/blog/at-ut-omnis-quia-nisi-in-qui-molestias
+    2026-02-16T00:00:00+00:00
+            
+    
+    http://laravel-core.test/blog/in-et-praesentium-quia-maiores
+    2026-02-16T00:00:00+00:00
+            
+    
+    http://laravel-core.test/blog/aliquam-sunt-perferendis-esse-qui
+    2026-02-16T00:00:00+00:00
+            
+    
+    http://laravel-core.test/blog/ut-deleniti-illum-provident-animi-sit-et-dolore
+    2026-02-16T00:00:00+00:00
+            
+    
+    http://laravel-core.test/blog/libero-enim-quia-et-nihil-id
+    2026-02-16T00:00:00+00:00
+            
+    
+    http://laravel-core.test/blog/quis-corporis-tempora-omnis-soluta
+    2026-02-16T00:00:00+00:00
+            
+    
+    http://laravel-core.test/blog/voluptates-voluptatem-cumque-sapiente-reiciendis-voluptatem-reprehenderit-non
+    2026-02-16T00:00:00+00:00
+            
+    
+    http://laravel-core.test/blog/fuga-et-quis-est
+    2026-02-16T00:00:00+00:00
+            
+    
+    http://laravel-core.test/blog/animi-voluptatem-iste-et-voluptatum-quia-qui-alias
+    2026-02-16T00:00:00+00:00
+            
+    
+    http://laravel-core.test/blog/sint-nam-ex-tempore-necessitatibus
+    2026-02-16T00:00:00+00:00
+            
+    
+    http://laravel-core.test/blog/mollitia-odio-eos-modi-consequuntur
+    2026-02-16T00:00:00+00:00
+            
+    
+    http://laravel-core.test/blog/voluptas-repudiandae-numquam-officia-aperiam-rerum-praesentium-et-est
+    2026-02-16T00:00:00+00:00
+            
+    
+    http://laravel-core.test/blog/similique-saepe-at-deleniti-repellendus-possimus-laboriosam
+    2026-02-16T00:00:00+00:00
+            
+    
+    http://laravel-core.test/blog/inventore-beatae-officia-dolorem-vero-suscipit-earum-officiis
+    2026-02-16T00:00:00+00:00
+            
+    
+    http://laravel-core.test/blog/earum-quasi-et-sequi-soluta
+    2026-02-16T00:00:00+00:00
+            
+    
+    http://laravel-core.test/blog/alias-voluptatem-totam-quibusdam
+    2026-02-16T00:00:00+00:00
+            
+    
+    http://laravel-core.test/blog/et-aliquid-aut-ducimus-ratione-voluptatum-voluptatem-minima
+    2026-02-16T00:00:00+00:00
+            
+    
+    http://laravel-core.test/blog/aut-explicabo-eos-sunt-possimus-sunt-unde
+    2026-02-16T00:00:00+00:00
+            
+    
+    http://laravel-core.test/blog/porro-amet-totam-illo-aliquam-quos-quae-voluptatem
+    2026-02-16T00:00:00+00:00
+            
+    
+    http://laravel-core.test/blog/ut-laudantium-consequatur-voluptates-vero-dignissimos
+    2026-02-16T00:00:00+00:00
+            
+    
+    http://laravel-core.test/blog/quo-consequatur-tempora-et-saepe-repudiandae-pariatur
+    2026-02-16T00:00:00+00:00
+            
+    
+    http://laravel-core.test/blog/est-repudiandae-incidunt-aspernatur-natus-illum
+    2026-02-16T00:00:00+00:00
+            
+
diff --git a/resources/css/app.css b/resources/css/app.css
deleted file mode 100644
index d4b5078..0000000
--- a/resources/css/app.css
+++ /dev/null
@@ -1 +0,0 @@
-@import 'tailwindcss';
diff --git a/resources/css/default/app.css b/resources/css/default/app.css
new file mode 100644
index 0000000..9c00171
--- /dev/null
+++ b/resources/css/default/app.css
@@ -0,0 +1,10 @@
+@import 'tailwindcss';
+@import './theme.css';
+/** 
+ * TODO Remove this file when we have a proper multi-domain architecture 
+* ! DEPRECATED
+* ? Test
+* * Test
+* @param myParam - Test parameter
+*/
+
diff --git a/resources/css/default/theme.css b/resources/css/default/theme.css
new file mode 100644
index 0000000..63b0e50
--- /dev/null
+++ b/resources/css/default/theme.css
@@ -0,0 +1,72 @@
+
+@theme {
+    --font-sans: 'Instrument Sans', ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji',
+    'Segoe UI Symbol', 'Noto Color Emoji';
+    --color-brand-primary: #A3160B;
+    --color-brand-primary-muted: #f46358;
+    --color-brand-secondary: #F69A13;
+    --color-brand-secondary-muted: #faca84;
+    --color-base: #444444;
+    --color-muted: #696969;
+    --color-inverted: #e9ebfc;
+    --color-accent: #000000;
+    --color-heading: #A3160B;
+    --color-h1: #A3160B;
+    --color-link: #A3160B;
+    --color-link-hover: #7f1e1e;
+    --color-btn: #A3160B;
+    --color-btn-hover: #A3160B;
+    --color-input: #000000;
+    --color-input-focus: #7f1e1e;
+    --color-header: #444444;
+    --color-header-muted: #696969;
+    --color-footer:  #771008;
+    --color-footer-muted: #f46358;
+    --color-supplementary: #091843;
+    --color-supplementary-muted: #0f2970;
+    --color-info: #1e429f;
+    --color-success: #03543f;
+    --color-warning: #723b13;
+    --color-danger: #9b1c1c;
+    --color-featured: #0a0a0a;
+    --color-blog: #0a0a0a;
+    --color-place: #0a0a0a;
+    --color-album: #0a0a0a;
+    --color-bor-base: #dbdbdb;
+    --color-bor-muted: #f4f6fd;
+    --color-bor-primary: #A3160B;
+    --color-bor-secondary:#023859;
+    --color-bor-btn: #dbdbdb;
+    --color-bor-input: #dbdbdb;
+    --color-bor-input-focus: #A3160B;
+    --color-bor-footer:#fde9e7;
+    --color-bor-supplementary: #f4f6fd;
+    --color-bor-info: #a4cafe;
+    --color-bor-success: #84e1bc;
+    --color-bor-warning: #faca15;
+    --color-bor-danger: #f8b4b4;
+    --color-bcg-body: #FFFFFF;
+    --color-bcg-base: #F7F8F2;
+    --color-bcg-primary:#A3160B;
+    --color-bcg-primary-muted: #bf5e5e;
+    --color-bcg-secondary:#F69A13;
+    --color-bcg-secondary-muted:#faca84;
+    --color-bcg-btn: #F7F8F2;
+    --color-bcg-btn-hover: #FFFFFF;
+    --color-bcg-input: #fef4e6;
+    --color-bcg-info: #ebf5ff;
+    --color-bcg-success: #f3faf7;
+    --color-bcg-warning: #fdfdea;
+    --color-bcg-danger: #fdf2f2;
+    --color-bcg-accent: #e9eefc;
+    --color-bcg-header: #FFFFFF;
+    --color-bcg-jumbotron: #F7F8F2;
+    --color-bcg-supplementary: #F7F8F2;
+    --color-bcg-footer: #FFFFFF;
+    --color-bcg-featured: #F7F8F2;
+    --color-bcg-article: #fef4e6;
+    --color-bcg-blog: #F7F8F2;
+    --color-bcg-place: #F7F8F2;
+    --color-bcg-album: #F7F8F2;
+    --color-icon: #ffffff;
+}
\ No newline at end of file
diff --git a/resources/css/vades/app.css b/resources/css/vades/app.css
new file mode 100644
index 0000000..9c00171
--- /dev/null
+++ b/resources/css/vades/app.css
@@ -0,0 +1,10 @@
+@import 'tailwindcss';
+@import './theme.css';
+/** 
+ * TODO Remove this file when we have a proper multi-domain architecture 
+* ! DEPRECATED
+* ? Test
+* * Test
+* @param myParam - Test parameter
+*/
+
diff --git a/resources/css/vades/theme.css b/resources/css/vades/theme.css
new file mode 100644
index 0000000..63b0e50
--- /dev/null
+++ b/resources/css/vades/theme.css
@@ -0,0 +1,72 @@
+
+@theme {
+    --font-sans: 'Instrument Sans', ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji',
+    'Segoe UI Symbol', 'Noto Color Emoji';
+    --color-brand-primary: #A3160B;
+    --color-brand-primary-muted: #f46358;
+    --color-brand-secondary: #F69A13;
+    --color-brand-secondary-muted: #faca84;
+    --color-base: #444444;
+    --color-muted: #696969;
+    --color-inverted: #e9ebfc;
+    --color-accent: #000000;
+    --color-heading: #A3160B;
+    --color-h1: #A3160B;
+    --color-link: #A3160B;
+    --color-link-hover: #7f1e1e;
+    --color-btn: #A3160B;
+    --color-btn-hover: #A3160B;
+    --color-input: #000000;
+    --color-input-focus: #7f1e1e;
+    --color-header: #444444;
+    --color-header-muted: #696969;
+    --color-footer:  #771008;
+    --color-footer-muted: #f46358;
+    --color-supplementary: #091843;
+    --color-supplementary-muted: #0f2970;
+    --color-info: #1e429f;
+    --color-success: #03543f;
+    --color-warning: #723b13;
+    --color-danger: #9b1c1c;
+    --color-featured: #0a0a0a;
+    --color-blog: #0a0a0a;
+    --color-place: #0a0a0a;
+    --color-album: #0a0a0a;
+    --color-bor-base: #dbdbdb;
+    --color-bor-muted: #f4f6fd;
+    --color-bor-primary: #A3160B;
+    --color-bor-secondary:#023859;
+    --color-bor-btn: #dbdbdb;
+    --color-bor-input: #dbdbdb;
+    --color-bor-input-focus: #A3160B;
+    --color-bor-footer:#fde9e7;
+    --color-bor-supplementary: #f4f6fd;
+    --color-bor-info: #a4cafe;
+    --color-bor-success: #84e1bc;
+    --color-bor-warning: #faca15;
+    --color-bor-danger: #f8b4b4;
+    --color-bcg-body: #FFFFFF;
+    --color-bcg-base: #F7F8F2;
+    --color-bcg-primary:#A3160B;
+    --color-bcg-primary-muted: #bf5e5e;
+    --color-bcg-secondary:#F69A13;
+    --color-bcg-secondary-muted:#faca84;
+    --color-bcg-btn: #F7F8F2;
+    --color-bcg-btn-hover: #FFFFFF;
+    --color-bcg-input: #fef4e6;
+    --color-bcg-info: #ebf5ff;
+    --color-bcg-success: #f3faf7;
+    --color-bcg-warning: #fdfdea;
+    --color-bcg-danger: #fdf2f2;
+    --color-bcg-accent: #e9eefc;
+    --color-bcg-header: #FFFFFF;
+    --color-bcg-jumbotron: #F7F8F2;
+    --color-bcg-supplementary: #F7F8F2;
+    --color-bcg-footer: #FFFFFF;
+    --color-bcg-featured: #F7F8F2;
+    --color-bcg-article: #fef4e6;
+    --color-bcg-blog: #F7F8F2;
+    --color-bcg-place: #F7F8F2;
+    --color-bcg-album: #F7F8F2;
+    --color-icon: #ffffff;
+}
\ No newline at end of file
diff --git a/resources/views/components/default/article/index.blade.php b/resources/views/components/default/article/index.blade.php
new file mode 100644
index 0000000..6f98d59
--- /dev/null
+++ b/resources/views/components/default/article/index.blade.php
@@ -0,0 +1,51 @@
+@php
+    if(isset($page->user)){
+        $page->user = null;
+    }
+@endphp
+@inject('carbon', 'Carbon\Carbon')
+
+    
+        
+            
+        
+    
+    
+ @foreach($articles as $item) + @php($coverImage = !empty($item->cover_image_url) ? $item->cover_image_url : config('myapp.image.placeholder.article')) + + + + {{ $item->title}} + + + +

{{ $item->title }}

+

{{ $carbon::parse($item->created_at)->format('Y-m-d') }}

+ +
+ {{ $item->description }} +
+
+ +
+ {{__('app.nav.readMore')}} +
+
+
+
+ + @endforeach +
+
+ {!! $articles->links() !!} + + {{-- --}} +
+
\ No newline at end of file diff --git a/resources/views/components/default/article/show-default.blade.php b/resources/views/components/default/article/show-default.blade.php new file mode 100644 index 0000000..1a36bb3 --- /dev/null +++ b/resources/views/components/default/article/show-default.blade.php @@ -0,0 +1,34 @@ + + + + + + + + + @if(!empty($page->featured_image_url)) +
+ {{ $page->title }} +
The Alps in early winter.
+
+ @endif +
+ {!! $markdown !!} +
+ @if($page->tags->isNotEmpty()) +
+ @foreach($page->tags as $tag) + + {{ $tag->name }} + + @endforeach +
+ @endif +
+ + +
+
\ No newline at end of file diff --git a/resources/views/components/default/data/nav.php b/resources/views/components/default/data/nav.php new file mode 100644 index 0000000..1c47a51 --- /dev/null +++ b/resources/views/components/default/data/nav.php @@ -0,0 +1,100 @@ + [ + 'name' => 'home', + 'label' => 'home', + 'uri' => 'home', + 'isExternal' => false, + ], + 'articleIndex' => [ + 'name' => 'articleIndex', + 'label' => 'app.nav.articleIndex', + 'uri' => 'blog', + 'isExternal' => false, + ], + 'articleShow' => [ + 'name' => 'articleShow', + 'label' => 'app.nav.articleShow', + 'uri' => 'blog/item-slug', + 'isExternal' => false, + 'params' => ['slug' => 'item-slug'] + ], + 'tagArticle' => [ + 'name' => 'tagArticle', + 'label' => 'app.nav.tags', + 'uri' => 'blog/tags', + 'isExternal' => false, + ], + 'placeList' => [ + 'name' => 'placeList', + 'label' => 'places', + 'uri' => 'places', + 'isExternal' => false, + + ], + 'placeItem' => [ + 'name' => 'placeItem', + 'label' => 'placeItem', + 'uri' => 'places/place-item', + 'isExternal' => false, + 'params' => ['placeId' => 'place-item-slug'], + ], + 'placeCategoryList' => [ + 'name' => 'placeCategoryList', + 'label' => 'placeCategoryList', + 'uri' => 'places/categories', + 'isExternal' => false, + ], + 'albumList' => [ + 'name' => 'albumList', + 'label' => 'albumList', + 'uri' => 'albums', + 'isExternal' => false, + ], + 'albumEventList' => [ + 'name' => 'albumEventList', + 'label' => 'photoGallery', + 'uri' => 'albums/album-id', + 'isExternal' => false, + 'params' => ['albumId' => env('MY_PROJECT_NAME')], + ], + 'albumGallery' => [ + 'name' => 'albumGallery', + 'label' => 'gallery', + 'uri' => 'albums/album-id/event-id', + 'isExternal' => false, + 'params' => ['albumId' => 'album-id', 'eventId' => 'event-id'], + ], + 'contact' => [ + 'name' => 'pageItem', + 'label' => 'app.nav.contact', + 'hasIcon' => 'contact', + 'uri' => 'contact', + 'isExternal' => false, + 'params' => ['slug' => 'contact'], + ], + 'about' => [ + 'name' => 'pageItem', + 'label' => 'app.nav.about', + 'hasIcon' => 'info-circle', + 'uri' => 'nav.about', + 'isExternal' => false, + 'params' => ['slug' => 'about'], + ], +]; + +return[ + 'slogan' => 'Laravel demo project', + 'header' => [ + $myAppNav['articleIndex'], + $myAppNav['tagArticle'], + $myAppNav['about'], + $myAppNav['contact'], + ], + 'footer' => [ + $myAppNav['articleIndex'], + $myAppNav['tagArticle'], + $myAppNav['about'], + $myAppNav['contact'], + ], +]; \ No newline at end of file diff --git a/resources/views/components/default/home/index.blade.php b/resources/views/components/default/home/index.blade.php new file mode 100644 index 0000000..daa459b --- /dev/null +++ b/resources/views/components/default/home/index.blade.php @@ -0,0 +1,8 @@ + +
+

Home

+ cover + featured + test +
+
\ No newline at end of file diff --git a/resources/views/components/default/layout.blade.php b/resources/views/components/default/layout.blade.php new file mode 100644 index 0000000..ecd0d3e --- /dev/null +++ b/resources/views/components/default/layout.blade.php @@ -0,0 +1,44 @@ + + + + + + + + {{ $title ?? config('myapp.metaTitle') }} + + + + + + + @if (file_exists(public_path('build/manifest.json')) || file_exists(public_path('hot'))) + @vite([$globalCssPath, 'resources/js/app.js']) + @else + @vite([$globalCssPath, 'resources/js/app.js']) + @endif + @livewireStyles + {{-- --}} + + +
+ + @if(isset($jumbotron) && !empty($jumbotron)) +
{{ $jumbotron }}
+ @endif +
+ {{ $slot }} +
+ @if(config('myapp.hasSupplementary')) + + @endif + + + +
+@livewireScripts + + \ No newline at end of file diff --git a/resources/views/components/default/page/index.blade.php b/resources/views/components/default/page/index.blade.php new file mode 100644 index 0000000..6be1781 --- /dev/null +++ b/resources/views/components/default/page/index.blade.php @@ -0,0 +1,29 @@ + +@php + if(isset($page->user)){ + $page->user = null; + } +@endphp + + + + + + + + @if(!empty($page->featured_image_url)) +
+ {{ $page->title }} +
The Alps in early winter.
+
+ @endif +
+ {!! $renderedBody !!} +
+ @if(!empty($page->livewireWidget) && $page->livewireWidget === 'contact-form') + + @endif +
\ No newline at end of file diff --git a/resources/views/components/default/partials/footer/brand.blade.php b/resources/views/components/default/partials/footer/brand.blade.php new file mode 100644 index 0000000..33ff35c --- /dev/null +++ b/resources/views/components/default/partials/footer/brand.blade.php @@ -0,0 +1,3 @@ +
class([])}}> + © {{ date('Y') }} {{ config('app.name') }} {{ config('myapp.projectSlug') }} +
\ No newline at end of file diff --git a/resources/views/components/default/partials/footer/index.blade.php b/resources/views/components/default/partials/footer/index.blade.php new file mode 100644 index 0000000..a5b7bea --- /dev/null +++ b/resources/views/components/default/partials/footer/index.blade.php @@ -0,0 +1,6 @@ +
+ +
\ No newline at end of file diff --git a/resources/views/components/default/partials/footer/nav.blade.php b/resources/views/components/default/partials/footer/nav.blade.php new file mode 100644 index 0000000..23831d0 --- /dev/null +++ b/resources/views/components/default/partials/footer/nav.blade.php @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/resources/views/components/default/partials/header/brand.blade.php b/resources/views/components/default/partials/header/brand.blade.php new file mode 100644 index 0000000..09f9eec --- /dev/null +++ b/resources/views/components/default/partials/header/brand.blade.php @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/resources/views/components/default/partials/header/index.blade.php b/resources/views/components/default/partials/header/index.blade.php new file mode 100644 index 0000000..5cad4a4 --- /dev/null +++ b/resources/views/components/default/partials/header/index.blade.php @@ -0,0 +1,21 @@ + \ No newline at end of file diff --git a/resources/views/components/default/partials/header/nav.blade.php b/resources/views/components/default/partials/header/nav.blade.php new file mode 100644 index 0000000..861541b --- /dev/null +++ b/resources/views/components/default/partials/header/nav.blade.php @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/resources/views/components/default/partials/page-header.blade.php b/resources/views/components/default/partials/page-header.blade.php new file mode 100644 index 0000000..0da99ba --- /dev/null +++ b/resources/views/components/default/partials/page-header.blade.php @@ -0,0 +1,26 @@ +@inject('carbon', 'Carbon\Carbon') + + @if(empty($page->featured_image_url) && !empty($page->cover_image_url)) + + {{ $page->title }} + + + @endif + + + {{ $page->title }} + + + {{ $page->subtitle ?? null }} + + + {{ $page->excerpt ?? null }} + + @if(isset($page->user->name)) + + {{$page->user->name}} + {{ $carbon::parse($page->createdAt)->format('Y-m-d') }} + + @endif + + \ No newline at end of file diff --git a/resources/views/components/default/partials/supplementary/index.blade.php b/resources/views/components/default/partials/supplementary/index.blade.php new file mode 100644 index 0000000..4ba21fe --- /dev/null +++ b/resources/views/components/default/partials/supplementary/index.blade.php @@ -0,0 +1,10 @@ + +
+
+ suplementary + {{-- + + --}} +
+ +
\ No newline at end of file diff --git a/resources/views/components/default/tag/index.blade.php b/resources/views/components/default/tag/index.blade.php new file mode 100644 index 0000000..8bd833a --- /dev/null +++ b/resources/views/components/default/tag/index.blade.php @@ -0,0 +1,24 @@ +@php + if(isset($page->user)){ + $page->user = null; + } +@endphp + + + + + + + @foreach($tags as $tag) + + {{ $tag->name }} + {{ $tag->contents_count }} + + + + + @endforeach + + \ No newline at end of file diff --git a/resources/views/sites/myprompties/home.blade.php b/resources/views/components/myprompties/home.blade.php similarity index 100% rename from resources/views/sites/myprompties/home.blade.php rename to resources/views/components/myprompties/home.blade.php diff --git a/resources/views/components/shared/alert.blade.php b/resources/views/components/shared/alert.blade.php new file mode 100644 index 0000000..edc70ee --- /dev/null +++ b/resources/views/components/shared/alert.blade.php @@ -0,0 +1,4 @@ +
class(['alert-message'])}} + role="alert"> +
{{ $slot }}
+
\ No newline at end of file diff --git a/resources/views/components/shared/badge.blade.php b/resources/views/components/shared/badge.blade.php new file mode 100644 index 0000000..478eb44 --- /dev/null +++ b/resources/views/components/shared/badge.blade.php @@ -0,0 +1,9 @@ +class(['relative inline-flex bg-skin-base text-skin-base font-medium me-2 px-2.5 py-0.5 rounded dark:bg-blue-900 dark:text-blue-300'])}}> + + {{ $slot }} + + + @isset($notify) + attributes->class(['absolute inline-flex items-center justify-center w-6 h-6 text-xs font-bold text-white bg-red-500 border-2 border-white rounded-full -top-2 -end-2 dark:border-gray-900'])}}>{{$notify}} + @endisset + \ No newline at end of file diff --git a/resources/views/components/shared/card.blade.php b/resources/views/components/shared/card.blade.php new file mode 100644 index 0000000..44ad783 --- /dev/null +++ b/resources/views/components/shared/card.blade.php @@ -0,0 +1,13 @@ +
class(['flex flex-col justify-between h-full card'])}}> + @isset($header) +
attributes->class([])}}>{{$header}}
+ @endisset + + @isset($body) +
attributes->class(['flex-grow'])}}>{{$body}}
+ @endisset + + @isset($footer) +
attributes->class(['mt-auto'])}}>{{$footer}}
+ @endisset +
\ No newline at end of file diff --git a/resources/views/components/shared/categories-dropdown.blade.php b/resources/views/components/shared/categories-dropdown.blade.php new file mode 100644 index 0000000..9862a46 --- /dev/null +++ b/resources/views/components/shared/categories-dropdown.blade.php @@ -0,0 +1,39 @@ + +@props(['type' => 'place','route' => 'placeList','label' => 'placeCategoryList']) +@if(isset($categories) && count($categories) > 0) + + + + {{ __($label) }} + + + + + + + + + + +@endif \ No newline at end of file diff --git a/resources/views/components/shared/dropdown.blade.php b/resources/views/components/shared/dropdown.blade.php new file mode 100644 index 0000000..c3eb2df --- /dev/null +++ b/resources/views/components/shared/dropdown.blade.php @@ -0,0 +1,22 @@ +
class(['relative'])}}> + @isset($header) +
attributes->class([])}} + @click="open = !open" + @click.away="open = false" + style="cursor:pointer;"> + {{$header}} +
+ @endisset + + @isset($body) + +
attributes->class(['absolute left-0 top-full mt-2 w-64 bg-white shadow-lg rounded z-50 max-h-128 overflow-auto divide-y divide-gray-100'])}} + x-show="open" + x-transition + style="display: none;"> + + {{$body}} + +
+ @endisset +
\ No newline at end of file diff --git a/resources/views/components/shared/gtag.blade.php b/resources/views/components/shared/gtag.blade.php new file mode 100644 index 0000000..87b6976 --- /dev/null +++ b/resources/views/components/shared/gtag.blade.php @@ -0,0 +1,10 @@ +@if(config('myapp.gatMeasurementId')) + + +@endif \ No newline at end of file diff --git a/resources/views/components/shared/iframe.blade.php b/resources/views/components/shared/iframe.blade.php new file mode 100644 index 0000000..dd6c9c1 --- /dev/null +++ b/resources/views/components/shared/iframe.blade.php @@ -0,0 +1,9 @@ +@props(['src']) +
class(['relative pb-[56.25%] pt-8 h-0 overflow-hidden'])}}> + +
\ No newline at end of file diff --git a/resources/views/components/shared/img-svg.blade.php b/resources/views/components/shared/img-svg.blade.php new file mode 100644 index 0000000..1ef5a57 --- /dev/null +++ b/resources/views/components/shared/img-svg.blade.php @@ -0,0 +1,10 @@ +@php + + $img = $img ?? ''; + $fullPath = storage_path('app/public/images/svg/' . $img . '.svg'); +@endphp + +@if(file_exists($fullPath)) + {!! file_get_contents($fullPath) !!} + @endif + \ No newline at end of file diff --git a/resources/views/components/shared/jumbotron.blade.php b/resources/views/components/shared/jumbotron.blade.php new file mode 100644 index 0000000..cf7c738 --- /dev/null +++ b/resources/views/components/shared/jumbotron.blade.php @@ -0,0 +1,6 @@ + +
class(['bg-skin-jumbotron jumbotron'])}}> +
+ {{$slot}} +
+
\ No newline at end of file diff --git a/resources/views/components/shared/lightbox.blade.php b/resources/views/components/shared/lightbox.blade.php new file mode 100644 index 0000000..015bc8f --- /dev/null +++ b/resources/views/components/shared/lightbox.blade.php @@ -0,0 +1,99 @@ +@props(['images']) +@props(['title']) +@isset($images) +
+
+ + +
+ @foreach($images as $index => $item) + + + {{ $item->title}} + + + @endforeach +
+ + +
+
+@endisset \ No newline at end of file diff --git a/resources/views/components/shared/modal.blade.php b/resources/views/components/shared/modal.blade.php new file mode 100644 index 0000000..2d38451 --- /dev/null +++ b/resources/views/components/shared/modal.blade.php @@ -0,0 +1,46 @@ + + + + \ No newline at end of file diff --git a/resources/views/components/shared/page-header.blade.php b/resources/views/components/shared/page-header.blade.php new file mode 100644 index 0000000..52d7fcb --- /dev/null +++ b/resources/views/components/shared/page-header.blade.php @@ -0,0 +1,22 @@ +
class(['flex gap-4 flex-col md:flex-row md:items-start mb-4'])}}> + @if(isset($image)) +
attributes->class([])}}>{{$image}}
+ @endif +
+ @if(!empty($title)) +

attributes->class(['text-3xl mb-2'])}}> + {{ $title }} +

+ @endif + @if(!empty($subtitle)) +

attributes->class(['text-xl mb-2'])}}>{{ $subtitle }}

+ @endif + @if(!empty($description)) +
attributes->class(['font-bold my-2'])}}>{{ $description }}
+ @endif + @if(!empty($info)) +
attributes->class(['text-sm mb-3'])}}>{{ $info }}
+ @endif +
+ +
\ No newline at end of file diff --git a/resources/views/components/shared/pagination.blade.php b/resources/views/components/shared/pagination.blade.php new file mode 100644 index 0000000..afade91 --- /dev/null +++ b/resources/views/components/shared/pagination.blade.php @@ -0,0 +1,35 @@ + diff --git a/resources/views/components/shared/panel.blade.php b/resources/views/components/shared/panel.blade.php new file mode 100644 index 0000000..0a98969 --- /dev/null +++ b/resources/views/components/shared/panel.blade.php @@ -0,0 +1,9 @@ +
class(['sm:flex sm:flex-row items-start gap-2 md:gap-4'])}}> + @isset($header) +
attributes->class(['sm:w-1/3'])}}>{{$header}}
+ @endisset + + @isset($body) +
attributes->class(['sm:w-2/3'])}}>{{$body}}
+ @endisset +
\ No newline at end of file diff --git a/resources/views/components/shared/post-image.blade.php b/resources/views/components/shared/post-image.blade.php new file mode 100644 index 0000000..f848c69 --- /dev/null +++ b/resources/views/components/shared/post-image.blade.php @@ -0,0 +1,18 @@ +@props(['postImage']) +
class([])}}> + @if(!empty($postImage->title)) +

+ {{ $postImage->title }} +

+ @endif + {{ $postImage->title }} + @if(!empty($postImage->description)) +
+ {{ $postImage->description }} +
+ @endif +
\ No newline at end of file diff --git a/resources/views/components/shared/prev-next.blade.php b/resources/views/components/shared/prev-next.blade.php new file mode 100644 index 0000000..9886c37 --- /dev/null +++ b/resources/views/components/shared/prev-next.blade.php @@ -0,0 +1,20 @@ + + \ No newline at end of file diff --git a/resources/views/components/vades/data/nav.php b/resources/views/components/vades/data/nav.php new file mode 100644 index 0000000..8cce104 --- /dev/null +++ b/resources/views/components/vades/data/nav.php @@ -0,0 +1,97 @@ + [ + 'name' => 'home', + 'label' => 'home', + 'uri' => 'home', + 'isExternal' => false, + ], + 'blogList' => [ + 'name' => 'blogList', + 'label' => 'blogList', + 'uri' => 'blog', + 'isExternal' => false, + ], + 'blogItem' => [ + 'name' => 'blogItem', + 'label' => 'blogItem', + 'uri' => 'blog/item-slug', + 'isExternal' => false, + 'params' => ['postId' => 'item-slug'] + ], + 'blogCategoryList' => [ + 'name' => 'blogCategoryList', + 'label' => 'blogCategoryList', + 'uri' => 'blog/categories', + 'isExternal' => false, + ], + 'blogTagList' => [ + 'name' => 'blogTagList', + 'label' => 'blogTagList', + 'uri' => 'blog/tags', + 'isExternal' => false, + ], + 'placeList' => [ + 'name' => 'placeList', + 'label' => 'places', + 'uri' => 'places', + 'isExternal' => false, + + ], + 'placeItem' => [ + 'name' => 'placeItem', + 'label' => 'placeItem', + 'uri' => 'places/place-item', + 'isExternal' => false, + 'params' => ['placeId' => 'place-item-slug'], + ], + 'placeCategoryList' => [ + 'name' => 'placeCategoryList', + 'label' => 'placeCategoryList', + 'uri' => 'places/categories', + 'isExternal' => false, + ], + 'albumList' => [ + 'name' => 'albumList', + 'label' => 'albumList', + 'uri' => 'albums', + 'isExternal' => false, + ], + 'albumEventList' => [ + 'name' => 'albumEventList', + 'label' => 'photoGallery', + 'uri' => 'albums/album-id', + 'isExternal' => false, + 'params' => ['albumId' => env('MY_PROJECT_NAME')], + ], + 'albumGallery' => [ + 'name' => 'albumGallery', + 'label' => 'gallery', + 'uri' => 'albums/album-id/event-id', + 'isExternal' => false, + 'params' => ['albumId' => 'album-id', 'eventId' => 'event-id'], + ], + 'contact' => [ + 'name' => 'pageItem', + 'label' => 'contact', + 'hasIcon' => 'contact', + 'uri' => 'contact', + 'isExternal' => false, + 'params' => ['pageId' => 'contact'], + ], + 'about' => [ + 'name' => 'pageItem', + 'label' => 'about', + 'hasIcon' => 'info-circle', + 'uri' => 'about', + 'isExternal' => false, + 'params' => ['pageId' => 'about'], + ], +]; + +return[ + 'headerNav' => [ + $myAppNav['about'], + $myAppNav['contact'], + ], +]; \ No newline at end of file diff --git a/resources/views/sites/vades/home.blade.php b/resources/views/components/vades/home.blade.php similarity index 100% rename from resources/views/sites/vades/home.blade.php rename to resources/views/components/vades/home.blade.php diff --git "a/resources/views/components/widgets/\342\232\241categories-dropdown/categories-dropdown.blade.php" "b/resources/views/components/widgets/\342\232\241categories-dropdown/categories-dropdown.blade.php" new file mode 100644 index 0000000..41c4aa8 --- /dev/null +++ "b/resources/views/components/widgets/\342\232\241categories-dropdown/categories-dropdown.blade.php" @@ -0,0 +1,34 @@ +@if($categories->isNotEmpty()) + + + + {{ __($label) }} + + + + + + + + + +@endif \ No newline at end of file diff --git "a/resources/views/components/widgets/\342\232\241categories-dropdown/categories-dropdown.php" "b/resources/views/components/widgets/\342\232\241categories-dropdown/categories-dropdown.php" new file mode 100644 index 0000000..37c1f71 --- /dev/null +++ "b/resources/views/components/widgets/\342\232\241categories-dropdown/categories-dropdown.php" @@ -0,0 +1,35 @@ +value, + string $route = 'articleIndex', + string $label = 'articleCategories', + ?string $currentCategory = null + ) { + $this->type = $type; + $this->route = $route; + $this->label = $label; + $this->currentCategory = $currentCategory ?? request()->query('category'); + } + + public function render() + { + $categories = Category::publishedByType($this->type) + ->withCount('contents')->where('contents_count','>',0)->get(); + + return view('components.widgets.⚡categories-dropdown.categories-dropdown', [ + 'categories' => $categories, + ]); + } +}; \ No newline at end of file diff --git "a/resources/views/components/widgets/\342\232\241contact-form/contact-form.blade.php" "b/resources/views/components/widgets/\342\232\241contact-form/contact-form.blade.php" new file mode 100644 index 0000000..22682f2 --- /dev/null +++ "b/resources/views/components/widgets/\342\232\241contact-form/contact-form.blade.php" @@ -0,0 +1,51 @@ +
+ @if ($errorMessage) + {{ $errorMessage }} + @endif + @if (session()->has('success')) + {{ session('success') }} + @endif +
+
+ + + @error('name') {{ $message }} @enderror +
+
+ + + @error('email') {{ $message }} @enderror +
+
+ + + @error('message') {{ $message }} @enderror +
+
+ +
+
+
\ No newline at end of file diff --git "a/resources/views/components/widgets/\342\232\241contact-form/contact-form.php" "b/resources/views/components/widgets/\342\232\241contact-form/contact-form.php" new file mode 100644 index 0000000..00e2a67 --- /dev/null +++ "b/resources/views/components/widgets/\342\232\241contact-form/contact-form.php" @@ -0,0 +1,49 @@ + 'required|min:3', + 'email' => 'required|email', + 'message' => 'required|min:5', + ]; + + public function submit(Request $request,DomainManagerService $domainManager) + { + $this->errorMessage = null; + + $this->validate(); + + // Save data + try { + Inquiry::create([ + 'project_id' =>$domainManager->getProjectId(), + 'subject' => 'Contact Form Submission', + 'name' => $this->name, + 'email' => $this->email, + 'message' => $this->message, + 'ip_address' => $request->ip(), + 'user_agent' => $request->userAgent(), + ]); + $this->reset(['name', 'email', 'message']); + + session()->flash('success', __('app.form.successContactForm')); + } catch (\Exception $e) { + $this->errorMessage = __('app.form.errorContactForm'); + } + } + + public function render() + { + return view('components.widgets.⚡contact-form.contact-form'); + } +}; \ No newline at end of file diff --git "a/resources/views/components/widgets/\342\232\241search-suggestion/search-suggestion.blade.php" "b/resources/views/components/widgets/\342\232\241search-suggestion/search-suggestion.blade.php" new file mode 100644 index 0000000..71893bc --- /dev/null +++ "b/resources/views/components/widgets/\342\232\241search-suggestion/search-suggestion.blade.php" @@ -0,0 +1,40 @@ + + + +
+
+ +
+ +
+
+ {{-- The dropdown with the search results. + It is only shown if the query is not empty and there are search results. --}} + @if(!empty($query) && !empty($results)) + + + + @endif +
\ No newline at end of file diff --git "a/resources/views/components/widgets/\342\232\241search-suggestion/search-suggestion.php" "b/resources/views/components/widgets/\342\232\241search-suggestion/search-suggestion.php" new file mode 100644 index 0000000..47e100a --- /dev/null +++ "b/resources/views/components/widgets/\342\232\241search-suggestion/search-suggestion.php" @@ -0,0 +1,98 @@ +contentType = $contentType; + $this->placeholderText = $placeholderText; + } + /** + * This method is called whenever the 'query' public property is updated. + * It performs a search for products based on the query. + */ + public function updatedQuery() + { + $this->results = Content::published() + ->where(function($query) { + $query->where('title', 'like', '%' . $this->query . '%') + ->orWhere('description', 'like', '%' . $this->query . '%'); + }) + ->whereIn('content_type', $this->contentType) + ->get(); + $this->selectedResult = 0; // Auswahl zurücksetzen bei neuer Suche + } + + public function moveSelectionDown() + { + if (count($this->results) === 0) return; + if ($this->selectedResult < count($this->results) - 1) { + $this->selectedResult++; + } + } + + public function moveSelectionUp() + { + if (count($this->results) === 0) return; + if ($this->selectedResult > 0) { + $this->selectedResult--; + } + } + + /** + * This method is called when a search result is clicked. + * It sets the query to the name of the selected product and clears the search results. + * + * @param int $id The ID of the selected product. + */ + public function selectResult($id = null) + { + try { + // Wenn kein postId übergeben wurde, wähle das aktuell selektierte + if ($id === null && isset($this->results[$this->selectedResult])) { + $id = $this->results[$this->selectedResult]->id; + } + $item = Content::find($id); + if ($item) { + + switch ($item->content_type->value) { + case ContentContentType::Page->value: + return redirect()->route('pageItem', $item->slug); + case ContentContentType::Article->value: + + return redirect()->route('articleShow', $item->slug); + case ContentContentType::Tutorial->value: + case ContentContentType::Place->value: + case ContentContentType::Guide->value: + break; + default: + // Do nothing + break; + } + } + } catch (\Throwable $e) { + if (config('app.debug')) { + throw $e; + } + // Im Produktionsmodus: Fehler ignorieren, nichts tun + } + } + + public function render() + { + return view('components.widgets.⚡search-suggestion.search-suggestion'); + } +}; \ No newline at end of file diff --git a/resources/views/default/home.blade.php b/resources/views/default/home.blade.php deleted file mode 100644 index 39bd7b9..0000000 --- a/resources/views/default/home.blade.php +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - Martin Vach Photography | Coming Soon - - - - - - - -
-
-

- laravel-core.test -

-
-
- - -
- content here -
- - - diff --git a/resources/views/errors/401.blade.php b/resources/views/errors/401.blade.php new file mode 100644 index 0000000..5c586db --- /dev/null +++ b/resources/views/errors/401.blade.php @@ -0,0 +1,5 @@ +@extends('errors::minimal') + +@section('title', __('Unauthorized')) +@section('code', '401') +@section('message', __('Unauthorized')) diff --git a/resources/views/errors/402.blade.php b/resources/views/errors/402.blade.php new file mode 100644 index 0000000..3bc23ef --- /dev/null +++ b/resources/views/errors/402.blade.php @@ -0,0 +1,5 @@ +@extends('errors::minimal') + +@section('title', __('Payment Required')) +@section('code', '402') +@section('message', __('Payment Required')) diff --git a/resources/views/errors/403.blade.php b/resources/views/errors/403.blade.php new file mode 100644 index 0000000..a5506f0 --- /dev/null +++ b/resources/views/errors/403.blade.php @@ -0,0 +1,5 @@ +@extends('errors::minimal') + +@section('title', __('Forbidden')) +@section('code', '403') +@section('message', __($exception->getMessage() ?: 'Forbidden')) diff --git a/resources/views/errors/404.blade.php b/resources/views/errors/404.blade.php new file mode 100644 index 0000000..9ec68af --- /dev/null +++ b/resources/views/errors/404.blade.php @@ -0,0 +1,7 @@ +@extends('errors.layout') +@section('title', __('app.error.404.title')) +@section('code', '404') +@section('content') +

{{__('app.error.404.message')}}

+ {{__('app.nav.takeMeHome')}} +@endsection \ No newline at end of file diff --git a/resources/views/errors/419.blade.php b/resources/views/errors/419.blade.php new file mode 100644 index 0000000..c09216e --- /dev/null +++ b/resources/views/errors/419.blade.php @@ -0,0 +1,5 @@ +@extends('errors::minimal') + +@section('title', __('Page Expired')) +@section('code', '419') +@section('message', __('Page Expired')) diff --git a/resources/views/errors/429.blade.php b/resources/views/errors/429.blade.php new file mode 100644 index 0000000..f01b07b --- /dev/null +++ b/resources/views/errors/429.blade.php @@ -0,0 +1,5 @@ +@extends('errors::minimal') + +@section('title', __('Too Many Requests')) +@section('code', '429') +@section('message', __('Too Many Requests')) diff --git a/resources/views/errors/500.blade.php b/resources/views/errors/500.blade.php new file mode 100644 index 0000000..e718742 --- /dev/null +++ b/resources/views/errors/500.blade.php @@ -0,0 +1,6 @@ +@extends('errors.layout') +@section('title', __('app.error.500.title')) +@section('code', '500') +@section('content') +

{{__('app.error.500.message')}}

+@endsection \ No newline at end of file diff --git a/resources/views/errors/503.blade.php b/resources/views/errors/503.blade.php new file mode 100644 index 0000000..c5a9dde --- /dev/null +++ b/resources/views/errors/503.blade.php @@ -0,0 +1,5 @@ +@extends('errors::minimal') + +@section('title', __('Service Unavailable')) +@section('code', '503') +@section('message', __('Service Unavailable')) diff --git a/resources/views/errors/layout.blade.php b/resources/views/errors/layout.blade.php new file mode 100644 index 0000000..0401c4d --- /dev/null +++ b/resources/views/errors/layout.blade.php @@ -0,0 +1,35 @@ + + + + @yield('title', 'Error') + @if (file_exists(public_path('build/manifest.json')) || file_exists(public_path('hot'))) + @vite([$globalCssPath, 'resources/js/app.js']) + @else + @vite([$globalCssPath, 'resources/js/app.js']) + @endif + + +
+
+ + {{-- {{ config('myapp.name') }} --}} +
+
+ +

@yield('title', 'An Error Occurred')

+
+ @yield('content') +
+ + +
+ +@if(app()->environment('local')) +

@yield('code', 'Error')

+
+ {{ $exception->getMessage() }} +
+ @endif +
+ + \ No newline at end of file diff --git a/resources/views/errors/minimal.blade.php b/resources/views/errors/minimal.blade.php new file mode 100644 index 0000000..db69f25 --- /dev/null +++ b/resources/views/errors/minimal.blade.php @@ -0,0 +1,34 @@ + + + + + + + @yield('title') + + + + + + +
+
+
+
+ @yield('code') +
+ +
+ @yield('message') +
+
+
+
+ + diff --git a/resources/views/livewire/.gitkeep b/resources/views/livewire/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/resources/views/vendor/pagination/bootstrap-4.blade.php b/resources/views/vendor/pagination/bootstrap-4.blade.php new file mode 100644 index 0000000..63c6f56 --- /dev/null +++ b/resources/views/vendor/pagination/bootstrap-4.blade.php @@ -0,0 +1,46 @@ +@if ($paginator->hasPages()) + +@endif diff --git a/resources/views/vendor/pagination/bootstrap-5.blade.php b/resources/views/vendor/pagination/bootstrap-5.blade.php new file mode 100644 index 0000000..a1795a4 --- /dev/null +++ b/resources/views/vendor/pagination/bootstrap-5.blade.php @@ -0,0 +1,88 @@ +@if ($paginator->hasPages()) + +@endif diff --git a/resources/views/vendor/pagination/default.blade.php b/resources/views/vendor/pagination/default.blade.php new file mode 100644 index 0000000..0db70b5 --- /dev/null +++ b/resources/views/vendor/pagination/default.blade.php @@ -0,0 +1,46 @@ +@if ($paginator->hasPages()) + +@endif diff --git a/resources/views/vendor/pagination/semantic-ui.blade.php b/resources/views/vendor/pagination/semantic-ui.blade.php new file mode 100644 index 0000000..ef0dbb1 --- /dev/null +++ b/resources/views/vendor/pagination/semantic-ui.blade.php @@ -0,0 +1,36 @@ +@if ($paginator->hasPages()) + +@endif diff --git a/resources/views/vendor/pagination/simple-bootstrap-4.blade.php b/resources/views/vendor/pagination/simple-bootstrap-4.blade.php new file mode 100644 index 0000000..4bb4917 --- /dev/null +++ b/resources/views/vendor/pagination/simple-bootstrap-4.blade.php @@ -0,0 +1,27 @@ +@if ($paginator->hasPages()) + +@endif diff --git a/resources/views/vendor/pagination/simple-bootstrap-5.blade.php b/resources/views/vendor/pagination/simple-bootstrap-5.blade.php new file mode 100644 index 0000000..a89005e --- /dev/null +++ b/resources/views/vendor/pagination/simple-bootstrap-5.blade.php @@ -0,0 +1,29 @@ +@if ($paginator->hasPages()) + +@endif diff --git a/resources/views/vendor/pagination/simple-default.blade.php b/resources/views/vendor/pagination/simple-default.blade.php new file mode 100644 index 0000000..36bdbc1 --- /dev/null +++ b/resources/views/vendor/pagination/simple-default.blade.php @@ -0,0 +1,19 @@ +@if ($paginator->hasPages()) + +@endif diff --git a/resources/views/vendor/pagination/simple-tailwind.blade.php b/resources/views/vendor/pagination/simple-tailwind.blade.php new file mode 100644 index 0000000..ea02400 --- /dev/null +++ b/resources/views/vendor/pagination/simple-tailwind.blade.php @@ -0,0 +1,25 @@ +@if ($paginator->hasPages()) + +@endif diff --git a/resources/views/vendor/pagination/tailwind.blade.php b/resources/views/vendor/pagination/tailwind.blade.php new file mode 100644 index 0000000..f201654 --- /dev/null +++ b/resources/views/vendor/pagination/tailwind.blade.php @@ -0,0 +1,106 @@ +@if ($paginator->hasPages()) + +@endif diff --git a/routes/default.php b/routes/default.php index b90d64f..9437309 100644 --- a/routes/default.php +++ b/routes/default.php @@ -1,8 +1,28 @@ name('home'); +/** + * Home + */ +Route::get('/', HomeController::class)->name('home'); + +/** + * Pages + */ +Route::get('/pages/{slug}', PageController::class)->name('pageItem'); + +/** + * Blog + */ +Route::get('/blog', [ArticleController::class, 'index'])->name('articleIndex'); + +Route::get('/blog/{slug}', [ArticleController::class, 'show'])->name('articleShow'); +/** + * Tags + */ +Route::get('/tags/article', [TagController::class, 'index'])->name('tagArticle'); \ No newline at end of file diff --git a/storage/debugbar/.gitignore b/storage/debugbar/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/storage/debugbar/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/tests/Unit/AppProjectTest.php b/tests/Unit/AppProjectTest.php new file mode 100644 index 0000000..a547c97 --- /dev/null +++ b/tests/Unit/AppProjectTest.php @@ -0,0 +1,13 @@ +getUrl())->toBe('https://www.ivnbg.com'); + expect(AppProject::MartinVach->getUrl())->toBe('https://www.martinvach.com'); + expect(AppProject::MyPrompties->getUrl())->toBe('https://www.myprompties.com'); + expect(AppProject::Vades->getUrl())->toBe('https://www.vades.dev'); + expect(AppProject::Aitomatix->getUrl())->toBe('https://www.aitomatix.com'); + expect(AppProject::AitomatixCz->getUrl())->toBe('https://www.aitomatix.cz'); + expect(AppProject::LaravelCore->getUrl())->toBe('https://www.laravel-core-test.com'); +}); \ No newline at end of file diff --git a/vite.config.js b/vite.config.js index 533c20f..c7597f4 100644 --- a/vite.config.js +++ b/vite.config.js @@ -8,6 +8,7 @@ import path from 'path'; export default defineConfig(() => { // Check if SITE is defined const site = process.env.SITE; + console.log(`SITE environment variable: ${site}`); // Determine the public root // If SITE exists, resolve to external domain. If not, use default 'public'. @@ -15,10 +16,14 @@ export default defineConfig(() => { ? path.resolve(__dirname, '..', 'domains', site, 'public_html') : 'public'; + const domainResourceDir = site || 'default'; + + console.log(`Using public directory: ${publicDir}`); + return { plugins: [ laravel({ - input: ['resources/css/app.css', 'resources/js/app.js'], + input: ['resources/css/'+ domainResourceDir + '/app.css', 'resources/js/app.js'], refresh: true, // Pass the dynamic directory here @@ -41,4 +46,4 @@ export default defineConfig(() => { }, }, }; -}); +}); \ No newline at end of file From 015b64a9b23da7a15f7da0a413299e9167660f43 Mon Sep 17 00:00:00 2001 From: Martin Vach Date: Thu, 5 Mar 2026 14:01:09 +0100 Subject: [PATCH 006/103] Merge pull request #12 * #11: Adding basic layout styles * #11: Adding basic layout styles * #11: Adding styles * #11: Adding card styles * #11: Adding search styles * #11: Adding new styles * #11: Adding new styles * #11: Install mui * #11: Implement ui components * #11: Styling footer * #11: Styling jumbotron * #11: Styling page header * #11: Styling body * #11: Styling form * #11: Styling header * #11: Styling my-prev-next * #11: Styling article detail * #11: Styling autocomplete * #11: Styling card and panel * #11: Styling navigation * #11: Adding nav for small devices * #11: Adding nav for small and large devices * #11: Adding categories composer * #11: Adding TaC * #11: Moving components from shared to ui * #11: Moving components from shared to ui * #11: Adding homepage elements * #11: Adding homepage items * #11: Testing theme * #11: Adjusting responsive styles * #11: Renaming composer categories * #11: Adjusting tags --- .../Web/Default/HomeController.php | 10 +- .../Controllers/Web/Default/TagController.php | 7 +- app/Providers/AppServiceProvider.php | 8 +- app/View/Composers/CategoryComposer.php | 32 ++ app/View/Composers/TagComposer.php | 32 ++ composer.json | 5 +- composer.lock | 275 ++++++++++++++- config/myapp.php | 2 + lang/en/app.php | 4 + resources/css/app.css | 4 + resources/css/default/app.css | 21 +- resources/css/default/theme.css | 24 +- resources/css/shared/alert.css | 22 ++ resources/css/shared/badge.css | 11 + resources/css/shared/base.css | 67 ++++ resources/css/shared/button.css | 11 + resources/css/shared/card.css | 32 ++ resources/css/shared/dropdown.css | 14 + resources/css/shared/footer.css | 6 + resources/css/shared/form.css | 28 ++ resources/css/shared/header.css | 23 ++ resources/css/shared/jumbotron.css | 6 + resources/css/shared/page-header.css | 15 + resources/css/shared/panel.css | 9 + resources/css/shared/prev-next.css | 7 + resources/css/shared/search.css | 13 + resources/css/shared/supplementary.css | 19 ++ resources/css/shared/utils.css | 12 + resources/css/theme.css | 24 ++ resources/js/app.js | 1 + resources/js/globals/theme.js | 148 ++++++++ resources/js/utils.js | 22 ++ .../views/components/_shared/alert.blade.php | 3 + .../views/components/_shared/badge.blade.php | 9 + .../views/components/_shared/card.blade.php | 13 + .../categories-dropdown.blade.php | 0 .../{shared => _shared}/dropdown.blade.php | 2 +- .../{shared => _shared}/gtag.blade.php | 0 .../{shared => _shared}/iframe.blade.php | 4 +- .../{shared => _shared}/img-svg.blade.php | 0 .../components/_shared/jumbotron.blade.php | 6 + .../{shared => _shared}/lightbox.blade.php | 0 .../{shared => _shared}/modal.blade.php | 0 .../components/_shared/page-header.blade.php | 22 ++ .../{shared => _shared}/pagination.blade.php | 0 .../views/components/_shared/panel.blade.php | 9 + .../{shared => _shared}/post-image.blade.php | 0 .../{shared => _shared}/prev-next.blade.php | 6 +- .../default/article/index.blade.php | 30 +- .../default/article/show-default.blade.php | 22 +- .../views/components/default/data/nav.php | 9 + .../default/home/article-list.blade.php | 32 ++ .../default/home/features.blade.php | 51 +++ .../components/default/home/hero.blade.php | 6 + .../components/default/home/index.blade.php | 78 +++++ .../views/components/default/layout.blade.php | 24 +- .../components/default/page/index.blade.php | 4 +- .../default/partials/footer/index.blade.php | 12 +- .../default/partials/footer/nav.blade.php | 6 +- .../default/partials/header/brand.blade.php | 5 +- .../default/partials/header/index.blade.php | 25 +- .../default/partials/header/nav-lg.blade.php | 7 + .../default/partials/header/nav-sm.blade.php | 34 ++ .../default/partials/header/nav.blade.php | 45 ++- .../default/partials/page-header.blade.php | 4 +- .../partials/supplementary/index.blade.php | 9 +- .../components/default/tag/index.blade.php | 32 +- .../views/components/shared/alert.blade.php | 4 - .../views/components/shared/badge.blade.php | 9 - .../views/components/shared/card.blade.php | 13 - .../components/shared/jumbotron.blade.php | 6 - .../views/components/shared/panel.blade.php | 9 - .../ui/alerts/description.blade.php | 4 + .../components/ui/alerts/heading.blade.php | 13 + .../components/ui/alerts/index.blade.php | 144 ++++++++ .../ui/autocomplete/index.blade.php | 228 +++++++++++++ .../components/ui/autocomplete/item.blade.php | 37 ++ .../ui/autocomplete/items.blade.php | 23 ++ .../views/components/ui/badge/index.blade.php | 99 ++++++ .../components/ui/button/abstract.blade.php | 38 +++ .../components/ui/button/index.blade.php | 187 ++++++++++ .../views/components/ui/card/index.blade.php | 23 ++ .../ui/dropdown/checkbox-or-radio.blade.php | 106 ++++++ .../components/ui/dropdown/group.blade.php | 10 + .../components/ui/dropdown/index.blade.php | 133 ++++++++ .../components/ui/dropdown/item.blade.php | 104 ++++++ .../ui/dropdown/separator.blade.php | 6 + .../components/ui/dropdown/submenu.blade.php | 68 ++++ resources/views/components/ui/error.blade.php | 51 +++ resources/views/components/ui/field.blade.php | 30 ++ .../views/components/ui/fieldset.blade.php | 32 ++ .../components/ui/heading/index.blade.php | 30 ++ .../views/components/ui/icon/index.blade.php | 45 +++ .../components/ui/icon/loading.blade.php | 26 ++ .../components/ui/input/extra-slot.blade.php | 5 + .../views/components/ui/input/index.blade.php | 237 +++++++++++++ .../ui/input/options/button.blade.php | 8 + .../ui/input/options/clearable.blade.php | 11 + .../ui/input/options/copyable.blade.php | 32 ++ .../ui/input/options/revealable.blade.php | 27 ++ .../views/components/ui/kbd/index.blade.php | 0 resources/views/components/ui/label.blade.php | 27 ++ .../components/ui/layout/header.blade.php | 31 ++ .../components/ui/layout/index.blade.php | 25 ++ .../views/components/ui/layout/main.blade.php | 15 + .../components/ui/layout/runtime.blade.php | 32 ++ .../layout/variant/header-sidebar.blade.php | 323 ++++++++++++++++++ .../ui/layout/variant/sidebar-main.blade.php | 278 +++++++++++++++ resources/views/components/ui/link.blade.php | 26 ++ .../components/ui/my-card/index.blade.php | 13 + .../ui/my-categories-dropdown/index.blade.php | 18 + .../components/ui/my-dropdown/index.blade.php | 22 ++ .../components/ui/my-gtag/index.blade.php | 10 + .../components/ui/my-iframe/index.blade.php | 9 + .../components/ui/my-img-svg/index.blade.php | 10 + .../ui/my-jumbotron/index.blade.php | 6 + .../components/ui/my-lightbox/index.blade.php | 99 ++++++ .../components/ui/my-modal/index.blade.php | 46 +++ .../my-page-header/index.blade.php} | 7 +- .../components/ui/my-panel/index.blade.php | 9 + .../ui/my-prev-next/index.blade.php | 14 + .../components/ui/navbar/index.blade.php | 13 + .../views/components/ui/navbar/item.blade.php | 75 ++++ .../components/ui/navlist/group.blade.php | 39 +++ .../navlist/group/variant/compact.blade.php | 59 ++++ .../navlist/group/variant/default.blade.php | 59 ++++ .../ui/navlist/has-tooltip.blade.php | 69 ++++ .../components/ui/navlist/index.blade.php | 13 + .../components/ui/navlist/item.blade.php | 94 +++++ resources/views/components/ui/popup.blade.php | 46 +++ .../components/ui/sidebar/index.blade.php | 156 +++++++++ .../components/ui/sidebar/push.blade.php | 1 + .../components/ui/sidebar/toggle.blade.php | 30 ++ resources/views/components/ui/text.blade.php | 6 + .../components/ui/textarea/index.blade.php | 105 ++++++ .../categories-dropdown.blade.php" | 34 -- .../categories-dropdown.php" | 35 -- .../contact-form.blade.php" | 68 ++-- .../search-suggestion-bck.blade.php" | 40 +++ .../search-suggestion.blade.php" | 18 +- .../vendor/pagination/tailwind.blade.php | 26 +- .../vendor/pagination/tailwind_bck.blade.php | 106 ++++++ sheaf-lock.json | 39 +++ sheaf.json | 68 ++++ 144 files changed, 5167 insertions(+), 273 deletions(-) create mode 100644 app/View/Composers/CategoryComposer.php create mode 100644 app/View/Composers/TagComposer.php create mode 100644 resources/css/app.css create mode 100644 resources/css/shared/alert.css create mode 100644 resources/css/shared/badge.css create mode 100644 resources/css/shared/base.css create mode 100644 resources/css/shared/button.css create mode 100644 resources/css/shared/card.css create mode 100644 resources/css/shared/dropdown.css create mode 100644 resources/css/shared/footer.css create mode 100644 resources/css/shared/form.css create mode 100644 resources/css/shared/header.css create mode 100644 resources/css/shared/jumbotron.css create mode 100644 resources/css/shared/page-header.css create mode 100644 resources/css/shared/panel.css create mode 100644 resources/css/shared/prev-next.css create mode 100644 resources/css/shared/search.css create mode 100644 resources/css/shared/supplementary.css create mode 100644 resources/css/shared/utils.css create mode 100644 resources/css/theme.css create mode 100644 resources/js/globals/theme.js create mode 100644 resources/js/utils.js create mode 100644 resources/views/components/_shared/alert.blade.php create mode 100644 resources/views/components/_shared/badge.blade.php create mode 100644 resources/views/components/_shared/card.blade.php rename resources/views/components/{shared => _shared}/categories-dropdown.blade.php (100%) rename resources/views/components/{shared => _shared}/dropdown.blade.php (75%) rename resources/views/components/{shared => _shared}/gtag.blade.php (100%) rename resources/views/components/{shared => _shared}/iframe.blade.php (51%) rename resources/views/components/{shared => _shared}/img-svg.blade.php (100%) create mode 100644 resources/views/components/_shared/jumbotron.blade.php rename resources/views/components/{shared => _shared}/lightbox.blade.php (100%) rename resources/views/components/{shared => _shared}/modal.blade.php (100%) create mode 100644 resources/views/components/_shared/page-header.blade.php rename resources/views/components/{shared => _shared}/pagination.blade.php (100%) create mode 100644 resources/views/components/_shared/panel.blade.php rename resources/views/components/{shared => _shared}/post-image.blade.php (100%) rename resources/views/components/{shared => _shared}/prev-next.blade.php (61%) create mode 100644 resources/views/components/default/home/article-list.blade.php create mode 100644 resources/views/components/default/home/features.blade.php create mode 100644 resources/views/components/default/home/hero.blade.php create mode 100644 resources/views/components/default/partials/header/nav-lg.blade.php create mode 100644 resources/views/components/default/partials/header/nav-sm.blade.php delete mode 100644 resources/views/components/shared/alert.blade.php delete mode 100644 resources/views/components/shared/badge.blade.php delete mode 100644 resources/views/components/shared/card.blade.php delete mode 100644 resources/views/components/shared/jumbotron.blade.php delete mode 100644 resources/views/components/shared/panel.blade.php create mode 100644 resources/views/components/ui/alerts/description.blade.php create mode 100644 resources/views/components/ui/alerts/heading.blade.php create mode 100644 resources/views/components/ui/alerts/index.blade.php create mode 100644 resources/views/components/ui/autocomplete/index.blade.php create mode 100644 resources/views/components/ui/autocomplete/item.blade.php create mode 100644 resources/views/components/ui/autocomplete/items.blade.php create mode 100644 resources/views/components/ui/badge/index.blade.php create mode 100644 resources/views/components/ui/button/abstract.blade.php create mode 100644 resources/views/components/ui/button/index.blade.php create mode 100644 resources/views/components/ui/card/index.blade.php create mode 100644 resources/views/components/ui/dropdown/checkbox-or-radio.blade.php create mode 100644 resources/views/components/ui/dropdown/group.blade.php create mode 100644 resources/views/components/ui/dropdown/index.blade.php create mode 100644 resources/views/components/ui/dropdown/item.blade.php create mode 100644 resources/views/components/ui/dropdown/separator.blade.php create mode 100644 resources/views/components/ui/dropdown/submenu.blade.php create mode 100644 resources/views/components/ui/error.blade.php create mode 100644 resources/views/components/ui/field.blade.php create mode 100644 resources/views/components/ui/fieldset.blade.php create mode 100644 resources/views/components/ui/heading/index.blade.php create mode 100644 resources/views/components/ui/icon/index.blade.php create mode 100644 resources/views/components/ui/icon/loading.blade.php create mode 100644 resources/views/components/ui/input/extra-slot.blade.php create mode 100644 resources/views/components/ui/input/index.blade.php create mode 100644 resources/views/components/ui/input/options/button.blade.php create mode 100644 resources/views/components/ui/input/options/clearable.blade.php create mode 100644 resources/views/components/ui/input/options/copyable.blade.php create mode 100644 resources/views/components/ui/input/options/revealable.blade.php create mode 100644 resources/views/components/ui/kbd/index.blade.php create mode 100644 resources/views/components/ui/label.blade.php create mode 100644 resources/views/components/ui/layout/header.blade.php create mode 100644 resources/views/components/ui/layout/index.blade.php create mode 100644 resources/views/components/ui/layout/main.blade.php create mode 100644 resources/views/components/ui/layout/runtime.blade.php create mode 100644 resources/views/components/ui/layout/variant/header-sidebar.blade.php create mode 100644 resources/views/components/ui/layout/variant/sidebar-main.blade.php create mode 100644 resources/views/components/ui/link.blade.php create mode 100644 resources/views/components/ui/my-card/index.blade.php create mode 100644 resources/views/components/ui/my-categories-dropdown/index.blade.php create mode 100644 resources/views/components/ui/my-dropdown/index.blade.php create mode 100644 resources/views/components/ui/my-gtag/index.blade.php create mode 100644 resources/views/components/ui/my-iframe/index.blade.php create mode 100644 resources/views/components/ui/my-img-svg/index.blade.php create mode 100644 resources/views/components/ui/my-jumbotron/index.blade.php create mode 100644 resources/views/components/ui/my-lightbox/index.blade.php create mode 100644 resources/views/components/ui/my-modal/index.blade.php rename resources/views/components/{shared/page-header.blade.php => ui/my-page-header/index.blade.php} (70%) create mode 100644 resources/views/components/ui/my-panel/index.blade.php create mode 100644 resources/views/components/ui/my-prev-next/index.blade.php create mode 100644 resources/views/components/ui/navbar/index.blade.php create mode 100644 resources/views/components/ui/navbar/item.blade.php create mode 100644 resources/views/components/ui/navlist/group.blade.php create mode 100644 resources/views/components/ui/navlist/group/variant/compact.blade.php create mode 100644 resources/views/components/ui/navlist/group/variant/default.blade.php create mode 100644 resources/views/components/ui/navlist/has-tooltip.blade.php create mode 100644 resources/views/components/ui/navlist/index.blade.php create mode 100644 resources/views/components/ui/navlist/item.blade.php create mode 100644 resources/views/components/ui/popup.blade.php create mode 100644 resources/views/components/ui/sidebar/index.blade.php create mode 100644 resources/views/components/ui/sidebar/push.blade.php create mode 100644 resources/views/components/ui/sidebar/toggle.blade.php create mode 100644 resources/views/components/ui/text.blade.php create mode 100644 resources/views/components/ui/textarea/index.blade.php delete mode 100644 "resources/views/components/widgets/\342\232\241categories-dropdown/categories-dropdown.blade.php" delete mode 100644 "resources/views/components/widgets/\342\232\241categories-dropdown/categories-dropdown.php" create mode 100644 "resources/views/components/widgets/\342\232\241search-suggestion/search-suggestion-bck.blade.php" create mode 100644 resources/views/vendor/pagination/tailwind_bck.blade.php create mode 100644 sheaf-lock.json create mode 100644 sheaf.json diff --git a/app/Http/Controllers/Web/Default/HomeController.php b/app/Http/Controllers/Web/Default/HomeController.php index 32c73b5..68ca214 100644 --- a/app/Http/Controllers/Web/Default/HomeController.php +++ b/app/Http/Controllers/Web/Default/HomeController.php @@ -3,6 +3,7 @@ namespace App\Http\Controllers\Web\Default; use App\Http\Controllers\Controller; +use App\Models\Content; use Illuminate\Http\Request; use Illuminate\View\View; @@ -13,7 +14,14 @@ class HomeController extends Controller */ public function __invoke(Request $request): View { + $articles = Content::publishedByType() + ->filter($request) + ->latest() + ->take(6) + ->get(); - return view('home.index'); + return view('home.index', [ + 'articles' => $articles ?? [], + ]); } } \ No newline at end of file diff --git a/app/Http/Controllers/Web/Default/TagController.php b/app/Http/Controllers/Web/Default/TagController.php index 5d0d7b9..aa76251 100644 --- a/app/Http/Controllers/Web/Default/TagController.php +++ b/app/Http/Controllers/Web/Default/TagController.php @@ -7,7 +7,6 @@ use App\Models\Content; use App\Models\Tag; use Illuminate\Http\Request; -use Illuminate\Support\Str; use Illuminate\View\View; class TagController extends Controller @@ -17,7 +16,11 @@ public function index(Request $request): View { $contentType = basename($request->path()); $meta = Content::publishedByType(ContentContentType::Meta)->where('slug','tags-'. $contentType)->firstOrFail(); - $tags = Tag::ByContentType($contentType)->withCount('contents')->where('contents_count','>',0)->get(); + $tags = Tag::ByContentType($contentType) + ->withCount('contents') + ->where('contents_count','>',0) + ->orderByDesc('contents_count') + ->get(); return view('tag.index', [ 'page' => $meta, 'tags' => $tags ?? [], diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 452e6b6..f821067 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -2,6 +2,9 @@ namespace App\Providers; +use App\View\Composers\CategoryComposer; +use App\View\Composers\TagComposer; +use Illuminate\Support\Facades\View; use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider @@ -19,6 +22,7 @@ public function register(): void */ public function boot(): void { - // + View::composer('*', CategoryComposer::class); + View::composer('*', TagComposer::class); } -} +} \ No newline at end of file diff --git a/app/View/Composers/CategoryComposer.php b/app/View/Composers/CategoryComposer.php new file mode 100644 index 0000000..f641af7 --- /dev/null +++ b/app/View/Composers/CategoryComposer.php @@ -0,0 +1,32 @@ +getData(); + + // 2. Extract 'type', defaulting to 'place' if missing to prevent errors + $categoryType = $viewData['categoryType'] ?? ''; + + // 3. Use the dynamic $type variable in your query + + $categories = Category::publishedByType($categoryType) + ->withCount('contents')->where('contents_count','>',0)->get(); + + $currentCategory = request()->query('category', null); + + $view->with([ + 'composerCategories' => $categories, + 'composerCurrentCategory' => $currentCategory, + ]); + } +} \ No newline at end of file diff --git a/app/View/Composers/TagComposer.php b/app/View/Composers/TagComposer.php new file mode 100644 index 0000000..e28a493 --- /dev/null +++ b/app/View/Composers/TagComposer.php @@ -0,0 +1,32 @@ +getData(); + + // 2. Extract 'type', defaulting to 'place' if missing to prevent errors + $tagType = $viewData['tagType'] ?? ''; + + // 3. Use the dynamic $type variable in your query + + $tags = Tag::byContentType($tagType) + ->withCount('contents')->where('contents_count','>',0)->get(); + + $currentTag = request()->query('category', null); + + $view->with([ + 'composerTags' => $tags, + 'composerCurrentTag' => $currentTag, + ]); + } +} \ No newline at end of file diff --git a/composer.json b/composer.json index 3104f5e..b9eb7c9 100644 --- a/composer.json +++ b/composer.json @@ -10,14 +10,17 @@ "license": "MIT", "require": { "php": "^8.4", + "blade-ui-kit/blade-heroicons": "^2.6", "laravel/framework": "^12.0", "laravel/telescope": "^5.16", "laravel/tinker": "^2.10.1", "livewire/volt": "^1.7.0", + "sheaf/cli": "^1.3", "spatie/laravel-data": "^4.18", "spatie/laravel-sitemap": "^7.3", "spatie/laravel-sluggable": "^3.7", - "spatie/yaml-front-matter": "^2.1" + "spatie/yaml-front-matter": "^2.1", + "wireui/heroicons": "*" }, "require-dev": { "fakerphp/faker": "^1.23", diff --git a/composer.lock b/composer.lock index de9abb6..c0ee1d1 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,158 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "cc732e5e7cb99a3ae2c9d6a8494a2243", + "content-hash": "c289ac488d3e580a6601d38e6b037f07", "packages": [ + { + "name": "blade-ui-kit/blade-heroicons", + "version": "2.6.0", + "source": { + "type": "git", + "url": "https://github.com/driesvints/blade-heroicons.git", + "reference": "4553b2a1f6c76f0ac7f3bc0de4c0cfa06a097d19" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/driesvints/blade-heroicons/zipball/4553b2a1f6c76f0ac7f3bc0de4c0cfa06a097d19", + "reference": "4553b2a1f6c76f0ac7f3bc0de4c0cfa06a097d19", + "shasum": "" + }, + "require": { + "blade-ui-kit/blade-icons": "^1.6", + "illuminate/support": "^9.0|^10.0|^11.0|^12.0", + "php": "^8.0" + }, + "require-dev": { + "orchestra/testbench": "^7.0|^8.0|^9.0|^10.0", + "phpunit/phpunit": "^9.0|^10.5|^11.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "BladeUI\\Heroicons\\BladeHeroiconsServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "BladeUI\\Heroicons\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Dries Vints", + "homepage": "https://driesvints.com" + } + ], + "description": "A package to easily make use of Heroicons in your Laravel Blade views.", + "homepage": "https://github.com/blade-ui-kit/blade-heroicons", + "keywords": [ + "Heroicons", + "blade", + "laravel" + ], + "support": { + "issues": "https://github.com/driesvints/blade-heroicons/issues", + "source": "https://github.com/driesvints/blade-heroicons/tree/2.6.0" + }, + "funding": [ + { + "url": "https://github.com/sponsors/driesvints", + "type": "github" + }, + { + "url": "https://www.paypal.com/paypalme/driesvints", + "type": "paypal" + } + ], + "time": "2025-02-13T20:53:33+00:00" + }, + { + "name": "blade-ui-kit/blade-icons", + "version": "1.8.1", + "source": { + "type": "git", + "url": "https://github.com/driesvints/blade-icons.git", + "reference": "47e7b6f43250e6404e4224db8229219cd42b543c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/driesvints/blade-icons/zipball/47e7b6f43250e6404e4224db8229219cd42b543c", + "reference": "47e7b6f43250e6404e4224db8229219cd42b543c", + "shasum": "" + }, + "require": { + "illuminate/contracts": "^8.0|^9.0|^10.0|^11.0|^12.0", + "illuminate/filesystem": "^8.0|^9.0|^10.0|^11.0|^12.0", + "illuminate/support": "^8.0|^9.0|^10.0|^11.0|^12.0", + "illuminate/view": "^8.0|^9.0|^10.0|^11.0|^12.0", + "php": "^7.4|^8.0", + "symfony/console": "^5.3|^6.0|^7.0", + "symfony/finder": "^5.3|^6.0|^7.0" + }, + "require-dev": { + "mockery/mockery": "^1.5.1", + "orchestra/testbench": "^6.0|^7.0|^8.0|^9.0|^10.0", + "phpunit/phpunit": "^9.0|^10.5|^11.0" + }, + "bin": [ + "bin/blade-icons-generate" + ], + "type": "library", + "extra": { + "laravel": { + "providers": [ + "BladeUI\\Icons\\BladeIconsServiceProvider" + ] + } + }, + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "BladeUI\\Icons\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Dries Vints", + "homepage": "https://driesvints.com" + } + ], + "description": "A package to easily make use of icons in your Laravel Blade views.", + "homepage": "https://github.com/driesvints/blade-icons", + "keywords": [ + "blade", + "icons", + "laravel", + "svg" + ], + "support": { + "issues": "https://github.com/driesvints/blade-icons/issues", + "source": "https://github.com/driesvints/blade-icons" + }, + "funding": [ + { + "url": "https://github.com/sponsors/driesvints", + "type": "github" + }, + { + "url": "https://www.paypal.com/paypalme/driesvints", + "type": "paypal" + } + ], + "time": "2026-01-20T09:46:32+00:00" + }, { "name": "brick/math", "version": "0.14.1", @@ -3901,6 +4051,66 @@ }, "time": "2025-12-14T04:43:48+00:00" }, + { + "name": "sheaf/cli", + "version": "v1.3.4", + "source": { + "type": "git", + "url": "https://github.com/sheafui/cli.git", + "reference": "4bf1d1959f7a4c18b0d1388e6bb3509ce6253f79" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sheafui/cli/zipball/4bf1d1959f7a4c18b0d1388e6bb3509ce6253f79", + "reference": "4bf1d1959f7a4c18b0d1388e6bb3509ce6253f79", + "shasum": "" + }, + "require-dev": { + "orchestra/testbench": "^10.4", + "pestphp/pest": "^3.8", + "pestphp/pest-plugin-laravel": "^3.2" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Sheaf\\Cli\\ServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Sheaf\\Cli\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Youssef ACHCHIRAJ", + "email": "achchiraj.youssef@gmail.com", + "homepage": "https://youssef-achchiraj.com", + "role": "Full Stack Developer" + } + ], + "description": "A CLI tool for Sheaf UI", + "homepage": "https://github.com/sheaf/cli", + "keywords": [ + "artisan-command", + "cli", + "laravel", + "laravel-package", + "package", + "sheaf" + ], + "support": { + "issues": "https://github.com/sheafui/cli/issues", + "source": "https://github.com/sheafui/cli/tree/v1.3.4" + }, + "time": "2025-11-30T14:34:29+00:00" + }, { "name": "spatie/browsershot", "version": "5.2.0", @@ -7482,6 +7692,69 @@ "source": "https://github.com/webmozarts/assert/tree/1.12.1" }, "time": "2025-10-29T15:56:20+00:00" + }, + { + "name": "wireui/heroicons", + "version": "v2.9.0", + "source": { + "type": "git", + "url": "https://github.com/wireui/heroicons.git", + "reference": "ccd2ab94293d6f231271c0847c1db34305313c6f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/wireui/heroicons/zipball/ccd2ab94293d6f231271c0847c1db34305313c6f", + "reference": "ccd2ab94293d6f231271c0847c1db34305313c6f", + "shasum": "" + }, + "require": { + "laravel/framework": "^9.16|^10.0|^11.0|^12.0", + "php": "^8.1|^8.2|^8.3|^8.4" + }, + "require-dev": { + "larastan/larastan": "^3.0", + "laravel/pint": "^1.6", + "orchestra/testbench": "^10.0", + "pestphp/pest": "^3.0" + }, + "type": "library", + "extra": { + "aliases": [], + "laravel": { + "providers": [ + "WireUi\\Heroicons\\HeroiconsServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "WireUi\\Heroicons\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Pedro Oliveira", + "email": "pedrolivertwd@gmail.com" + } + ], + "description": "The Tailwind Heroicons for laravel blade by WireUI", + "keywords": [ + "blade components", + "blade heroicons", + "laravel components", + "livewire icons", + "livewire icons components", + "wireui" + ], + "support": { + "issues": "https://github.com/wireui/heroicons/issues", + "source": "https://github.com/wireui/heroicons/tree/v2.9.0" + }, + "time": "2025-03-02T22:06:22+00:00" } ], "packages-dev": [ diff --git a/config/myapp.php b/config/myapp.php index 8cef448..7c7b0c0 100644 --- a/config/myapp.php +++ b/config/myapp.php @@ -4,9 +4,11 @@ 'projectSlug' => env('MY_PROJECT_SLUG'), 'importDir' => env('MY_IMPORT_DIR'), 'imagePlaceholder' => env('MY_IMAGE_PLACEHOLDER'), + 'gatMeasurementId' => env('MY_GTAG_MEASUREMENT_ID'), 'image' => [ 'featured' => 'featured.jpg', 'cover' => 'cover.jpg', + 'svgPath' => 'app/public/images/svg', 'placeholder' => [ 'page' => 'storage/images/placeholders/page.jpg', 'article' => 'storage/images/placeholders/article.jpg', diff --git a/lang/en/app.php b/lang/en/app.php index 76c1e3f..1626eeb 100644 --- a/lang/en/app.php +++ b/lang/en/app.php @@ -18,12 +18,16 @@ 'seeMore' => 'See more', 'otherPlaces' => 'Other places', 'all' => 'All', + 'allArticles' => 'All articles', 'all_' => 'All :name', 'recentPosts' => 'Recent posts', 'listOfPlaces' => 'List of places', 'address' => 'Address', 'highlights' => 'Highlights', 'takeMeHome' => 'Take me home', + 'previous' => 'Previous', + 'next' => 'Next', + "termsAndConditions" => "Terms and Conditions", ], 'search' => [ diff --git a/resources/css/app.css b/resources/css/app.css new file mode 100644 index 0000000..d295389 --- /dev/null +++ b/resources/css/app.css @@ -0,0 +1,4 @@ +@import './theme.css'; /* By Sheaf.dev */ + + + @custom-variant dark (&:where(.dark, .dark *)); /* By Sheaf.dev */ diff --git a/resources/css/default/app.css b/resources/css/default/app.css index 9c00171..090bc1e 100644 --- a/resources/css/default/app.css +++ b/resources/css/default/app.css @@ -1,10 +1,27 @@ @import 'tailwindcss'; @import './theme.css'; +/*@import '../shared/base.css'; +@import '../shared/utils.css';*/ +/*@import '../shared/header.css';*/ +/*@import '../shared/supplementary.css';*/ +/*@import '../shared/footer.css';*/ +/*@import '../shared/form.css';*/ +/*@import '../shared/button.css';/* +@import '../shared/dropdown.css';*/ +/*@import '../shared/search.css';*/ +/*@import '../shared/card.css';*/ +/*@import '../shared/badge.css'; +@import '../shared/alert.css'; +@import '../shared/jumbotron.css';*/ +/*@import '../shared/page-header.css';*/ +/*@import '../shared/prev-next.css'; +@import '../shared/panel.css';*/ +/* Custom styles for the default domain */ + /** * TODO Remove this file when we have a proper multi-domain architecture * ! DEPRECATED * ? Test * * Test * @param myParam - Test parameter -*/ - +*/ \ No newline at end of file diff --git a/resources/css/default/theme.css b/resources/css/default/theme.css index 63b0e50..2608e1a 100644 --- a/resources/css/default/theme.css +++ b/resources/css/default/theme.css @@ -1,5 +1,6 @@ @theme { + --font-size-base: 1.2rem; --font-sans: 'Instrument Sans', ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; --color-brand-primary: #A3160B; @@ -63,10 +64,31 @@ --color-bcg-jumbotron: #F7F8F2; --color-bcg-supplementary: #F7F8F2; --color-bcg-footer: #FFFFFF; + --color-bcg-card: #F7F8F2; --color-bcg-featured: #F7F8F2; --color-bcg-article: #fef4e6; --color-bcg-blog: #F7F8F2; --color-bcg-place: #F7F8F2; --color-bcg-album: #F7F8F2; --color-icon: #ffffff; -} \ No newline at end of file + + /* * SHEAF UI color scheme */ + /* --color-primary: var(--color-red-500); + --color-primary-content: var(--color-blue-700); + --color-primary-fg: var(--color-blue-600);*/ + + --radius-field: 0.25rem; + --radius-box: 0.5rem; +} + + +/* +@layer theme { + .dark { + --color-primary: var(--color-white); + --color-primary-content: var(--color-white); + --color-primary-fg: var(--color-neutral-800); + } +}*/ + +@custom-variant dark (&:where(.dark, .dark *)); \ No newline at end of file diff --git a/resources/css/shared/alert.css b/resources/css/shared/alert.css new file mode 100644 index 0000000..0274c79 --- /dev/null +++ b/resources/css/shared/alert.css @@ -0,0 +1,22 @@ + +/* region Alert */ +.alert { + @apply p-4 text-sm text-gray-800 rounded-lg bg-gray-50 font-medium mb-4; +} +.alert.is-info { + @apply text-blue-800 bg-blue-50 ; +} + +.alert.is-danger { + @apply text-red-800 bg-red-50 ; +} + +.alert.is-success { + @apply text-green-800 bg-green-50 ; +} +.alert.is-warning { + @apply text-yellow-800 bg-yellow-50 ; +} + + +/* endregion */ \ No newline at end of file diff --git a/resources/css/shared/badge.css b/resources/css/shared/badge.css new file mode 100644 index 0000000..bd7329f --- /dev/null +++ b/resources/css/shared/badge.css @@ -0,0 +1,11 @@ + +/* region Button */ +.badge { + @apply relative inline-flex font-medium me-2 px-2.5 py-0.5 rounded border border-bor-btn; +} + +.badge-notify { + @apply absolute inline-flex items-center justify-center w-6 h-6 text-xs font-bold bg-bcg-btn rounded-full -top-2 -end-2 border border-bor-btn; +} + +/* endregion */ \ No newline at end of file diff --git a/resources/css/shared/base.css b/resources/css/shared/base.css new file mode 100644 index 0000000..250e5d2 --- /dev/null +++ b/resources/css/shared/base.css @@ -0,0 +1,67 @@ +/* region Layout */ + +html, body { + @apply h-full max-w-full overflow-x-hidden; +} + +/*body { + @apply m-0 text-base bg-bcg-body text-[1.2rem]; +}*/ +/*#root{ + @apply min-h-screen flex flex-col; +}*/ + +/*#header{ + @apply text-header bg-bcg-header shadow-md; + +}*/ +/*.header-container{ + @apply container mx-auto flex justify-between items-center px-4 h-16; +}*/ + + +/* + +main{ + @apply container mx-auto mb-auto p-6 mb-6; +} +*/ + + +/*#footer{ + @apply bg-bcg-footer border-t border-bor-footer; +} +.footer-container{ + @apply container mx-auto text-center p-4 md:flex justify-between items-center; +}*/ + +/* region Typo */ +/*h1 { + @apply text-4xl text-h1 mb-4 font-serif break-words; +} + +h2{ + @apply text-2xl text-heading mt-3 break-words; +} + +h3{ + @apply text-xl text-heading mb-1 break-words; +} + +.subtitle { + @apply text-heading text-lg italic; +} + +.perex { + @apply text-lg mb-4 font-serif; +}*/ + +/* endregion */ + +/* region Grid*/ + +/*.base-grid{ + @apply grid gap-2 sm:grid-cols-2 lg:grid-cols-3 lg:gap-3 2xl:grid-cols-4 xl:gap-4; +}*/ + +/* endregion */ \ No newline at end of file diff --git a/resources/css/shared/button.css b/resources/css/shared/button.css new file mode 100644 index 0000000..67f9348 --- /dev/null +++ b/resources/css/shared/button.css @@ -0,0 +1,11 @@ + +/* region Button */ +.button { + @apply py-2.5 px-5 me-2 mb-2 text-btn focus:outline-none bg-bcg-btn rounded-sm border border-bor-btn hover:bg-bcg-btn-hover hover:text-btn-hover focus:z-10 focus:ring-4 focus:ring-gray-100 cursor-pointer; +} + +.button-secondary { + @apply focus:outline-none text-white bg-bcg-secondary hover:bg-bcg-secondary-muted focus:ring-4 focus:ring-green-300 font-medium rounded-lg text-sm px-5 py-2.5 me-2 mb-2 cursor-pointer; +} + +/* endregion */ \ No newline at end of file diff --git a/resources/css/shared/card.css b/resources/css/shared/card.css new file mode 100644 index 0000000..184c2a3 --- /dev/null +++ b/resources/css/shared/card.css @@ -0,0 +1,32 @@ +.card { + @apply flex flex-col justify-between h-full bg-bcg-card sm:border border-bor-base; +} +.card-footer { + @apply mt-auto text-center pb-4; + .button{ + @apply inline-block text-center; + } +} +.card-body{ + @apply flex-grow px-6 py-4; +} + +.card-header{ + .card-image{ + @apply w-full h-64 object-cover mb-4; + } +} + +.card-title{ + @apply text-2xl font-bold mb-2; +} + +.card-info{ + @apply text-sm mb-3; +} + + + +.card-excerpt{ + @apply mb-3; +} \ No newline at end of file diff --git a/resources/css/shared/dropdown.css b/resources/css/shared/dropdown.css new file mode 100644 index 0000000..51f040a --- /dev/null +++ b/resources/css/shared/dropdown.css @@ -0,0 +1,14 @@ +/* region Dropdown */ +.dropdown { + @apply absolute left-0 top-full mt-2 w-64 bg-white shadow-lg rounded z-50 max-h-128 overflow-auto divide-y divide-gray-100; + .dropdown-container {} + .dropdown-list-item { + @apply block px-4 py-2 hover:bg-gray-100 cursor-pointer text-lg; + &:hover { + @apply bg-gray-100; + } + } + +} + +/* endregion */ \ No newline at end of file diff --git a/resources/css/shared/footer.css b/resources/css/shared/footer.css new file mode 100644 index 0000000..84b6585 --- /dev/null +++ b/resources/css/shared/footer.css @@ -0,0 +1,6 @@ +.footer-brand { + @apply text-sm text-footer; +} +.footer-nav { + @apply text-sm flex [&>a]:pl-2 [&>a]:pl-4 [&>a]:text-footer [&>a]:hover:text-footer-muted; +} \ No newline at end of file diff --git a/resources/css/shared/form.css b/resources/css/shared/form.css new file mode 100644 index 0000000..44f7850 --- /dev/null +++ b/resources/css/shared/form.css @@ -0,0 +1,28 @@ + + +.form-field{ + @apply mb-5; + +} +.form-label{ + @apply block mb-2 text-sm font-medium text-gray-900 dark:text-white; + +} +.form-input { + @apply bg-bcg-input border focus:outline-none border-bor-input text-input text-sm rounded-sm focus:ring-blue-500 focus:border-bor-input-focus block w-full p-2.5 ; +} + +.form-input.has-icon-start { + @apply ps-10; +} +.form-input.has-icon-end { + @apply pe-10; +} + +.form-error { + @apply block mt-2 text-sm text-red-600 ; +} + +.form-submit { + @apply flex justify-center items-center gap-4; +} \ No newline at end of file diff --git a/resources/css/shared/header.css b/resources/css/shared/header.css new file mode 100644 index 0000000..1591363 --- /dev/null +++ b/resources/css/shared/header.css @@ -0,0 +1,23 @@ +.header-brand{ + @apply flex justify-between items-center gap-6; + .header-logo { + svg { + @apply w-12 h-12; + } + } + .header-slogan { + @apply hidden sm:inline text-header italic; + } + +} +.header-search{ + @apply flex-1 mx-4; +} + +.header-nav{ + a { + &:hover { + @apply text-link-hover; + } + } +} \ No newline at end of file diff --git a/resources/css/shared/jumbotron.css b/resources/css/shared/jumbotron.css new file mode 100644 index 0000000..0d2e82b --- /dev/null +++ b/resources/css/shared/jumbotron.css @@ -0,0 +1,6 @@ +.jumbotron{ + @apply bg-bcg-jumbotron p-8; +} +.jumbotron-inner{ + @apply container mx-auto px-6 ; +} \ No newline at end of file diff --git a/resources/css/shared/page-header.css b/resources/css/shared/page-header.css new file mode 100644 index 0000000..b7c71d1 --- /dev/null +++ b/resources/css/shared/page-header.css @@ -0,0 +1,15 @@ +.page-header { + @apply flex gap-4 flex-col md:flex-row md:items-start mb-4; +} +.page-header-title { + @apply text-3xl mb-2; +} +.pag-header-subtitle { + @apply text-xl mb-2; +} +.page-header-description { + @apply font-bold my-2; +} +.page-header-info { + @apply text-sm mb-3; +} \ No newline at end of file diff --git a/resources/css/shared/panel.css b/resources/css/shared/panel.css new file mode 100644 index 0000000..4ca8c37 --- /dev/null +++ b/resources/css/shared/panel.css @@ -0,0 +1,9 @@ +.panel{ + @apply sm:flex sm:flex-row items-start gap-2 md:gap-4; +} +.panel-header{ + @apply sm:w-1/3; +} +.panel-body{ + @apply sm:w-2/3; +} \ No newline at end of file diff --git a/resources/css/shared/prev-next.css b/resources/css/shared/prev-next.css new file mode 100644 index 0000000..2a89e55 --- /dev/null +++ b/resources/css/shared/prev-next.css @@ -0,0 +1,7 @@ +.prev-next { + @apply flex; +} +.prev-next-prev { +} +.prev-next-next { +} \ No newline at end of file diff --git a/resources/css/shared/search.css b/resources/css/shared/search.css new file mode 100644 index 0000000..10addfb --- /dev/null +++ b/resources/css/shared/search.css @@ -0,0 +1,13 @@ +/* region Search suggestion */ +.search-suggestions { + @apply relative; +} + +.search-suggestions-container { + @apply absolute inset-y-0 end-2.5 flex items-center ps-3.5 pointer-events-none; +} +.search-suggestions-icon { + @apply [&>svg]:text-gray-500; +} + +/* endregion */ \ No newline at end of file diff --git a/resources/css/shared/supplementary.css b/resources/css/shared/supplementary.css new file mode 100644 index 0000000..361e0ed --- /dev/null +++ b/resources/css/shared/supplementary.css @@ -0,0 +1,19 @@ +#supplementary { + @apply p-4 bg-bcg-supplementary border-t border-bor-supplementary; + .supplementary-container { + @apply container mx-auto text-center text-sm p-4 md:flex justify-between items-center text-supplementary; + } + /* region Nav */ + nav { + @apply [&>a]:pl-2; + .title{ + @apply font-bold; + } + a { + @apply text-supplementary; + &:hover { + @apply text-supplementary-muted; + } + } + } +} \ No newline at end of file diff --git a/resources/css/shared/utils.css b/resources/css/shared/utils.css new file mode 100644 index 0000000..0c9183b --- /dev/null +++ b/resources/css/shared/utils.css @@ -0,0 +1,12 @@ +/* region Utils */ +.has-transition{ + @apply transform transition-transform duration-300 hover:scale-110; +} + +.iframe{ + @apply relative pb-[56.25%] pt-8 h-0 overflow-hidden; +} +.iframe iframe{ + @apply absolute top-0 left-0 w-full h-full; +} +/* endregion */ \ No newline at end of file diff --git a/resources/css/theme.css b/resources/css/theme.css new file mode 100644 index 0000000..442446f --- /dev/null +++ b/resources/css/theme.css @@ -0,0 +1,24 @@ +/* By Sheaf.dev */ +@theme inline { + /* base color variables */ + + /* --color-neutral-900: var(--color-neutral-950); */ + + /* primary color varibles */ + --color-primary: var(--color-neutral-800); + --color-primary-content: var(--color-neutral-800); + --color-primary-fg: var(--color-white); + + /* radius variables */ + --radius-field: 0.25rem; + --radius-box: 0.5rem; +} + + +@layer theme { + .dark { + --color-primary: var(--color-white); + --color-primary-content: var(--color-white); + --color-primary-fg: var(--color-neutral-800); + } +} \ No newline at end of file diff --git a/resources/js/app.js b/resources/js/app.js index e69de29..f6b6ce4 100644 --- a/resources/js/app.js +++ b/resources/js/app.js @@ -0,0 +1 @@ +//import './globals/theme.js'; /* By Sheaf.dev */ \ No newline at end of file diff --git a/resources/js/globals/theme.js b/resources/js/globals/theme.js new file mode 100644 index 0000000..01f7da9 --- /dev/null +++ b/resources/js/globals/theme.js @@ -0,0 +1,148 @@ +/** +* Sheaf Dark Mode Theme System +* Provides comprehensive theme management with Alpine.js integration +*/ + +import defineReactiveMagicProperty from '../utils.js'; + +document.addEventListener('alpine:init', () => { + defineReactiveMagicProperty('theme', { + currentTheme: null, + storedTheme: null, + + init() { + // Check localStorage for stored theme preference + this.storedTheme = localStorage.getItem('theme') ?? 'system'; + + // Resolve the configured theme to be only [light, dark] + this.currentTheme = computeTheme(this.storedTheme); + + // Apply initial theme to DOM + applyTheme(this.currentTheme); + + // Listen for system theme changes + const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)'); + mediaQuery.addEventListener('change', (event) => { + if (this.storedTheme === 'system') { + this.currentTheme = event.matches ? 'dark' : 'light'; + applyTheme(this.currentTheme); + } + }); + }, + + /** + * Set theme preference and persist to localStorage + */ + setTheme(newTheme) { + this.storedTheme = newTheme; + localStorage.setItem('theme', newTheme); + + this.currentTheme = computeTheme(newTheme); + applyTheme(this.currentTheme); + }, + + /** + * Theme setter methods + */ + setLight() { + this.setTheme('light'); + }, + + setDark() { + this.setTheme('dark'); + }, + + setSystem() { + this.setTheme('system'); + }, + + /** + * Toggle between light and dark themes + */ + toggle() { + if (this.storedTheme === 'system') { + // If system, toggle to opposite of current computed theme + this.setTheme(this.currentTheme === 'dark' ? 'light' : 'dark'); + } else { + // Toggle between light and dark + this.setTheme(this.storedTheme === 'dark' ? 'light' : 'dark'); + } + }, + + /** + * Get current theme state information + */ + get() { + return { + stored: this.storedTheme, + current: this.currentTheme, + isLight: this.isLight, + isDark: this.isDark, + isSystem: this.isSystem + }; + }, + + // Getter methods for easy template usage + get isLight() { + return this.storedTheme === 'light'; + }, + + get isDark() { + return this.storedTheme === 'dark'; + }, + + get isSystem() { + return this.storedTheme === 'system'; + }, + + /** + * Sometimes we need to show only light or dark, not system mode. + * These getters handle scenarios where we need the resolved theme state. + */ + get isResolvedToLight() { + if (this.isSystem) { + return getSystemTheme() === 'light'; + } + return this.isLight; + }, + + get isResolvedToDark() { + if (this.isSystem) { + return getSystemTheme() === 'dark'; + } + return this.isDark; + } + }); +}); + +/** + * Static helper functions + */ + +function computeTheme(themePreference) { + if (themePreference === 'system') { + return getSystemTheme(); + } + return themePreference; +} + +function getSystemTheme() { + return window.matchMedia('(prefers-color-scheme: dark)').matches + ? 'dark' + : 'light'; +} + +function applyTheme(theme) { + const documentElement = document.documentElement; + + if (theme === 'dark') { + documentElement.classList.add('dark'); + } else { + documentElement.classList.remove('dark'); + } + + // Dispatch custom event for theme change listeners + document.dispatchEvent(new CustomEvent('theme-changed', { + detail: { theme } + })); +} \ No newline at end of file diff --git a/resources/js/utils.js b/resources/js/utils.js new file mode 100644 index 0000000..93bb38a --- /dev/null +++ b/resources/js/utils.js @@ -0,0 +1,22 @@ +/** +* Sheaf Utility Functions +* Provides reactive magic property registration for Alpine.js +*/ + +export default function defineReactiveMagicProperty(name, rawObject) { + const instance = Alpine.reactive(rawObject); + + /** + * Reactive objects are plain proxies and do not support hooks like stores, + * or scopes in Alpine.js so we initialize manually + */ + if (typeof instance.init === 'function') { + instance.init(); + } + + Alpine.magic(name, () => instance); + + // Register the magic property globally + // Ex: if the magic is called \$theme, we register Theme into the window + window[name[0].toUpperCase() + name.slice(1)] = instance; +} \ No newline at end of file diff --git a/resources/views/components/_shared/alert.blade.php b/resources/views/components/_shared/alert.blade.php new file mode 100644 index 0000000..06bf6ed --- /dev/null +++ b/resources/views/components/_shared/alert.blade.php @@ -0,0 +1,3 @@ +
class(['alert'])}} role="alert"> +
{{ $slot }}
+
\ No newline at end of file diff --git a/resources/views/components/_shared/badge.blade.php b/resources/views/components/_shared/badge.blade.php new file mode 100644 index 0000000..590fbcc --- /dev/null +++ b/resources/views/components/_shared/badge.blade.php @@ -0,0 +1,9 @@ +class(['badge'])}}> + + {{ $slot }} + + + @isset($notify) + attributes->class(['badge-notify'])}}>{{$notify}} + @endisset + \ No newline at end of file diff --git a/resources/views/components/_shared/card.blade.php b/resources/views/components/_shared/card.blade.php new file mode 100644 index 0000000..4e8df4f --- /dev/null +++ b/resources/views/components/_shared/card.blade.php @@ -0,0 +1,13 @@ +
class(['card'])}}> + @isset($header) +
attributes->class(['card-header'])}}>{{$header}}
+ @endisset + + @isset($body) +
attributes->class(['card-body'])}}>{{$body}}
+ @endisset + + @isset($footer) +
attributes->class(['card-footer'])}}>{{$footer}}
+ @endisset +
\ No newline at end of file diff --git a/resources/views/components/shared/categories-dropdown.blade.php b/resources/views/components/_shared/categories-dropdown.blade.php similarity index 100% rename from resources/views/components/shared/categories-dropdown.blade.php rename to resources/views/components/_shared/categories-dropdown.blade.php diff --git a/resources/views/components/shared/dropdown.blade.php b/resources/views/components/_shared/dropdown.blade.php similarity index 75% rename from resources/views/components/shared/dropdown.blade.php rename to resources/views/components/_shared/dropdown.blade.php index c3eb2df..82f9227 100644 --- a/resources/views/components/shared/dropdown.blade.php +++ b/resources/views/components/_shared/dropdown.blade.php @@ -10,7 +10,7 @@ @isset($body) -
attributes->class(['absolute left-0 top-full mt-2 w-64 bg-white shadow-lg rounded z-50 max-h-128 overflow-auto divide-y divide-gray-100'])}} +
attributes->class([''])}} x-show="open" x-transition style="display: none;"> diff --git a/resources/views/components/shared/gtag.blade.php b/resources/views/components/_shared/gtag.blade.php similarity index 100% rename from resources/views/components/shared/gtag.blade.php rename to resources/views/components/_shared/gtag.blade.php diff --git a/resources/views/components/shared/iframe.blade.php b/resources/views/components/_shared/iframe.blade.php similarity index 51% rename from resources/views/components/shared/iframe.blade.php rename to resources/views/components/_shared/iframe.blade.php index dd6c9c1..e281fcb 100644 --- a/resources/views/components/shared/iframe.blade.php +++ b/resources/views/components/_shared/iframe.blade.php @@ -1,6 +1,6 @@ @props(['src']) -
class(['relative pb-[56.25%] pt-8 h-0 overflow-hidden'])}}> - +
\ No newline at end of file diff --git a/resources/views/components/ui/my-img-svg/index.blade.php b/resources/views/components/ui/my-img-svg/index.blade.php new file mode 100644 index 0000000..7919b1e --- /dev/null +++ b/resources/views/components/ui/my-img-svg/index.blade.php @@ -0,0 +1,10 @@ +@php + + $img = $img ?? ''; + $fullPath = storage_path(config('myapp.image.svgPath').'/' . $img . '.svg'); +@endphp + +@if(file_exists($fullPath)) + {!! file_get_contents($fullPath) !!} + @endif + \ No newline at end of file diff --git a/resources/views/components/ui/my-jumbotron/index.blade.php b/resources/views/components/ui/my-jumbotron/index.blade.php new file mode 100644 index 0000000..41de710 --- /dev/null +++ b/resources/views/components/ui/my-jumbotron/index.blade.php @@ -0,0 +1,6 @@ + +
class(['bg-white dark:bg-neutral-900'])}}> +
+ {{$slot}} +
+
\ No newline at end of file diff --git a/resources/views/components/ui/my-lightbox/index.blade.php b/resources/views/components/ui/my-lightbox/index.blade.php new file mode 100644 index 0000000..015bc8f --- /dev/null +++ b/resources/views/components/ui/my-lightbox/index.blade.php @@ -0,0 +1,99 @@ +@props(['images']) +@props(['title']) +@isset($images) +
+
+ + +
+ @foreach($images as $index => $item) + + + {{ $item->title}} + + + @endforeach +
+ + +
+
+@endisset \ No newline at end of file diff --git a/resources/views/components/ui/my-modal/index.blade.php b/resources/views/components/ui/my-modal/index.blade.php new file mode 100644 index 0000000..2d38451 --- /dev/null +++ b/resources/views/components/ui/my-modal/index.blade.php @@ -0,0 +1,46 @@ + + + + \ No newline at end of file diff --git a/resources/views/components/shared/page-header.blade.php b/resources/views/components/ui/my-page-header/index.blade.php similarity index 70% rename from resources/views/components/shared/page-header.blade.php rename to resources/views/components/ui/my-page-header/index.blade.php index 52d7fcb..f57b126 100644 --- a/resources/views/components/shared/page-header.blade.php +++ b/resources/views/components/ui/my-page-header/index.blade.php @@ -4,12 +4,11 @@ @endif
@if(!empty($title)) -

attributes->class(['text-3xl mb-2'])}}> - {{ $title }} -

+ {{ $title }} + @endif @if(!empty($subtitle)) -

attributes->class(['text-xl mb-2'])}}>{{ $subtitle }}

+ {{ $subtitle }} @endif @if(!empty($description))
attributes->class(['font-bold my-2'])}}>{{ $description }}
diff --git a/resources/views/components/ui/my-panel/index.blade.php b/resources/views/components/ui/my-panel/index.blade.php new file mode 100644 index 0000000..c7483c8 --- /dev/null +++ b/resources/views/components/ui/my-panel/index.blade.php @@ -0,0 +1,9 @@ +
class(['sm:flex sm:flex-row items-start gap-2 md:gap-4 bg-white dark:bg-neutral-900 border border-black/10 dark:border-white/10 border-bor-base rounded-sm dark:hover:bg-neutral-800'])}}> + @isset($header) +
attributes->class(['sm:w-1/3'])}}>{{$header}}
+ @endisset + + @isset($body) +
attributes->class(['sm:w-2/3'])}}>{{$body}}
+ @endisset +
\ No newline at end of file diff --git a/resources/views/components/ui/my-prev-next/index.blade.php b/resources/views/components/ui/my-prev-next/index.blade.php new file mode 100644 index 0000000..5611a2c --- /dev/null +++ b/resources/views/components/ui/my-prev-next/index.blade.php @@ -0,0 +1,14 @@ + + \ No newline at end of file diff --git a/resources/views/components/ui/navbar/index.blade.php b/resources/views/components/ui/navbar/index.blade.php new file mode 100644 index 0000000..284591d --- /dev/null +++ b/resources/views/components/ui/navbar/index.blade.php @@ -0,0 +1,13 @@ +@php +$classes = [ + 'flex items-center gap-x-2', + 'py-1 px-2' +]; +@endphp + +
class($classes) }} + data-slot="navbar" +> + {{ $slot }} +
\ No newline at end of file diff --git a/resources/views/components/ui/navbar/item.blade.php b/resources/views/components/ui/navbar/item.blade.php new file mode 100644 index 0000000..f8baa12 --- /dev/null +++ b/resources/views/components/ui/navbar/item.blade.php @@ -0,0 +1,75 @@ +@props([ + 'icon' => null, + 'badge' => null, + 'label' => null, + 'href' => null, + 'active' => null +]) + +@php + $classes = [ + 'flex items-center justify-center', + + // active link state + 'data-active-link:bg-[--alpha(var(--color-primary)_/5%)] + data-active-link:!text-[var(--color-primary)] + data-active-link:[&_[data-slot=icon]]:!text-[var(--color-primary)]', + + // add hover state only if the item isn't already active + '[&:not([data-active-link])]:hover:bg-[--alpha(var(--color-primary)_/5%)] + [&:not([data-active-link])]:hover:!text-[var(--color-primary)] + [&:not([data-active-link])]:hover:[&_[data-slot=icon]]:!text-[var(--color-primary)]', + 'dark:text-neutral-200 text-neutral-600', + // icon styles + '[&_[data-slot=icon]]:dark:text-neutral-400 [&_[data-slot=icon]]:text-neutral-600 data-[active-link]:text-[var(--color-primary)]', + + 'px-2 gap-x-1 py-1 rounded-box', + // if there is a badge reduce the right padding for better UI + '[&:has([data-slot=badge])]:pr-1' + ]; + + $iconAttributes = new \Illuminate\View\ComponentAttributeBag(); + $badgeAttributes = new \Illuminate\View\ComponentAttributeBag(); + + foreach ($attributes->getAttributes() as $key => $value) { + if (str_starts_with($key, 'icon:')) { + $iconAttributes[substr($key, 5)] = $value; + } elseif (str_starts_with($key, 'badge:')) { + $badgeAttributes[substr($key, 6)] = $value; + } + } + + // allow other active logic from outside + $active = $active ?? (url($href) === url()->current()); + +@endphp + +when($active, fn($attrs) => $attrs->merge(['data-active-link' => 'true'] )) + ->class($classes) + }} +> + @if($icon) + + @endif + + + {{ $label }} + + + @if($badge) + + {{ $badge }} + + @endif + \ No newline at end of file diff --git a/resources/views/components/ui/navlist/group.blade.php b/resources/views/components/ui/navlist/group.blade.php new file mode 100644 index 0000000..3314fc2 --- /dev/null +++ b/resources/views/components/ui/navlist/group.blade.php @@ -0,0 +1,39 @@ +@props([ + 'collapsable' => false, + 'variant' => 'default', + 'label' => false +]) + +@php + +$classes = [ + 'flex flex-col gap-y-1' +]; +@endphp + +
class($classes) }} + data-slot="navlist-group" + x-data="{ + expanded: true, + expand(){ + this.expanded = !this.expanded; + } + }" +> + @switch($variant) + @case('compact') + + {{ $slot }} + + @break + @default + + {{ $slot }} + + @endswitch +
\ No newline at end of file diff --git a/resources/views/components/ui/navlist/group/variant/compact.blade.php b/resources/views/components/ui/navlist/group/variant/compact.blade.php new file mode 100644 index 0000000..42dffcf --- /dev/null +++ b/resources/views/components/ui/navlist/group/variant/compact.blade.php @@ -0,0 +1,59 @@ +@aware([ + 'collapsable' => true, + 'variant' => 'default', + 'label' => null, + 'icon' => null, +]) + +
+
+ + +
+ + +
+ +
+ {{ $slot }} +
\ No newline at end of file diff --git a/resources/views/components/ui/navlist/group/variant/default.blade.php b/resources/views/components/ui/navlist/group/variant/default.blade.php new file mode 100644 index 0000000..5b39845 --- /dev/null +++ b/resources/views/components/ui/navlist/group/variant/default.blade.php @@ -0,0 +1,59 @@ +@aware([ + 'collapsable' => true, + 'variant' => 'default', + 'label' => null, + 'icon' => null, +]) + +
+
$icon + ])> + @if ($icon) + + @endif + +

{{ $label }}

+
+ + @if ($collapsable) + + @endif +
+ +
+ {{ $slot }} +
\ No newline at end of file diff --git a/resources/views/components/ui/navlist/has-tooltip.blade.php b/resources/views/components/ui/navlist/has-tooltip.blade.php new file mode 100644 index 0000000..1e4a9e5 --- /dev/null +++ b/resources/views/components/ui/navlist/has-tooltip.blade.php @@ -0,0 +1,69 @@ +@props(['tooltip' => null, 'condition' => false]) + +@if ($condition) +{{-- + Sidebar tooltips inside scrollable containers (overflow-auto) create a new stacking context. + This means a normal absolute/fixed tooltip would be clipped or mispositioned. + To fix this, we dynamically append the tooltip to so it always floats on top and is not bound by the sidebar's box. +--}} + +
+ {{ $slot }} +
+@else + {{ $slot }} +@endif \ No newline at end of file diff --git a/resources/views/components/ui/navlist/index.blade.php b/resources/views/components/ui/navlist/index.blade.php new file mode 100644 index 0000000..0b283ee --- /dev/null +++ b/resources/views/components/ui/navlist/index.blade.php @@ -0,0 +1,13 @@ +@php + $classes = [ + 'flex flex-col w-full [:has([data-collapsed]_&)_&]:items-center gap-y-1', + 'py-1 px-2' + ]; +@endphp + +
class($classes) }} + data-slot="navlist" +> + {{ $slot }} +
\ No newline at end of file diff --git a/resources/views/components/ui/navlist/item.blade.php b/resources/views/components/ui/navlist/item.blade.php new file mode 100644 index 0000000..1b6bc31 --- /dev/null +++ b/resources/views/components/ui/navlist/item.blade.php @@ -0,0 +1,94 @@ +@aware([ + 'collapsible' => true +]) +@props([ + 'icon' => null, + 'badge' => null, + 'label' => null, + 'href' => '#', + 'active' => null +]) + +@php + // quick reference : + // [:not(:has([data-collapsed]_&))_&]: means if the sidebar is not collapsed + // [:has([data-collapsed]_&)_&]: means if the sidebar is collapsed + + $classes = [ + 'isolate', + 'flex items-center [:where(&)]:justify-start', + // When collapsed: center the content + '[:has([data-collapsed]_&)_&]:justify-center', + + // active link state + 'data-active-link:bg-[--alpha(var(--color-primary)_/5%)] + data-active-link:!text-[var(--color-primary)] + data-active-link:[&_[data-slot=icon]]:!text-[var(--color-primary)]', + + // add hover state only if the item isn't already active + '[&:not([data-active-link])]:hover:bg-[--alpha(var(--color-primary)_/5%)] + [&:not([data-active-link])]:hover:!text-[var(--color-primary)] + [&:not([data-active-link])]:hover:[&_[data-slot=icon]]:!text-[var(--color-primary)]', + // text styles + 'dark:text-neutral-400 text-neutral-600', + // icon styles + '[&_[data-slot=icon]]:dark:text-neutral-400 + [&_[data-slot=icon]]:text-neutral-600 + data-[active-link]:text-[var(--color-primary)]', + // gaps and padding + 'gap-x-2 pl-3 pr-1 py-1 rounded-box', + // When collapsed: remove horizontal padding, keep vertical padding for centering + '[:has([data-collapsed]_&)_&]:p-2', + ]; + + + $iconAttributes = new \Illuminate\View\ComponentAttributeBag(); + $badgeAttributes = new \Illuminate\View\ComponentAttributeBag(); + + foreach ($attributes->getAttributes() as $key => $value) { + if (str_starts_with($key, 'icon:')) { + $iconAttributes[substr($key, 5)] = $value; + } elseif (str_starts_with($key, 'badge:')) { + $badgeAttributes[substr($key, 6)] = $value; + } + } + + // allow other active logic from outside + $active = $active ?? (url($href) === url()->current()); + +@endphp +class($classes) }} +> + @if($icon) + + + + @endif + + + {{ $label }} + + + @if($badge) + {{ $badge }} + @endif + \ No newline at end of file diff --git a/resources/views/components/ui/popup.blade.php b/resources/views/components/ui/popup.blade.php new file mode 100644 index 0000000..dd00b09 --- /dev/null +++ b/resources/views/components/ui/popup.blade.php @@ -0,0 +1,46 @@ +{{-- + A helper to unify popover-like components (popover, dropdown, select, autocomplete, etc.) + + The key challenge: Alpine’s `x-show` directive toggles element visibility by + mutating DOM styles and setting an internal `_x_isShown` flag. That flag is not + reactive by default, so we can’t `$watch` it directly. + + This component bridges that gap by: + - Mirroring `_x_isShown` into a reactive `shown` state (inside `x-data`) + - Using a MutationObserver to watch style changes applied by `x-show` + - Keeping `shown` in sync so we can reactively trap focus, model, or trigger side-effects + + With this, when the popup is opened (parent’s `x-show` → true): + - `shown` updates automatically (shown → true) + - We can use it to focus the popup (once it opens), trap keyboard navigation, or dispatch events +--}} + +@props([ + 'autofocus' => true +]) + +
class(["absolute z-50 bg-white w-full dark:bg-neutral-800 mt-1 backdrop-blur-xl border dark:border-neutral-700 border-neutral-200 rounded-(--popup-round) shadow-lg p-(--popup-padding)"]) }} + x-transition:enter="transition ease-out duration-200" + x-transition:enter-start="opacity-0 transform scale-95" + x-transition:enter-end="opacity-100 transform scale-100" + x-transition:leave="transition ease-in duration-150" + x-transition:leave-start="opacity-100 transform scale-100" + x-transition:leave-end="opacity-0 transform scale-95" + style="display:none;" {{-- avoid flickering --}} +> + {{ $slot }} +
\ No newline at end of file diff --git a/resources/views/components/ui/sidebar/index.blade.php b/resources/views/components/ui/sidebar/index.blade.php new file mode 100644 index 0000000..abc32b1 --- /dev/null +++ b/resources/views/components/ui/sidebar/index.blade.php @@ -0,0 +1,156 @@ +{{-- + ╔═══════════════════════════════════════════════════════════════════════════════╗ + ║ SIDEBAR COMPONENT ║ + ║ ║ + ║ A responsive sidebar that adapts to different screen sizes: ║ + ║ • Mobile (< 768px): Overlay sidebar with backdrop ║ + ║ • Tablet (768px-1024px): Always collapsed, visible sidebar ║ + ║ • Desktop (>= 1024px): Expandable/collapsible sidebar ║ + ║ ║ + ║ Features: ║ + ║ • Touch device support (tap anywhere to toggle on tablets) ║ + ║ • Sticky header option ║ + ║ • Scrollable content area ║ + ║ • Brand/logo slot ║ + ║ • Toggle button with auto-hide on collapse ║ + ╚═══════════════════════════════════════════════════════════════════════════════╝ +--}} + + +@aware([ + 'collapsable' => true, +]) + +{{-- + ┌─────────────────────────────────────────────────────────────────────────────┐ + │ COMPONENT PROPS │ + │ │ + │ @param bool $stickyHeader - Makes the sidebar header stick to top on scroll │ + │ @param bool $scrollable - Enables vertical scrolling for sidebar content │ + │ @param bool $collapsable - Allows sidebar to be collapsed/expanded │ + │ @param string $brand - Brand name/logo content │ + └─────────────────────────────────────────────────────────────────────────────┘ +--}} + +@props([ + 'stickyHeader' => true, + 'scrollable' => true, + 'collapsable' => true, + 'brand' => null +]) + +@php + $classes = [ + 'isolate', + '[grid-area:sidebar]', + 'z-40 dark:bg-neutral-950 bg-white lg:block', + 'border-r dark:border-white/5 border-black/5', + 'transition-[width] duration-500', + 'overflow-x-visible', + '!overflow-y-auto' => $scrollable, // Only make scrollable if needed + ]; +@endphp + +{{-- + ┌─────────────────────────────────────────────────────────────────────────────┐ + │ SIDEBAR CONTAINER │ + │ │ + │ data-slot="sidebar" - Used by parent layout for CSS targeting │ + │ style="z-index:9999" - Ensures sidebar stays above other content │ + └─────────────────────────────────────────────────────────────────────────────┘ +--}} +
class($classes) }} + data-slot="sidebar" + style="z-index:99;" + @if ($collapsable) + x-data="{ + collapsable: @js($collapsable) + }" + @endif + + {{-- + ┌─────────────────────────────────────────────────────────────────────────┐ + │ TOUCH DEVICE INTERACTION │ + │ │ + │ On touch devices (tablets), clicking anywhere on sidebar toggles it │ + │ EXCEPT when clicking: │ + │ • The brand/logo area │ + │ • The toggle button itself │ + │ • On mobile devices (uses overlay instead) │ + │ │ + │ Why? Better UX on tablets where hover doesn't exist │ + └─────────────────────────────────────────────────────────────────────────┘ + --}} + x-init=" + if(window.matchMedia('(pointer: coarse)').matches) { + $el.addEventListener('click', (event) => { + // Don't toggle if clicking brand area + if(event.target.closest('[data-slot=sidebar-brand]')) { + return; + } + + // Don't toggle if clicking the toggle button + if(event.target.closest('[data-slot=sidebar-toggle]')) { + return; + } + + // Don't toggle on mobile (uses overlay mode) + if($data.isMobile) { + return; + } + + // Toggle collapse state + toggle(); + }); + } + " +> + @if(filled($brand)) +
$stickyHeader, + ]) + > +
$collapsable + ]) + data-slot="sidebar-brand" + > + {{ $brand }} +
+ + @if ($collapsable) + + @endif +
+ @endif + +
$stickyHeader, + ]) + > + {{ $slot }} +
+
\ No newline at end of file diff --git a/resources/views/components/ui/sidebar/push.blade.php b/resources/views/components/ui/sidebar/push.blade.php new file mode 100644 index 0000000..ec7dc85 --- /dev/null +++ b/resources/views/components/ui/sidebar/push.blade.php @@ -0,0 +1 @@ +
class('flex-1 pointer-events-none') }} data-slot="sidebar-spacer">
\ No newline at end of file diff --git a/resources/views/components/ui/sidebar/toggle.blade.php b/resources/views/components/ui/sidebar/toggle.blade.php new file mode 100644 index 0000000..9aeed46 --- /dev/null +++ b/resources/views/components/ui/sidebar/toggle.blade.php @@ -0,0 +1,30 @@ +@props([ + 'tooltip'=>null +]) + + + + + + diff --git a/resources/views/components/ui/text.blade.php b/resources/views/components/ui/text.blade.php new file mode 100644 index 0000000..1826781 --- /dev/null +++ b/resources/views/components/ui/text.blade.php @@ -0,0 +1,6 @@ +
class('text-neutral-950 [:where(&)]:text-sm [:where(&)]:text-start dark:text-neutral-50') }} + data-slot="text" +> + {{ $slot }} +
\ No newline at end of file diff --git a/resources/views/components/ui/textarea/index.blade.php b/resources/views/components/ui/textarea/index.blade.php new file mode 100644 index 0000000..f997811 --- /dev/null +++ b/resources/views/components/ui/textarea/index.blade.php @@ -0,0 +1,105 @@ + +@props([ + 'disabled' => false, + 'resize' => 'vertical', + 'name' => $attributes->whereStartsWith('wire:model')->first() ?? $attributes->whereStartsWith('x-model')->first(), + 'rows' => null, + 'invalid' => null, + ]) +@php + $rows ??= 3; + + $initialHeight = (($rows) * 1.5) + 0.75; + + $classes = [ + // Text colors + 'inline-block p-2 w-full text-base sm:text-sm text-neutral-800 disabled:text-neutral-500 placeholder-neutral-400 disabled:placeholder-neutral-400/70 dark:text-neutral-300 dark:disabled:text-neutral-400 dark:placeholder-neutral-400 dark:disabled:placeholder-neutral-500', + + // Background + 'bg-white dark:bg-neutral-900 dark:disabled:bg-neutral-800', + + // Cursor and transitions + 'disabled:cursor-not-allowed transition-colors duration-200', + + // Shadows and borders + 'shadow-sm disabled:shadow-none border rounded-box', + + // Focus outline + 'focus:ring-2 focus:ring-offset-0 focus:outline-none', + + // Normal state borders and focus rings + 'border-black/10 focus:border-black/15 focus:ring-neutral-900/15 dark:border-white/10 dark:focus:border-white/20 dark:focus:ring-neutral-100/15' => !$invalid, + + // Invalid state borders and focus rings + 'border-red-500 focus:border-red-500 focus:ring-red-500/25 dark:border-red-400 dark:focus:border-red-400 dark:focus:ring-red-400/25' => $invalid, + + // Resize handling + match ($resize) { + 'none' => 'resize-none', + 'both' => 'resize', + 'horizontal' => 'resize-x', + 'vertical' => 'resize-y', + }, + ]; +@endphp + + + diff --git "a/resources/views/components/widgets/\342\232\241categories-dropdown/categories-dropdown.blade.php" "b/resources/views/components/widgets/\342\232\241categories-dropdown/categories-dropdown.blade.php" deleted file mode 100644 index 41c4aa8..0000000 --- "a/resources/views/components/widgets/\342\232\241categories-dropdown/categories-dropdown.blade.php" +++ /dev/null @@ -1,34 +0,0 @@ -@if($categories->isNotEmpty()) - - - - {{ __($label) }} - - - - - - - - - -@endif \ No newline at end of file diff --git "a/resources/views/components/widgets/\342\232\241categories-dropdown/categories-dropdown.php" "b/resources/views/components/widgets/\342\232\241categories-dropdown/categories-dropdown.php" deleted file mode 100644 index 37c1f71..0000000 --- "a/resources/views/components/widgets/\342\232\241categories-dropdown/categories-dropdown.php" +++ /dev/null @@ -1,35 +0,0 @@ -value, - string $route = 'articleIndex', - string $label = 'articleCategories', - ?string $currentCategory = null - ) { - $this->type = $type; - $this->route = $route; - $this->label = $label; - $this->currentCategory = $currentCategory ?? request()->query('category'); - } - - public function render() - { - $categories = Category::publishedByType($this->type) - ->withCount('contents')->where('contents_count','>',0)->get(); - - return view('components.widgets.⚡categories-dropdown.categories-dropdown', [ - 'categories' => $categories, - ]); - } -}; \ No newline at end of file diff --git "a/resources/views/components/widgets/\342\232\241contact-form/contact-form.blade.php" "b/resources/views/components/widgets/\342\232\241contact-form/contact-form.blade.php" index 22682f2..f88eb3e 100644 --- "a/resources/views/components/widgets/\342\232\241contact-form/contact-form.blade.php" +++ "b/resources/views/components/widgets/\342\232\241contact-form/contact-form.blade.php" @@ -1,51 +1,49 @@ -
+
@if ($errorMessage) - {{ $errorMessage }} + + {{ $errorMessage }} + @endif @if (session()->has('success')) - {{ session('success') }} + + {{ session('success') }} + @endif
-
- - + + {{__('app.form.name')}} + - @error('name') {{ $message }} @enderror -
-
- - + + + + {{__('app.form.email')}} + - @error('email') {{ $message }} @enderror -
-
- - - @error('message') {{ $message }} @enderror -
-
- + /> + + + + + +
+ {{__('app.form.submit')}}
+
\ No newline at end of file diff --git "a/resources/views/components/widgets/\342\232\241search-suggestion/search-suggestion-bck.blade.php" "b/resources/views/components/widgets/\342\232\241search-suggestion/search-suggestion-bck.blade.php" new file mode 100644 index 0000000..0780743 --- /dev/null +++ "b/resources/views/components/widgets/\342\232\241search-suggestion/search-suggestion-bck.blade.php" @@ -0,0 +1,40 @@ + + + +
+
+ +
+ +
+
+ {{-- The dropdown with the search results. + It is only shown if the query is not empty and there are search results. --}} + @if(!empty($query) && !empty($results)) + + + + @endif +
\ No newline at end of file diff --git "a/resources/views/components/widgets/\342\232\241search-suggestion/search-suggestion.blade.php" "b/resources/views/components/widgets/\342\232\241search-suggestion/search-suggestion.blade.php" index 71893bc..911a52d 100644 --- "a/resources/views/components/widgets/\342\232\241search-suggestion/search-suggestion.blade.php" +++ "b/resources/views/components/widgets/\342\232\241search-suggestion/search-suggestion.blade.php" @@ -1,12 +1,8 @@ - +
-
- -
-
{{-- The dropdown with the search results. It is only shown if the query is not empty and there are search results. --}} @if(!empty($query) && !empty($results)) - -
- {{__('app.nav.readMore')}} + {{__('app.nav.readMore')}} » From 28a74eaee9d568a82ec048fb0d9a99e1abab2c62 Mon Sep 17 00:00:00 2001 From: Martin Vach Date: Mon, 11 May 2026 19:46:37 +0200 Subject: [PATCH 057/103] Replacing buttons --- resources/css/shared/button.css | 13 +++++++------ resources/css/vades/app.css | 1 + .../components/default/home/articles.blade.php | 7 +++---- .../views/components/default/home/hero.blade.php | 4 ++-- .../components/default/home/photo-gallery.blade.php | 7 +++---- .../views/components/default/home/places.blade.php | 12 +++++------- .../default/partials/header/nav-sm.blade.php | 4 ++-- .../views/components/default/place/index.blade.php | 4 ++-- .../views/components/ui/my-card/article.blade.php | 2 +- .../components/ui/my-prev-next/index.blade.php | 4 ++-- .../views/components/vades/home/hero.blade.php | 4 ++-- 11 files changed, 30 insertions(+), 32 deletions(-) diff --git a/resources/css/shared/button.css b/resources/css/shared/button.css index 67f9348..730a155 100644 --- a/resources/css/shared/button.css +++ b/resources/css/shared/button.css @@ -1,11 +1,12 @@ /* region Button */ -.button { - @apply py-2.5 px-5 me-2 mb-2 text-btn focus:outline-none bg-bcg-btn rounded-sm border border-bor-btn hover:bg-bcg-btn-hover hover:text-btn-hover focus:z-10 focus:ring-4 focus:ring-gray-100 cursor-pointer; +.my-btn-raquo::after { + content: '\00BB'; + @apply inline-block; } -.button-secondary { - @apply focus:outline-none text-white bg-bcg-secondary hover:bg-bcg-secondary-muted focus:ring-4 focus:ring-green-300 font-medium rounded-lg text-sm px-5 py-2.5 me-2 mb-2 cursor-pointer; +.my-btn-laquo::before { + content: '\00AB'; + @apply inline-block; } - -/* endregion */ \ No newline at end of file +/* endregion */ diff --git a/resources/css/vades/app.css b/resources/css/vades/app.css index d88578b..261b598 100644 --- a/resources/css/vades/app.css +++ b/resources/css/vades/app.css @@ -17,6 +17,7 @@ @import '../shared/panel.css'; @import '../shared/prev-next.css'; @import '../shared/iframe.css'; +@import '../shared/button.css'; @import './custom.css'; /** diff --git a/resources/views/components/default/home/articles.blade.php b/resources/views/components/default/home/articles.blade.php index dc80e89..13acd88 100644 --- a/resources/views/components/default/home/articles.blade.php +++ b/resources/views/components/default/home/articles.blade.php @@ -12,7 +12,6 @@ class="!text-center">{{__('app.nav.recentPosts')}} @endforeach
- {{__('app.nav.allArticles')}} -
\ No newline at end of file + {>{{__('app.nav.allArticles')}} +
diff --git a/resources/views/components/default/home/hero.blade.php b/resources/views/components/default/home/hero.blade.php index b5af2eb..5724683 100644 --- a/resources/views/components/default/home/hero.blade.php +++ b/resources/views/components/default/home/hero.blade.php @@ -1,6 +1,6 @@
class(['text-center my-10'])}}>

{{$page->title}}

{{$page->excerpt}}
-
{{__('app.nav.readMoreAbout',['about'=> 'Nuremberg'])}}
+ -
\ No newline at end of file + diff --git a/resources/views/components/default/home/photo-gallery.blade.php b/resources/views/components/default/home/photo-gallery.blade.php index 7fca27b..30ee785 100644 --- a/resources/views/components/default/home/photo-gallery.blade.php +++ b/resources/views/components/default/home/photo-gallery.blade.php @@ -14,7 +14,6 @@ class="overflow-hidden rounded-md">
- {{__('app.nav.allImages')}} -
\ No newline at end of file + {>{{__('app.nav.allImages')}} +
diff --git a/resources/views/components/default/home/places.blade.php b/resources/views/components/default/home/places.blade.php index 9fb7524..07a1c27 100644 --- a/resources/views/components/default/home/places.blade.php +++ b/resources/views/components/default/home/places.blade.php @@ -18,16 +18,14 @@ class="!text-center">{{__('app.nav.otherPlaces')}} {{ $item->title }} - {{__('app.nav.readMore')}} + {>{{__('app.nav.readMore')}} @endforeach
- {{__('app.nav.allPlaces')}} -
\ No newline at end of file + {>{{__('app.nav.allPlaces')}} + diff --git a/resources/views/components/default/partials/header/nav-sm.blade.php b/resources/views/components/default/partials/header/nav-sm.blade.php index a96c7ee..ba92a47 100644 --- a/resources/views/components/default/partials/header/nav-sm.blade.php +++ b/resources/views/components/default/partials/header/nav-sm.blade.php @@ -1,7 +1,7 @@
- + { @click="drawerOpen = true">
@@ -19,7 +19,7 @@ class="fixed top-0 right-0 z-40 h-screen p-4 overflow-y-auto bg-white w-80 dark: style="display: none;">
Menu
- + { @click="drawerOpen = false">
@foreach(config('myapp.drawerNav') as $key => $val) diff --git a/resources/views/components/default/place/index.blade.php b/resources/views/components/default/place/index.blade.php index c628a14..f95962c 100644 --- a/resources/views/components/default/place/index.blade.php +++ b/resources/views/components/default/place/index.blade.php @@ -33,7 +33,7 @@
- {{__('app.nav.readMore')}} + {{__('app.nav.readMore')}} @@ -45,4 +45,4 @@ {{-- --}} - \ No newline at end of file + diff --git a/resources/views/components/ui/my-card/article.blade.php b/resources/views/components/ui/my-card/article.blade.php index 1a54e84..4810d03 100644 --- a/resources/views/components/ui/my-card/article.blade.php +++ b/resources/views/components/ui/my-card/article.blade.php @@ -15,6 +15,6 @@ - {{__('app.nav.readMore')}} » + {{__('app.nav.readMore')}} diff --git a/resources/views/components/ui/my-prev-next/index.blade.php b/resources/views/components/ui/my-prev-next/index.blade.php index 2d173ab..aae0849 100644 --- a/resources/views/components/ui/my-prev-next/index.blade.php +++ b/resources/views/components/ui/my-prev-next/index.blade.php @@ -3,12 +3,12 @@ aria-label="Previous and next links"> @if(isset($prevUrl)) - {{__('app.nav.previous')}} + {{__('app.nav.previous')}} @endif @if(isset($nextUrl)) - {{__('app.nav.next')}} + {{__('app.nav.next')}} @endif diff --git a/resources/views/components/vades/home/hero.blade.php b/resources/views/components/vades/home/hero.blade.php index af1ebf4..5197562 100644 --- a/resources/views/components/vades/home/hero.blade.php +++ b/resources/views/components/vades/home/hero.blade.php @@ -1,6 +1,6 @@
class(['text-center'])}}>

{{$page->title}}

{{$page->excerpt}}
-
{{__('app.nav.readMoreAbout',['about'=> 'Nuremberg'])}}
+ -
\ No newline at end of file + From 8958410e6e8dd55c7186979c0dc5039bba0b9831 Mon Sep 17 00:00:00 2001 From: Martin Vach Date: Mon, 11 May 2026 20:06:22 +0200 Subject: [PATCH 058/103] Replacing buttons --- .../components/default/partials/header/nav-lg.blade.php | 2 +- .../components/default/partials/header/nav-sm.blade.php | 4 ++-- resources/views/components/vades/home/articles.blade.php | 6 +++--- resources/views/components/vades/home/hero.blade.php | 2 +- .../\342\232\241contact-form/contact-form.blade.php" | 4 ++-- storage/app/public/images/svg/bars-3.svg | 3 +++ 6 files changed, 12 insertions(+), 9 deletions(-) create mode 100644 storage/app/public/images/svg/bars-3.svg diff --git a/resources/views/components/default/partials/header/nav-lg.blade.php b/resources/views/components/default/partials/header/nav-lg.blade.php index d8665df..ef8d858 100644 --- a/resources/views/components/default/partials/header/nav-lg.blade.php +++ b/resources/views/components/default/partials/header/nav-lg.blade.php @@ -1,6 +1,6 @@