diff --git a/app/Http/Controllers/Api/EventPublicController.php b/app/Http/Controllers/Api/EventPublicController.php index 7e308a7..8d3a97f 100644 --- a/app/Http/Controllers/Api/EventPublicController.php +++ b/app/Http/Controllers/Api/EventPublicController.php @@ -292,7 +292,7 @@ class EventPublicController extends BaseController } if ($since) { - $query->where('created_at', '>', $since); + $query->where('photos.created_at', '>', $since); } $locale = request()->query('locale', 'de'); diff --git a/app/Http/Controllers/MarketingController.php b/app/Http/Controllers/MarketingController.php index f45323c..3071ef6 100644 --- a/app/Http/Controllers/MarketingController.php +++ b/app/Http/Controllers/MarketingController.php @@ -127,6 +127,34 @@ class MarketingController extends Controller return view('marketing.success', ['provider' => 'Stripe']); } + public function blogIndex(Request $request) + { + $locale = $request->get('locale', app()->getLocale()); + $posts = \Stephenjude\FilamentBlog\Models\Post::query() + ->where('is_published', true) + ->whereNotNull('published_at') + ->where('published_at', '<=', now()) + ->whereJsonContains("translations->locale->title->{$locale}", true) + ->orderBy('published_at', 'desc') + ->paginate(8); + + return view('marketing.blog', compact('posts')); + } + + public function blogShow($slug) + { + $locale = app()->getLocale(); + $post = \Stephenjude\FilamentBlog\Models\Post::query() + ->where('slug', $slug) + ->where('is_published', true) + ->whereNotNull('published_at') + ->where('published_at', '<=', now()) + ->whereJsonContains("translations->locale->title->{$locale}", true) + ->firstOrFail(); + + return view('marketing.blog-show', compact('post')); + } + public function paypalCheckout(Request $request, $package) { $packages = [ diff --git a/app/Http/Middleware/SetLocale.php b/app/Http/Middleware/SetLocale.php new file mode 100644 index 0000000..03299f4 --- /dev/null +++ b/app/Http/Middleware/SetLocale.php @@ -0,0 +1,32 @@ +segment(1); + + $supportedLocales = ['de', 'en']; + + if (in_array($locale, $supportedLocales)) { + app()->setLocale($locale); + session()->put('locale', $locale); + } else { + $locale = session('locale', config('app.locale', 'de')); + app()->setLocale($locale); + } + + return $next($request); + } +} diff --git a/app/Http/Middleware/SuperAdminAuth.php b/app/Http/Middleware/SuperAdminAuth.php new file mode 100644 index 0000000..1678b31 --- /dev/null +++ b/app/Http/Middleware/SuperAdminAuth.php @@ -0,0 +1,37 @@ +is('super-admin/login') || $request->is('super-admin/register')) { + return $next($request); + } + + if (!Auth::check()) { + abort(403, 'Nicht angemeldet.'); + } + + $user = Auth::user(); + Log::info('SuperAdminAuth: User ID ' . $user->id . ', role: ' . $user->role); + + if ($user->role !== 'super_admin') { + abort(403, 'Zugriff nur für SuperAdmin. User ID: ' . $user->id . ', Role: ' . $user->role); + } + + return $next($request); + } +} \ No newline at end of file diff --git a/app/Models/BlogCategory.php b/app/Models/BlogCategory.php new file mode 100644 index 0000000..6cf89b6 --- /dev/null +++ b/app/Models/BlogCategory.php @@ -0,0 +1,25 @@ +by('oauth:' . ($request->ip() ?? 'unknown')); }); + + if ($this->app->runningInConsole()) { + $this->app->register(\App\Providers\Filament\AdminPanelProvider::class); + } } } diff --git a/app/Providers/Filament/AdminPanelProvider.php b/app/Providers/Filament/AdminPanelProvider.php new file mode 100644 index 0000000..bfd0360 --- /dev/null +++ b/app/Providers/Filament/AdminPanelProvider.php @@ -0,0 +1,69 @@ +default() + ->id('admin') + ->path('admin') + ->login() + ->colors([ + 'primary' => Color::Pink, + ]) + ->discoverResources(in: app_path('Filament/Resources'), for: 'App\\Filament\\Resources') + ->discoverPages(in: app_path('Filament/Pages'), for: 'App\\Filament\\Pages') + ->pages([ + Pages\Dashboard::class, + ]) + ->discoverWidgets(in: app_path('Filament/Widgets'), for: 'App\\Filament\\Widgets') + ->widgets([ + Widgets\AccountWidget::class, + Widgets\FilamentInfoWidget::class, + ]) + ->middleware([ + EncryptCookies::class, + AddQueuedCookiesToResponse::class, + StartSession::class, + AuthenticateSession::class, + ShareErrorsFromSession::class, + VerifyCsrfToken::class, + SubstituteBindings::class, + DisableBladeIconComponents::class, + DispatchServingFilamentEvent::class, + ]) + ->authMiddleware([ + Authenticate::class, + ]) + ->resources([ + // Blog-Resources moved to SuperAdminPanel + ]) + // Remove blog models as they are global and handled in SuperAdmin + ; + } +} \ No newline at end of file diff --git a/app/Providers/Filament/SuperAdminPanelProvider.php b/app/Providers/Filament/SuperAdminPanelProvider.php index da76f47..62c6c6c 100644 --- a/app/Providers/Filament/SuperAdminPanelProvider.php +++ b/app/Providers/Filament/SuperAdminPanelProvider.php @@ -3,21 +3,33 @@ namespace App\Providers\Filament; use Filament\Http\Middleware\Authenticate; -use Filament\Http\Middleware\AuthenticateSession; use Filament\Http\Middleware\DisableBladeIconComponents; use Filament\Http\Middleware\DispatchServingFilamentEvent; -use Filament\Pages\Dashboard; +use Filament\Pages; use Filament\Panel; use Filament\PanelProvider; use Filament\Support\Colors\Color; -use Filament\Widgets\AccountWidget; -use Filament\Widgets\FilamentInfoWidget; +use Filament\Widgets; use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse; use Illuminate\Cookie\Middleware\EncryptCookies; use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken; use Illuminate\Routing\Middleware\SubstituteBindings; +use Illuminate\Session\Middleware\AuthenticateSession; use Illuminate\Session\Middleware\StartSession; use Illuminate\View\Middleware\ShareErrorsFromSession; +use App\Filament\Resources\LegalPageResource; +use App\Filament\Resources\TenantResource; +use App\Filament\Pages\SuperAdminProfile; +use App\Models\User; +use App\Models\Tenant; +use App\Models\BlogPost; +use App\Models\BlogCategory; +use App\Models\BlogTag; +use App\Filament\Widgets\PlatformStatsWidget; +use App\Filament\Widgets\TopTenantsByUploads; +use Stephenjude\FilamentBlog\Filament\Resources\CategoryResource; +use Stephenjude\FilamentBlog\Filament\Resources\PostResource; +use Stephenjude\FilamentBlog\BlogPlugin; class SuperAdminPanelProvider extends PanelProvider { @@ -25,26 +37,27 @@ class SuperAdminPanelProvider extends PanelProvider { return $panel ->default() - ->id('super-admin') + ->id('superadmin') ->path('super-admin') - ->profile(\App\Filament\Pages\SuperAdminProfile::class, true) + ->login() ->colors([ - 'primary' => Color::Amber, + 'primary' => Color::Pink, ]) - ->discoverResources(in: app_path('Filament/Resources'), for: 'App\Filament\Resources') - ->discoverPages(in: app_path('Filament/Pages'), for: 'App\Filament\Pages') + ->discoverResources(in: app_path('Filament/Resources'), for: 'App\\Filament\\Resources') + ->discoverPages(in: app_path('Filament/Pages'), for: 'App\\Filament\\Pages') ->pages([ - Dashboard::class, + Pages\Dashboard::class, ]) - ->discoverWidgets(in: app_path('Filament/Widgets'), for: 'App\Filament\Widgets') + ->plugin( + BlogPlugin::make() + ) + ->profile(SuperAdminProfile::class) + ->discoverWidgets(in: app_path('Filament/Widgets'), for: 'App\\Filament\\Widgets') ->widgets([ - AccountWidget::class, - FilamentInfoWidget::class, - \App\Filament\Widgets\PlatformStatsWidget::class, - \App\Filament\Widgets\UploadsPerDayChart::class, - \App\Filament\Widgets\RecentPhotosTable::class, - \App\Filament\Widgets\TopTenantsByUploads::class, - \App\Filament\Widgets\EventsActiveToday::class, + Widgets\AccountWidget::class, + Widgets\FilamentInfoWidget::class, + PlatformStatsWidget::class, + TopTenantsByUploads::class, ]) ->middleware([ EncryptCookies::class, @@ -59,6 +72,18 @@ class SuperAdminPanelProvider extends PanelProvider ]) ->authMiddleware([ Authenticate::class, - ]); + ]) + ->resources([ + TenantResource::class, + LegalPageResource::class, + ]) + ->authMiddleware([ + Authenticate::class, + 'superadmin.auth', + ]) + ->authGuard('web') + // SuperAdmin-Zugriff durch custom Middleware, globale Sichtbarkeit ohne Tenant-Isolation + // Blog-Resources werden durch das Plugin-ServiceProvider automatisch registriert + ; } } diff --git a/bootstrap/app.php b/bootstrap/app.php index 9911a78..7a2ebe6 100644 --- a/bootstrap/app.php +++ b/bootstrap/app.php @@ -23,11 +23,14 @@ return Application::configure(basePath: dirname(__DIR__)) 'tenant.token' => TenantTokenGuard::class, 'tenant.isolation' => TenantIsolation::class, 'credit.check' => CreditCheckMiddleware::class, + 'locale' => \App\Http\Middleware\SetLocale::class, + 'superadmin.auth' => \App\Http\Middleware\SuperAdminAuth::class, ]); $middleware->encryptCookies(except: ['appearance', 'sidebar_state']); $middleware->web(append: [ + \App\Http\Middleware\SetLocale::class, SetLocaleFromUser::class, HandleAppearance::class, HandleInertiaRequests::class, diff --git a/bootstrap/providers.php b/bootstrap/providers.php index bf71b94..60faac1 100644 --- a/bootstrap/providers.php +++ b/bootstrap/providers.php @@ -2,5 +2,6 @@ return [ App\Providers\AppServiceProvider::class, + Stephenjude\FilamentBlog\FilamentBlogServiceProvider::class, App\Providers\Filament\SuperAdminPanelProvider::class, ]; diff --git a/composer.json b/composer.json index 2635200..388ea39 100644 --- a/composer.json +++ b/composer.json @@ -16,6 +16,8 @@ "laravel/wayfinder": "^0.1.9", "paypal/rest-api-sdk-php": "^1.6", "simplesoftwareio/simple-qrcode": "^4.2", + "spatie/laravel-translatable": "^6.11", + "stephenjude/filament-blog": "*", "stripe/stripe-php": "^17.6" }, "require-dev": { diff --git a/composer.lock b/composer.lock index 9e08ec6..bd9838a 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": "b0eebcaa1d38fb0a00e546fad7bdc991", + "content-hash": "a79b02d59d8ee7716beea2fc8442a905", "packages": [ { "name": "anourvalar/eloquent-serialize", @@ -1386,6 +1386,43 @@ }, "time": "2025-09-04T14:12:50+00:00" }, + { + "name": "filament/spatie-laravel-tags-plugin", + "version": "v3.3.30", + "source": { + "type": "git", + "url": "https://github.com/filamentphp/spatie-laravel-tags-plugin.git", + "reference": "7763c2bab92c619cdd9294c69004f89e136c0afc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/filamentphp/spatie-laravel-tags-plugin/zipball/7763c2bab92c619cdd9294c69004f89e136c0afc", + "reference": "7763c2bab92c619cdd9294c69004f89e136c0afc", + "shasum": "" + }, + "require": { + "illuminate/database": "^10.45|^11.0|^12.0", + "php": "^8.1", + "spatie/laravel-tags": "^4.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Filament\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Filament support for `spatie/laravel-tags`.", + "homepage": "https://github.com/filamentphp/filament", + "support": { + "issues": "https://github.com/filamentphp/filament/issues", + "source": "https://github.com/filamentphp/filament" + }, + "time": "2025-05-19T07:27:08+00:00" + }, { "name": "filament/support", "version": "v4.0.7", @@ -5566,6 +5603,80 @@ }, "time": "2021-02-08T20:43:55+00:00" }, + { + "name": "spatie/eloquent-sortable", + "version": "4.5.2", + "source": { + "type": "git", + "url": "https://github.com/spatie/eloquent-sortable.git", + "reference": "c1c4f3a66cd41eb7458783c8a4c8e5d7924a9f20" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/eloquent-sortable/zipball/c1c4f3a66cd41eb7458783c8a4c8e5d7924a9f20", + "reference": "c1c4f3a66cd41eb7458783c8a4c8e5d7924a9f20", + "shasum": "" + }, + "require": { + "illuminate/database": "^9.31|^10.0|^11.0|^12.0", + "illuminate/support": "^9.31|^10.0|^11.0|^12.0", + "nesbot/carbon": "^2.63|^3.0", + "php": "^8.1", + "spatie/laravel-package-tools": "^1.9" + }, + "require-dev": { + "orchestra/testbench": "^7.0|^8.0|^9.0|^10.0", + "phpunit/phpunit": "^9.5|^10.0|^11.5.3" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Spatie\\EloquentSortable\\EloquentSortableServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Spatie\\EloquentSortable\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be" + } + ], + "description": "Sortable behaviour for eloquent models", + "homepage": "https://github.com/spatie/eloquent-sortable", + "keywords": [ + "behaviour", + "eloquent", + "laravel", + "model", + "sort", + "sortable" + ], + "support": { + "issues": "https://github.com/spatie/eloquent-sortable/issues", + "source": "https://github.com/spatie/eloquent-sortable/tree/4.5.2" + }, + "funding": [ + { + "url": "https://spatie.be/open-source/support-us", + "type": "custom" + }, + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2025-08-25T11:46:57+00:00" + }, { "name": "spatie/invade", "version": "2.1.0", @@ -5686,6 +5797,159 @@ ], "time": "2025-07-17T15:46:43+00:00" }, + { + "name": "spatie/laravel-tags", + "version": "4.10.0", + "source": { + "type": "git", + "url": "https://github.com/spatie/laravel-tags.git", + "reference": "9fc59a9328e892bbb5b01c948b0d703e22d543ec" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/laravel-tags/zipball/9fc59a9328e892bbb5b01c948b0d703e22d543ec", + "reference": "9fc59a9328e892bbb5b01c948b0d703e22d543ec", + "shasum": "" + }, + "require": { + "laravel/framework": "^10.0|^11.0|^12.0", + "nesbot/carbon": "^2.63|^3.0", + "php": "^8.1", + "spatie/eloquent-sortable": "^4.0", + "spatie/laravel-package-tools": "^1.4", + "spatie/laravel-translatable": "^6.0" + }, + "require-dev": { + "orchestra/testbench": "^8.0|^9.0|^10.0", + "pestphp/pest": "^1.22|^2.0", + "phpunit/phpunit": "^9.5.2" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Spatie\\Tags\\TagsServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Spatie\\Tags\\": "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": "Add tags and taggable behaviour to your Laravel app", + "homepage": "https://github.com/spatie/laravel-tags", + "keywords": [ + "laravel-tags", + "spatie" + ], + "support": { + "issues": "https://github.com/spatie/laravel-tags/issues", + "source": "https://github.com/spatie/laravel-tags/tree/4.10.0" + }, + "funding": [ + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2025-03-08T07:49:06+00:00" + }, + { + "name": "spatie/laravel-translatable", + "version": "6.11.4", + "source": { + "type": "git", + "url": "https://github.com/spatie/laravel-translatable.git", + "reference": "032d85b28de315310dab2048b857016f1194f68b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/laravel-translatable/zipball/032d85b28de315310dab2048b857016f1194f68b", + "reference": "032d85b28de315310dab2048b857016f1194f68b", + "shasum": "" + }, + "require": { + "illuminate/database": "^10.0|^11.0|^12.0", + "illuminate/support": "^10.0|^11.0|^12.0", + "php": "^8.0", + "spatie/laravel-package-tools": "^1.11" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.64", + "mockery/mockery": "^1.4", + "orchestra/testbench": "^7.0|^8.0|^9.0|^10.0", + "pestphp/pest": "^1.20|^2.0|^3.0" + }, + "type": "library", + "extra": { + "aliases": { + "Translatable": "Spatie\\Translatable\\Facades\\Translatable" + }, + "laravel": { + "providers": [ + "Spatie\\Translatable\\TranslatableServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Spatie\\Translatable\\": "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" + }, + { + "name": "Sebastian De Deyne", + "email": "sebastian@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "A trait to make an Eloquent model hold translations", + "homepage": "https://github.com/spatie/laravel-translatable", + "keywords": [ + "eloquent", + "i8n", + "laravel-translatable", + "model", + "multilingual", + "spatie", + "translate" + ], + "support": { + "issues": "https://github.com/spatie/laravel-translatable/issues", + "source": "https://github.com/spatie/laravel-translatable/tree/6.11.4" + }, + "funding": [ + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2025-02-20T15:51:22+00:00" + }, { "name": "spatie/shiki-php", "version": "2.3.2", @@ -5751,6 +6015,79 @@ ], "time": "2025-02-21T14:16:57+00:00" }, + { + "name": "stephenjude/filament-blog", + "version": "4.2.1", + "source": { + "type": "git", + "url": "https://github.com/stephenjude/filament-blog.git", + "reference": "040414004f876e880889e8d1646de219d85365bc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/stephenjude/filament-blog/zipball/040414004f876e880889e8d1646de219d85365bc", + "reference": "040414004f876e880889e8d1646de219d85365bc", + "shasum": "" + }, + "require": { + "filament/filament": "^4.0", + "filament/spatie-laravel-tags-plugin": "^v3.0", + "php": "^8.3", + "spatie/laravel-package-tools": "^1.16.1" + }, + "require-dev": { + "laravel/pint": "^1.13.1", + "nunomaduro/collision": "^7.8.1|^8.0", + "orchestra/testbench": "^9.0|^10.0", + "pestphp/pest": "^2.18.2|^3.7", + "pestphp/pest-plugin-arch": "^2.3.3|^3.0", + "pestphp/pest-plugin-laravel": "^2.2|^3.1", + "pestphp/pest-plugin-livewire": "^2.1|^3.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Stephenjude\\FilamentBlog\\BlogServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Stephenjude\\FilamentBlog\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "stephenjude", + "email": "stephenjudesuccess@gmail.com", + "role": "Developer" + } + ], + "description": "Filament Blog Builder", + "homepage": "https://github.com/stephenjude/filament-blog", + "keywords": [ + "blog", + "filament-blog", + "laravel", + "stephenjude" + ], + "support": { + "issues": "https://github.com/stephenjude/filament-blog/issues", + "source": "https://github.com/stephenjude/filament-blog/tree/4.2.1" + }, + "funding": [ + { + "url": "https://github.com/stephenjude", + "type": "github" + } + ], + "time": "2025-09-08T07:49:43+00:00" + }, { "name": "stripe/stripe-php", "version": "v17.6.0", diff --git a/config/app.php b/config/app.php index 324b513..76a1b7f 100644 --- a/config/app.php +++ b/config/app.php @@ -78,7 +78,7 @@ return [ | */ - 'locale' => env('APP_LOCALE', 'en'), + 'locale' => env('APP_LOCALE', 'de'), 'fallback_locale' => env('APP_FALLBACK_LOCALE', 'en'), diff --git a/config/filament-blog.php b/config/filament-blog.php new file mode 100644 index 0000000..91bb423 --- /dev/null +++ b/config/filament-blog.php @@ -0,0 +1,81 @@ + \App\Models\BlogPost::class, + 'category_model' => \App\Models\BlogCategory::class, + 'tag_model' => \App\Models\BlogTag::class, + 'panels' => [ + 'superadmin' => [ + 'resources' => [ + \Stephenjude\FilamentBlog\Filament\Resources\PostResource::class, + \Stephenjude\FilamentBlog\Filament\Resources\CategoryResource::class, + \Stephenjude\FilamentBlog\Filament\Resources\TagResource::class, + ], + ], + ], + + /** + * Supported content editors: richtext & markdown: + * \Filament\Forms\Components\RichEditor::class + * \Filament\Forms\Components\MarkdownEditor::class + */ + 'editor' => \Filament\Forms\Components\RichEditor::class, + + /** + * Configs for Posts banner file that give you option to change + * Disk,Directory name , maximum upload size and the + * Crop aspect ratio of the Posts banner image. + */ + 'banner' => [ + 'disk' => 'public', + 'directory' => 'blog', + 'maxSize' => 5120, + 'cropAspectRatio' => '16:9', + 'visibility' => 'public', + ], + + /** + * Configs for Posts that give you option to change + * the sort column and direction of the Posts. + */ + 'sort' => [ + 'column' => 'published_at', + 'direction' => 'desc', + ], + + /** + * Configs for Author Avatar file that give you option to change + * Disk,Directory name , maximum upload size and the + * Of the Author avatar image. + */ + 'avatar' => [ + 'disk' => 'public', + 'directory' => 'blog', + 'maxSize' => 5120, + 'visibility' => 'public', + ], + + /** + * Buttons for text editor toolbar. + */ + 'toolbar_buttons' => [ + 'attachFiles', + 'blockquote', + 'bold', + 'bulletList', + 'codeBlock', + 'h1', + 'h2', + 'h3', + 'hr', + 'image', + 'italic', + 'link', + 'orderedList', + 'redo', + 'strike', + 'table', + 'underline', + 'undo', + ], +]; diff --git a/database/migrations/2025_09_26_143146_create_filament_blog_tables.php b/database/migrations/2025_09_26_143146_create_filament_blog_tables.php new file mode 100644 index 0000000..493aa44 --- /dev/null +++ b/database/migrations/2025_09_26_143146_create_filament_blog_tables.php @@ -0,0 +1,60 @@ +id(); + $table->string('name'); + $table->string('slug')->unique(); + $table->longText('description')->nullable(); + $table->boolean('is_visible')->default(false); + $table->timestamps(); + }); + + Schema::create('blog_authors', function (Blueprint $table) { + $table->id(); + $table->string('name'); + $table->string('email')->unique(); + $table->string('photo')->nullable(); + $table->longText('bio')->nullable(); + $table->string('github_handle')->nullable(); + $table->string('twitter_handle')->nullable(); + $table->timestamps(); + }); + + Schema::create('blog_posts', function (Blueprint $table) { + $table->id(); + $table->foreignId('blog_author_id')->nullable()->constrained()->cascadeOnDelete(); + $table->foreignId('blog_category_id')->nullable()->constrained()->nullOnDelete(); + $table->string('title'); + $table->string('slug')->unique(); + $table->text('excerpt')->nullable(); + $table->string('banner')->nullable(); + $table->longText('content'); + $table->date('published_at')->nullable(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('blog_posts'); + Schema::dropIfExists('blog_categories'); + Schema::dropIfExists('blog_authors'); + } +}; diff --git a/database/migrations/2025_09_26_143310_add_translations_to_blog_tables.php b/database/migrations/2025_09_26_143310_add_translations_to_blog_tables.php new file mode 100644 index 0000000..da0e5b0 --- /dev/null +++ b/database/migrations/2025_09_26_143310_add_translations_to_blog_tables.php @@ -0,0 +1,36 @@ +json('translations')->nullable(); + }); + + Schema::table('blog_categories', function (Blueprint $table) { + $table->json('translations')->nullable(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('blog_posts', function (Blueprint $table) { + $table->dropColumn('translations'); + }); + + Schema::table('blog_categories', function (Blueprint $table) { + $table->dropColumn('translations'); + }); + } +}; diff --git a/database/migrations/2025_09_26_145500_add_email_to_tenants_table.php b/database/migrations/2025_09_26_145500_add_email_to_tenants_table.php new file mode 100644 index 0000000..b8f242a --- /dev/null +++ b/database/migrations/2025_09_26_145500_add_email_to_tenants_table.php @@ -0,0 +1,28 @@ +string('email')->nullable()->after('slug'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('tenants', function (Blueprint $table) { + $table->dropColumn('email'); + }); + } +}; \ No newline at end of file diff --git a/database/migrations/2025_09_26_153139_create_tag_tables.php b/database/migrations/2025_09_26_153139_create_tag_tables.php new file mode 100644 index 0000000..5925c6c --- /dev/null +++ b/database/migrations/2025_09_26_153139_create_tag_tables.php @@ -0,0 +1,36 @@ +id(); + + $table->json('name'); + $table->json('slug'); + $table->string('type')->nullable(); + $table->integer('order_column')->nullable(); + + $table->timestamps(); + }); + + Schema::create('taggables', function (Blueprint $table) { + $table->foreignId('tag_id')->constrained()->cascadeOnDelete(); + + $table->morphs('taggable'); + + $table->unique(['tag_id', 'taggable_id', 'taggable_type']); + }); + } + + public function down(): void + { + Schema::dropIfExists('taggables'); + Schema::dropIfExists('tags'); + } +}; diff --git a/public/vendor/livewire/livewire.esm.js b/public/vendor/livewire/livewire.esm.js new file mode 100644 index 0000000..e45b045 --- /dev/null +++ b/public/vendor/livewire/livewire.esm.js @@ -0,0 +1,11146 @@ +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __commonJS = (cb, mod) => function __require() { + return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod)); + +// ../alpine/packages/alpinejs/dist/module.cjs.js +var require_module_cjs = __commonJS({ + "../alpine/packages/alpinejs/dist/module.cjs.js"(exports, module) { + var __create2 = Object.create; + var __defProp2 = Object.defineProperty; + var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; + var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __getProtoOf2 = Object.getPrototypeOf; + var __hasOwnProp2 = Object.prototype.hasOwnProperty; + var __commonJS2 = (cb, mod) => function __require() { + return mod || (0, cb[__getOwnPropNames2(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; + }; + var __export = (target, all2) => { + for (var name in all2) + __defProp2(target, name, { get: all2[name], enumerable: true }); + }; + var __copyProps2 = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames2(from)) + if (!__hasOwnProp2.call(to, key) && key !== except) + __defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable }); + } + return to; + }; + var __toESM2 = (mod, isNodeMode, target) => (target = mod != null ? __create2(__getProtoOf2(mod)) : {}, __copyProps2(isNodeMode || !mod || !mod.__esModule ? __defProp2(target, "default", { value: mod, enumerable: true }) : target, mod)); + var __toCommonJS = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); + var require_shared_cjs = __commonJS2({ + "node_modules/@vue/shared/dist/shared.cjs.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + function makeMap(str, expectsLowerCase) { + const map = /* @__PURE__ */ Object.create(null); + const list = str.split(","); + for (let i = 0; i < list.length; i++) { + map[list[i]] = true; + } + return expectsLowerCase ? (val) => !!map[val.toLowerCase()] : (val) => !!map[val]; + } + var PatchFlagNames = { + [1]: `TEXT`, + [2]: `CLASS`, + [4]: `STYLE`, + [8]: `PROPS`, + [16]: `FULL_PROPS`, + [32]: `HYDRATE_EVENTS`, + [64]: `STABLE_FRAGMENT`, + [128]: `KEYED_FRAGMENT`, + [256]: `UNKEYED_FRAGMENT`, + [512]: `NEED_PATCH`, + [1024]: `DYNAMIC_SLOTS`, + [2048]: `DEV_ROOT_FRAGMENT`, + [-1]: `HOISTED`, + [-2]: `BAIL` + }; + var slotFlagsText = { + [1]: "STABLE", + [2]: "DYNAMIC", + [3]: "FORWARDED" + }; + var GLOBALS_WHITE_LISTED = "Infinity,undefined,NaN,isFinite,isNaN,parseFloat,parseInt,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,Math,Number,Date,Array,Object,Boolean,String,RegExp,Map,Set,JSON,Intl,BigInt"; + var isGloballyWhitelisted = /* @__PURE__ */ makeMap(GLOBALS_WHITE_LISTED); + var range = 2; + function generateCodeFrame(source, start22 = 0, end = source.length) { + let lines = source.split(/(\r?\n)/); + const newlineSequences = lines.filter((_, idx) => idx % 2 === 1); + lines = lines.filter((_, idx) => idx % 2 === 0); + let count = 0; + const res = []; + for (let i = 0; i < lines.length; i++) { + count += lines[i].length + (newlineSequences[i] && newlineSequences[i].length || 0); + if (count >= start22) { + for (let j = i - range; j <= i + range || end > count; j++) { + if (j < 0 || j >= lines.length) + continue; + const line = j + 1; + res.push(`${line}${" ".repeat(Math.max(3 - String(line).length, 0))}| ${lines[j]}`); + const lineLength = lines[j].length; + const newLineSeqLength = newlineSequences[j] && newlineSequences[j].length || 0; + if (j === i) { + const pad = start22 - (count - (lineLength + newLineSeqLength)); + const length = Math.max(1, end > count ? lineLength - pad : end - start22); + res.push(` | ` + " ".repeat(pad) + "^".repeat(length)); + } else if (j > i) { + if (end > count) { + const length = Math.max(Math.min(end - count, lineLength), 1); + res.push(` | ` + "^".repeat(length)); + } + count += lineLength + newLineSeqLength; + } + } + break; + } + } + return res.join("\n"); + } + var specialBooleanAttrs = `itemscope,allowfullscreen,formnovalidate,ismap,nomodule,novalidate,readonly`; + var isSpecialBooleanAttr = /* @__PURE__ */ makeMap(specialBooleanAttrs); + var isBooleanAttr2 = /* @__PURE__ */ makeMap(specialBooleanAttrs + `,async,autofocus,autoplay,controls,default,defer,disabled,hidden,loop,open,required,reversed,scoped,seamless,checked,muted,multiple,selected`); + var unsafeAttrCharRE = /[>/="'\u0009\u000a\u000c\u0020]/; + var attrValidationCache = {}; + function isSSRSafeAttrName(name) { + if (attrValidationCache.hasOwnProperty(name)) { + return attrValidationCache[name]; + } + const isUnsafe = unsafeAttrCharRE.test(name); + if (isUnsafe) { + console.error(`unsafe attribute name: ${name}`); + } + return attrValidationCache[name] = !isUnsafe; + } + var propsToAttrMap = { + acceptCharset: "accept-charset", + className: "class", + htmlFor: "for", + httpEquiv: "http-equiv" + }; + var isNoUnitNumericStyleProp = /* @__PURE__ */ makeMap(`animation-iteration-count,border-image-outset,border-image-slice,border-image-width,box-flex,box-flex-group,box-ordinal-group,column-count,columns,flex,flex-grow,flex-positive,flex-shrink,flex-negative,flex-order,grid-row,grid-row-end,grid-row-span,grid-row-start,grid-column,grid-column-end,grid-column-span,grid-column-start,font-weight,line-clamp,line-height,opacity,order,orphans,tab-size,widows,z-index,zoom,fill-opacity,flood-opacity,stop-opacity,stroke-dasharray,stroke-dashoffset,stroke-miterlimit,stroke-opacity,stroke-width`); + var isKnownAttr = /* @__PURE__ */ makeMap(`accept,accept-charset,accesskey,action,align,allow,alt,async,autocapitalize,autocomplete,autofocus,autoplay,background,bgcolor,border,buffered,capture,challenge,charset,checked,cite,class,code,codebase,color,cols,colspan,content,contenteditable,contextmenu,controls,coords,crossorigin,csp,data,datetime,decoding,default,defer,dir,dirname,disabled,download,draggable,dropzone,enctype,enterkeyhint,for,form,formaction,formenctype,formmethod,formnovalidate,formtarget,headers,height,hidden,high,href,hreflang,http-equiv,icon,id,importance,integrity,ismap,itemprop,keytype,kind,label,lang,language,loading,list,loop,low,manifest,max,maxlength,minlength,media,min,multiple,muted,name,novalidate,open,optimum,pattern,ping,placeholder,poster,preload,radiogroup,readonly,referrerpolicy,rel,required,reversed,rows,rowspan,sandbox,scope,scoped,selected,shape,size,sizes,slot,span,spellcheck,src,srcdoc,srclang,srcset,start,step,style,summary,tabindex,target,title,translate,type,usemap,value,width,wrap`); + function normalizeStyle(value) { + if (isArray2(value)) { + const res = {}; + for (let i = 0; i < value.length; i++) { + const item = value[i]; + const normalized = normalizeStyle(isString(item) ? parseStringStyle(item) : item); + if (normalized) { + for (const key in normalized) { + res[key] = normalized[key]; + } + } + } + return res; + } else if (isObject2(value)) { + return value; + } + } + var listDelimiterRE = /;(?![^(]*\))/g; + var propertyDelimiterRE = /:(.+)/; + function parseStringStyle(cssText) { + const ret = {}; + cssText.split(listDelimiterRE).forEach((item) => { + if (item) { + const tmp = item.split(propertyDelimiterRE); + tmp.length > 1 && (ret[tmp[0].trim()] = tmp[1].trim()); + } + }); + return ret; + } + function stringifyStyle(styles) { + let ret = ""; + if (!styles) { + return ret; + } + for (const key in styles) { + const value = styles[key]; + const normalizedKey = key.startsWith(`--`) ? key : hyphenate(key); + if (isString(value) || typeof value === "number" && isNoUnitNumericStyleProp(normalizedKey)) { + ret += `${normalizedKey}:${value};`; + } + } + return ret; + } + function normalizeClass(value) { + let res = ""; + if (isString(value)) { + res = value; + } else if (isArray2(value)) { + for (let i = 0; i < value.length; i++) { + const normalized = normalizeClass(value[i]); + if (normalized) { + res += normalized + " "; + } + } + } else if (isObject2(value)) { + for (const name in value) { + if (value[name]) { + res += name + " "; + } + } + } + return res.trim(); + } + var HTML_TAGS = "html,body,base,head,link,meta,style,title,address,article,aside,footer,header,h1,h2,h3,h4,h5,h6,hgroup,nav,section,div,dd,dl,dt,figcaption,figure,picture,hr,img,li,main,ol,p,pre,ul,a,b,abbr,bdi,bdo,br,cite,code,data,dfn,em,i,kbd,mark,q,rp,rt,rtc,ruby,s,samp,small,span,strong,sub,sup,time,u,var,wbr,area,audio,map,track,video,embed,object,param,source,canvas,script,noscript,del,ins,caption,col,colgroup,table,thead,tbody,td,th,tr,button,datalist,fieldset,form,input,label,legend,meter,optgroup,option,output,progress,select,textarea,details,dialog,menu,summary,template,blockquote,iframe,tfoot"; + var SVG_TAGS = "svg,animate,animateMotion,animateTransform,circle,clipPath,color-profile,defs,desc,discard,ellipse,feBlend,feColorMatrix,feComponentTransfer,feComposite,feConvolveMatrix,feDiffuseLighting,feDisplacementMap,feDistanceLight,feDropShadow,feFlood,feFuncA,feFuncB,feFuncG,feFuncR,feGaussianBlur,feImage,feMerge,feMergeNode,feMorphology,feOffset,fePointLight,feSpecularLighting,feSpotLight,feTile,feTurbulence,filter,foreignObject,g,hatch,hatchpath,image,line,linearGradient,marker,mask,mesh,meshgradient,meshpatch,meshrow,metadata,mpath,path,pattern,polygon,polyline,radialGradient,rect,set,solidcolor,stop,switch,symbol,text,textPath,title,tspan,unknown,use,view"; + var VOID_TAGS = "area,base,br,col,embed,hr,img,input,link,meta,param,source,track,wbr"; + var isHTMLTag = /* @__PURE__ */ makeMap(HTML_TAGS); + var isSVGTag = /* @__PURE__ */ makeMap(SVG_TAGS); + var isVoidTag = /* @__PURE__ */ makeMap(VOID_TAGS); + var escapeRE = /["'&<>]/; + function escapeHtml(string) { + const str = "" + string; + const match = escapeRE.exec(str); + if (!match) { + return str; + } + let html = ""; + let escaped; + let index; + let lastIndex = 0; + for (index = match.index; index < str.length; index++) { + switch (str.charCodeAt(index)) { + case 34: + escaped = """; + break; + case 38: + escaped = "&"; + break; + case 39: + escaped = "'"; + break; + case 60: + escaped = "<"; + break; + case 62: + escaped = ">"; + break; + default: + continue; + } + if (lastIndex !== index) { + html += str.substring(lastIndex, index); + } + lastIndex = index + 1; + html += escaped; + } + return lastIndex !== index ? html + str.substring(lastIndex, index) : html; + } + var commentStripRE = /^-?>||--!>| looseEqual(item, val)); + } + var toDisplayString = (val) => { + return val == null ? "" : isObject2(val) ? JSON.stringify(val, replacer, 2) : String(val); + }; + var replacer = (_key, val) => { + if (isMap(val)) { + return { + [`Map(${val.size})`]: [...val.entries()].reduce((entries, [key, val2]) => { + entries[`${key} =>`] = val2; + return entries; + }, {}) + }; + } else if (isSet(val)) { + return { + [`Set(${val.size})`]: [...val.values()] + }; + } else if (isObject2(val) && !isArray2(val) && !isPlainObject(val)) { + return String(val); + } + return val; + }; + var babelParserDefaultPlugins = [ + "bigInt", + "optionalChaining", + "nullishCoalescingOperator" + ]; + var EMPTY_OBJ = Object.freeze({}); + var EMPTY_ARR = Object.freeze([]); + var NOOP = () => { + }; + var NO = () => false; + var onRE = /^on[^a-z]/; + var isOn = (key) => onRE.test(key); + var isModelListener = (key) => key.startsWith("onUpdate:"); + var extend = Object.assign; + var remove = (arr, el) => { + const i = arr.indexOf(el); + if (i > -1) { + arr.splice(i, 1); + } + }; + var hasOwnProperty = Object.prototype.hasOwnProperty; + var hasOwn = (val, key) => hasOwnProperty.call(val, key); + var isArray2 = Array.isArray; + var isMap = (val) => toTypeString(val) === "[object Map]"; + var isSet = (val) => toTypeString(val) === "[object Set]"; + var isDate = (val) => val instanceof Date; + var isFunction2 = (val) => typeof val === "function"; + var isString = (val) => typeof val === "string"; + var isSymbol = (val) => typeof val === "symbol"; + var isObject2 = (val) => val !== null && typeof val === "object"; + var isPromise = (val) => { + return isObject2(val) && isFunction2(val.then) && isFunction2(val.catch); + }; + var objectToString = Object.prototype.toString; + var toTypeString = (value) => objectToString.call(value); + var toRawType = (value) => { + return toTypeString(value).slice(8, -1); + }; + var isPlainObject = (val) => toTypeString(val) === "[object Object]"; + var isIntegerKey = (key) => isString(key) && key !== "NaN" && key[0] !== "-" && "" + parseInt(key, 10) === key; + var isReservedProp = /* @__PURE__ */ makeMap(",key,ref,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"); + var cacheStringFunction = (fn) => { + const cache = /* @__PURE__ */ Object.create(null); + return (str) => { + const hit = cache[str]; + return hit || (cache[str] = fn(str)); + }; + }; + var camelizeRE = /-(\w)/g; + var camelize = cacheStringFunction((str) => { + return str.replace(camelizeRE, (_, c) => c ? c.toUpperCase() : ""); + }); + var hyphenateRE = /\B([A-Z])/g; + var hyphenate = cacheStringFunction((str) => str.replace(hyphenateRE, "-$1").toLowerCase()); + var capitalize = cacheStringFunction((str) => str.charAt(0).toUpperCase() + str.slice(1)); + var toHandlerKey = cacheStringFunction((str) => str ? `on${capitalize(str)}` : ``); + var hasChanged = (value, oldValue) => value !== oldValue && (value === value || oldValue === oldValue); + var invokeArrayFns = (fns, arg) => { + for (let i = 0; i < fns.length; i++) { + fns[i](arg); + } + }; + var def = (obj, key, value) => { + Object.defineProperty(obj, key, { + configurable: true, + enumerable: false, + value + }); + }; + var toNumber = (val) => { + const n = parseFloat(val); + return isNaN(n) ? val : n; + }; + var _globalThis; + var getGlobalThis = () => { + return _globalThis || (_globalThis = typeof globalThis !== "undefined" ? globalThis : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : {}); + }; + exports2.EMPTY_ARR = EMPTY_ARR; + exports2.EMPTY_OBJ = EMPTY_OBJ; + exports2.NO = NO; + exports2.NOOP = NOOP; + exports2.PatchFlagNames = PatchFlagNames; + exports2.babelParserDefaultPlugins = babelParserDefaultPlugins; + exports2.camelize = camelize; + exports2.capitalize = capitalize; + exports2.def = def; + exports2.escapeHtml = escapeHtml; + exports2.escapeHtmlComment = escapeHtmlComment; + exports2.extend = extend; + exports2.generateCodeFrame = generateCodeFrame; + exports2.getGlobalThis = getGlobalThis; + exports2.hasChanged = hasChanged; + exports2.hasOwn = hasOwn; + exports2.hyphenate = hyphenate; + exports2.invokeArrayFns = invokeArrayFns; + exports2.isArray = isArray2; + exports2.isBooleanAttr = isBooleanAttr2; + exports2.isDate = isDate; + exports2.isFunction = isFunction2; + exports2.isGloballyWhitelisted = isGloballyWhitelisted; + exports2.isHTMLTag = isHTMLTag; + exports2.isIntegerKey = isIntegerKey; + exports2.isKnownAttr = isKnownAttr; + exports2.isMap = isMap; + exports2.isModelListener = isModelListener; + exports2.isNoUnitNumericStyleProp = isNoUnitNumericStyleProp; + exports2.isObject = isObject2; + exports2.isOn = isOn; + exports2.isPlainObject = isPlainObject; + exports2.isPromise = isPromise; + exports2.isReservedProp = isReservedProp; + exports2.isSSRSafeAttrName = isSSRSafeAttrName; + exports2.isSVGTag = isSVGTag; + exports2.isSet = isSet; + exports2.isSpecialBooleanAttr = isSpecialBooleanAttr; + exports2.isString = isString; + exports2.isSymbol = isSymbol; + exports2.isVoidTag = isVoidTag; + exports2.looseEqual = looseEqual; + exports2.looseIndexOf = looseIndexOf; + exports2.makeMap = makeMap; + exports2.normalizeClass = normalizeClass; + exports2.normalizeStyle = normalizeStyle; + exports2.objectToString = objectToString; + exports2.parseStringStyle = parseStringStyle; + exports2.propsToAttrMap = propsToAttrMap; + exports2.remove = remove; + exports2.slotFlagsText = slotFlagsText; + exports2.stringifyStyle = stringifyStyle; + exports2.toDisplayString = toDisplayString; + exports2.toHandlerKey = toHandlerKey; + exports2.toNumber = toNumber; + exports2.toRawType = toRawType; + exports2.toTypeString = toTypeString; + } + }); + var require_shared = __commonJS2({ + "node_modules/@vue/shared/index.js"(exports2, module2) { + "use strict"; + if (false) { + module2.exports = null; + } else { + module2.exports = require_shared_cjs(); + } + } + }); + var require_reactivity_cjs = __commonJS2({ + "node_modules/@vue/reactivity/dist/reactivity.cjs.js"(exports2) { + "use strict"; + Object.defineProperty(exports2, "__esModule", { value: true }); + var shared = require_shared(); + var targetMap = /* @__PURE__ */ new WeakMap(); + var effectStack = []; + var activeEffect; + var ITERATE_KEY = Symbol("iterate"); + var MAP_KEY_ITERATE_KEY = Symbol("Map key iterate"); + function isEffect(fn) { + return fn && fn._isEffect === true; + } + function effect3(fn, options = shared.EMPTY_OBJ) { + if (isEffect(fn)) { + fn = fn.raw; + } + const effect4 = createReactiveEffect(fn, options); + if (!options.lazy) { + effect4(); + } + return effect4; + } + function stop2(effect4) { + if (effect4.active) { + cleanup(effect4); + if (effect4.options.onStop) { + effect4.options.onStop(); + } + effect4.active = false; + } + } + var uid = 0; + function createReactiveEffect(fn, options) { + const effect4 = function reactiveEffect() { + if (!effect4.active) { + return fn(); + } + if (!effectStack.includes(effect4)) { + cleanup(effect4); + try { + enableTracking(); + effectStack.push(effect4); + activeEffect = effect4; + return fn(); + } finally { + effectStack.pop(); + resetTracking(); + activeEffect = effectStack[effectStack.length - 1]; + } + } + }; + effect4.id = uid++; + effect4.allowRecurse = !!options.allowRecurse; + effect4._isEffect = true; + effect4.active = true; + effect4.raw = fn; + effect4.deps = []; + effect4.options = options; + return effect4; + } + function cleanup(effect4) { + const { deps } = effect4; + if (deps.length) { + for (let i = 0; i < deps.length; i++) { + deps[i].delete(effect4); + } + deps.length = 0; + } + } + var shouldTrack = true; + var trackStack = []; + function pauseTracking() { + trackStack.push(shouldTrack); + shouldTrack = false; + } + function enableTracking() { + trackStack.push(shouldTrack); + shouldTrack = true; + } + function resetTracking() { + const last = trackStack.pop(); + shouldTrack = last === void 0 ? true : last; + } + function track2(target, type, key) { + if (!shouldTrack || activeEffect === void 0) { + return; + } + let depsMap = targetMap.get(target); + if (!depsMap) { + targetMap.set(target, depsMap = /* @__PURE__ */ new Map()); + } + let dep = depsMap.get(key); + if (!dep) { + depsMap.set(key, dep = /* @__PURE__ */ new Set()); + } + if (!dep.has(activeEffect)) { + dep.add(activeEffect); + activeEffect.deps.push(dep); + if (activeEffect.options.onTrack) { + activeEffect.options.onTrack({ + effect: activeEffect, + target, + type, + key + }); + } + } + } + function trigger2(target, type, key, newValue, oldValue, oldTarget) { + const depsMap = targetMap.get(target); + if (!depsMap) { + return; + } + const effects = /* @__PURE__ */ new Set(); + const add2 = (effectsToAdd) => { + if (effectsToAdd) { + effectsToAdd.forEach((effect4) => { + if (effect4 !== activeEffect || effect4.allowRecurse) { + effects.add(effect4); + } + }); + } + }; + if (type === "clear") { + depsMap.forEach(add2); + } else if (key === "length" && shared.isArray(target)) { + depsMap.forEach((dep, key2) => { + if (key2 === "length" || key2 >= newValue) { + add2(dep); + } + }); + } else { + if (key !== void 0) { + add2(depsMap.get(key)); + } + switch (type) { + case "add": + if (!shared.isArray(target)) { + add2(depsMap.get(ITERATE_KEY)); + if (shared.isMap(target)) { + add2(depsMap.get(MAP_KEY_ITERATE_KEY)); + } + } else if (shared.isIntegerKey(key)) { + add2(depsMap.get("length")); + } + break; + case "delete": + if (!shared.isArray(target)) { + add2(depsMap.get(ITERATE_KEY)); + if (shared.isMap(target)) { + add2(depsMap.get(MAP_KEY_ITERATE_KEY)); + } + } + break; + case "set": + if (shared.isMap(target)) { + add2(depsMap.get(ITERATE_KEY)); + } + break; + } + } + const run = (effect4) => { + if (effect4.options.onTrigger) { + effect4.options.onTrigger({ + effect: effect4, + target, + key, + type, + newValue, + oldValue, + oldTarget + }); + } + if (effect4.options.scheduler) { + effect4.options.scheduler(effect4); + } else { + effect4(); + } + }; + effects.forEach(run); + } + var isNonTrackableKeys = /* @__PURE__ */ shared.makeMap(`__proto__,__v_isRef,__isVue`); + var builtInSymbols = new Set(Object.getOwnPropertyNames(Symbol).map((key) => Symbol[key]).filter(shared.isSymbol)); + var get2 = /* @__PURE__ */ createGetter(); + var shallowGet = /* @__PURE__ */ createGetter(false, true); + var readonlyGet = /* @__PURE__ */ createGetter(true); + var shallowReadonlyGet = /* @__PURE__ */ createGetter(true, true); + var arrayInstrumentations = /* @__PURE__ */ createArrayInstrumentations(); + function createArrayInstrumentations() { + const instrumentations = {}; + ["includes", "indexOf", "lastIndexOf"].forEach((key) => { + instrumentations[key] = function(...args) { + const arr = toRaw2(this); + for (let i = 0, l = this.length; i < l; i++) { + track2(arr, "get", i + ""); + } + const res = arr[key](...args); + if (res === -1 || res === false) { + return arr[key](...args.map(toRaw2)); + } else { + return res; + } + }; + }); + ["push", "pop", "shift", "unshift", "splice"].forEach((key) => { + instrumentations[key] = function(...args) { + pauseTracking(); + const res = toRaw2(this)[key].apply(this, args); + resetTracking(); + return res; + }; + }); + return instrumentations; + } + function createGetter(isReadonly2 = false, shallow = false) { + return function get3(target, key, receiver) { + if (key === "__v_isReactive") { + return !isReadonly2; + } else if (key === "__v_isReadonly") { + return isReadonly2; + } else if (key === "__v_raw" && receiver === (isReadonly2 ? shallow ? shallowReadonlyMap : readonlyMap : shallow ? shallowReactiveMap : reactiveMap).get(target)) { + return target; + } + const targetIsArray = shared.isArray(target); + if (!isReadonly2 && targetIsArray && shared.hasOwn(arrayInstrumentations, key)) { + return Reflect.get(arrayInstrumentations, key, receiver); + } + const res = Reflect.get(target, key, receiver); + if (shared.isSymbol(key) ? builtInSymbols.has(key) : isNonTrackableKeys(key)) { + return res; + } + if (!isReadonly2) { + track2(target, "get", key); + } + if (shallow) { + return res; + } + if (isRef(res)) { + const shouldUnwrap = !targetIsArray || !shared.isIntegerKey(key); + return shouldUnwrap ? res.value : res; + } + if (shared.isObject(res)) { + return isReadonly2 ? readonly(res) : reactive3(res); + } + return res; + }; + } + var set2 = /* @__PURE__ */ createSetter(); + var shallowSet = /* @__PURE__ */ createSetter(true); + function createSetter(shallow = false) { + return function set3(target, key, value, receiver) { + let oldValue = target[key]; + if (!shallow) { + value = toRaw2(value); + oldValue = toRaw2(oldValue); + if (!shared.isArray(target) && isRef(oldValue) && !isRef(value)) { + oldValue.value = value; + return true; + } + } + const hadKey = shared.isArray(target) && shared.isIntegerKey(key) ? Number(key) < target.length : shared.hasOwn(target, key); + const result = Reflect.set(target, key, value, receiver); + if (target === toRaw2(receiver)) { + if (!hadKey) { + trigger2(target, "add", key, value); + } else if (shared.hasChanged(value, oldValue)) { + trigger2(target, "set", key, value, oldValue); + } + } + return result; + }; + } + function deleteProperty(target, key) { + const hadKey = shared.hasOwn(target, key); + const oldValue = target[key]; + const result = Reflect.deleteProperty(target, key); + if (result && hadKey) { + trigger2(target, "delete", key, void 0, oldValue); + } + return result; + } + function has(target, key) { + const result = Reflect.has(target, key); + if (!shared.isSymbol(key) || !builtInSymbols.has(key)) { + track2(target, "has", key); + } + return result; + } + function ownKeys(target) { + track2(target, "iterate", shared.isArray(target) ? "length" : ITERATE_KEY); + return Reflect.ownKeys(target); + } + var mutableHandlers = { + get: get2, + set: set2, + deleteProperty, + has, + ownKeys + }; + var readonlyHandlers = { + get: readonlyGet, + set(target, key) { + { + console.warn(`Set operation on key "${String(key)}" failed: target is readonly.`, target); + } + return true; + }, + deleteProperty(target, key) { + { + console.warn(`Delete operation on key "${String(key)}" failed: target is readonly.`, target); + } + return true; + } + }; + var shallowReactiveHandlers = /* @__PURE__ */ shared.extend({}, mutableHandlers, { + get: shallowGet, + set: shallowSet + }); + var shallowReadonlyHandlers = /* @__PURE__ */ shared.extend({}, readonlyHandlers, { + get: shallowReadonlyGet + }); + var toReactive = (value) => shared.isObject(value) ? reactive3(value) : value; + var toReadonly = (value) => shared.isObject(value) ? readonly(value) : value; + var toShallow = (value) => value; + var getProto = (v) => Reflect.getPrototypeOf(v); + function get$1(target, key, isReadonly2 = false, isShallow = false) { + target = target["__v_raw"]; + const rawTarget = toRaw2(target); + const rawKey = toRaw2(key); + if (key !== rawKey) { + !isReadonly2 && track2(rawTarget, "get", key); + } + !isReadonly2 && track2(rawTarget, "get", rawKey); + const { has: has2 } = getProto(rawTarget); + const wrap = isShallow ? toShallow : isReadonly2 ? toReadonly : toReactive; + if (has2.call(rawTarget, key)) { + return wrap(target.get(key)); + } else if (has2.call(rawTarget, rawKey)) { + return wrap(target.get(rawKey)); + } else if (target !== rawTarget) { + target.get(key); + } + } + function has$1(key, isReadonly2 = false) { + const target = this["__v_raw"]; + const rawTarget = toRaw2(target); + const rawKey = toRaw2(key); + if (key !== rawKey) { + !isReadonly2 && track2(rawTarget, "has", key); + } + !isReadonly2 && track2(rawTarget, "has", rawKey); + return key === rawKey ? target.has(key) : target.has(key) || target.has(rawKey); + } + function size(target, isReadonly2 = false) { + target = target["__v_raw"]; + !isReadonly2 && track2(toRaw2(target), "iterate", ITERATE_KEY); + return Reflect.get(target, "size", target); + } + function add(value) { + value = toRaw2(value); + const target = toRaw2(this); + const proto = getProto(target); + const hadKey = proto.has.call(target, value); + if (!hadKey) { + target.add(value); + trigger2(target, "add", value, value); + } + return this; + } + function set$1(key, value) { + value = toRaw2(value); + const target = toRaw2(this); + const { has: has2, get: get3 } = getProto(target); + let hadKey = has2.call(target, key); + if (!hadKey) { + key = toRaw2(key); + hadKey = has2.call(target, key); + } else { + checkIdentityKeys(target, has2, key); + } + const oldValue = get3.call(target, key); + target.set(key, value); + if (!hadKey) { + trigger2(target, "add", key, value); + } else if (shared.hasChanged(value, oldValue)) { + trigger2(target, "set", key, value, oldValue); + } + return this; + } + function deleteEntry(key) { + const target = toRaw2(this); + const { has: has2, get: get3 } = getProto(target); + let hadKey = has2.call(target, key); + if (!hadKey) { + key = toRaw2(key); + hadKey = has2.call(target, key); + } else { + checkIdentityKeys(target, has2, key); + } + const oldValue = get3 ? get3.call(target, key) : void 0; + const result = target.delete(key); + if (hadKey) { + trigger2(target, "delete", key, void 0, oldValue); + } + return result; + } + function clear() { + const target = toRaw2(this); + const hadItems = target.size !== 0; + const oldTarget = shared.isMap(target) ? new Map(target) : new Set(target); + const result = target.clear(); + if (hadItems) { + trigger2(target, "clear", void 0, void 0, oldTarget); + } + return result; + } + function createForEach(isReadonly2, isShallow) { + return function forEach(callback, thisArg) { + const observed = this; + const target = observed["__v_raw"]; + const rawTarget = toRaw2(target); + const wrap = isShallow ? toShallow : isReadonly2 ? toReadonly : toReactive; + !isReadonly2 && track2(rawTarget, "iterate", ITERATE_KEY); + return target.forEach((value, key) => { + return callback.call(thisArg, wrap(value), wrap(key), observed); + }); + }; + } + function createIterableMethod(method, isReadonly2, isShallow) { + return function(...args) { + const target = this["__v_raw"]; + const rawTarget = toRaw2(target); + const targetIsMap = shared.isMap(rawTarget); + const isPair = method === "entries" || method === Symbol.iterator && targetIsMap; + const isKeyOnly = method === "keys" && targetIsMap; + const innerIterator = target[method](...args); + const wrap = isShallow ? toShallow : isReadonly2 ? toReadonly : toReactive; + !isReadonly2 && track2(rawTarget, "iterate", isKeyOnly ? MAP_KEY_ITERATE_KEY : ITERATE_KEY); + return { + next() { + const { value, done } = innerIterator.next(); + return done ? { value, done } : { + value: isPair ? [wrap(value[0]), wrap(value[1])] : wrap(value), + done + }; + }, + [Symbol.iterator]() { + return this; + } + }; + }; + } + function createReadonlyMethod(type) { + return function(...args) { + { + const key = args[0] ? `on key "${args[0]}" ` : ``; + console.warn(`${shared.capitalize(type)} operation ${key}failed: target is readonly.`, toRaw2(this)); + } + return type === "delete" ? false : this; + }; + } + function createInstrumentations() { + const mutableInstrumentations2 = { + get(key) { + return get$1(this, key); + }, + get size() { + return size(this); + }, + has: has$1, + add, + set: set$1, + delete: deleteEntry, + clear, + forEach: createForEach(false, false) + }; + const shallowInstrumentations2 = { + get(key) { + return get$1(this, key, false, true); + }, + get size() { + return size(this); + }, + has: has$1, + add, + set: set$1, + delete: deleteEntry, + clear, + forEach: createForEach(false, true) + }; + const readonlyInstrumentations2 = { + get(key) { + return get$1(this, key, true); + }, + get size() { + return size(this, true); + }, + has(key) { + return has$1.call(this, key, true); + }, + add: createReadonlyMethod("add"), + set: createReadonlyMethod("set"), + delete: createReadonlyMethod("delete"), + clear: createReadonlyMethod("clear"), + forEach: createForEach(true, false) + }; + const shallowReadonlyInstrumentations2 = { + get(key) { + return get$1(this, key, true, true); + }, + get size() { + return size(this, true); + }, + has(key) { + return has$1.call(this, key, true); + }, + add: createReadonlyMethod("add"), + set: createReadonlyMethod("set"), + delete: createReadonlyMethod("delete"), + clear: createReadonlyMethod("clear"), + forEach: createForEach(true, true) + }; + const iteratorMethods = ["keys", "values", "entries", Symbol.iterator]; + iteratorMethods.forEach((method) => { + mutableInstrumentations2[method] = createIterableMethod(method, false, false); + readonlyInstrumentations2[method] = createIterableMethod(method, true, false); + shallowInstrumentations2[method] = createIterableMethod(method, false, true); + shallowReadonlyInstrumentations2[method] = createIterableMethod(method, true, true); + }); + return [ + mutableInstrumentations2, + readonlyInstrumentations2, + shallowInstrumentations2, + shallowReadonlyInstrumentations2 + ]; + } + var [mutableInstrumentations, readonlyInstrumentations, shallowInstrumentations, shallowReadonlyInstrumentations] = /* @__PURE__ */ createInstrumentations(); + function createInstrumentationGetter(isReadonly2, shallow) { + const instrumentations = shallow ? isReadonly2 ? shallowReadonlyInstrumentations : shallowInstrumentations : isReadonly2 ? readonlyInstrumentations : mutableInstrumentations; + return (target, key, receiver) => { + if (key === "__v_isReactive") { + return !isReadonly2; + } else if (key === "__v_isReadonly") { + return isReadonly2; + } else if (key === "__v_raw") { + return target; + } + return Reflect.get(shared.hasOwn(instrumentations, key) && key in target ? instrumentations : target, key, receiver); + }; + } + var mutableCollectionHandlers = { + get: /* @__PURE__ */ createInstrumentationGetter(false, false) + }; + var shallowCollectionHandlers = { + get: /* @__PURE__ */ createInstrumentationGetter(false, true) + }; + var readonlyCollectionHandlers = { + get: /* @__PURE__ */ createInstrumentationGetter(true, false) + }; + var shallowReadonlyCollectionHandlers = { + get: /* @__PURE__ */ createInstrumentationGetter(true, true) + }; + function checkIdentityKeys(target, has2, key) { + const rawKey = toRaw2(key); + if (rawKey !== key && has2.call(target, rawKey)) { + const type = shared.toRawType(target); + console.warn(`Reactive ${type} contains both the raw and reactive versions of the same object${type === `Map` ? ` as keys` : ``}, which can lead to inconsistencies. Avoid differentiating between the raw and reactive versions of an object and only use the reactive version if possible.`); + } + } + var reactiveMap = /* @__PURE__ */ new WeakMap(); + var shallowReactiveMap = /* @__PURE__ */ new WeakMap(); + var readonlyMap = /* @__PURE__ */ new WeakMap(); + var shallowReadonlyMap = /* @__PURE__ */ new WeakMap(); + function targetTypeMap(rawType) { + switch (rawType) { + case "Object": + case "Array": + return 1; + case "Map": + case "Set": + case "WeakMap": + case "WeakSet": + return 2; + default: + return 0; + } + } + function getTargetType(value) { + return value["__v_skip"] || !Object.isExtensible(value) ? 0 : targetTypeMap(shared.toRawType(value)); + } + function reactive3(target) { + if (target && target["__v_isReadonly"]) { + return target; + } + return createReactiveObject(target, false, mutableHandlers, mutableCollectionHandlers, reactiveMap); + } + function shallowReactive(target) { + return createReactiveObject(target, false, shallowReactiveHandlers, shallowCollectionHandlers, shallowReactiveMap); + } + function readonly(target) { + return createReactiveObject(target, true, readonlyHandlers, readonlyCollectionHandlers, readonlyMap); + } + function shallowReadonly(target) { + return createReactiveObject(target, true, shallowReadonlyHandlers, shallowReadonlyCollectionHandlers, shallowReadonlyMap); + } + function createReactiveObject(target, isReadonly2, baseHandlers, collectionHandlers, proxyMap) { + if (!shared.isObject(target)) { + { + console.warn(`value cannot be made reactive: ${String(target)}`); + } + return target; + } + if (target["__v_raw"] && !(isReadonly2 && target["__v_isReactive"])) { + return target; + } + const existingProxy = proxyMap.get(target); + if (existingProxy) { + return existingProxy; + } + const targetType = getTargetType(target); + if (targetType === 0) { + return target; + } + const proxy = new Proxy(target, targetType === 2 ? collectionHandlers : baseHandlers); + proxyMap.set(target, proxy); + return proxy; + } + function isReactive2(value) { + if (isReadonly(value)) { + return isReactive2(value["__v_raw"]); + } + return !!(value && value["__v_isReactive"]); + } + function isReadonly(value) { + return !!(value && value["__v_isReadonly"]); + } + function isProxy(value) { + return isReactive2(value) || isReadonly(value); + } + function toRaw2(observed) { + return observed && toRaw2(observed["__v_raw"]) || observed; + } + function markRaw(value) { + shared.def(value, "__v_skip", true); + return value; + } + var convert = (val) => shared.isObject(val) ? reactive3(val) : val; + function isRef(r) { + return Boolean(r && r.__v_isRef === true); + } + function ref(value) { + return createRef(value); + } + function shallowRef(value) { + return createRef(value, true); + } + var RefImpl = class { + constructor(value, _shallow = false) { + this._shallow = _shallow; + this.__v_isRef = true; + this._rawValue = _shallow ? value : toRaw2(value); + this._value = _shallow ? value : convert(value); + } + get value() { + track2(toRaw2(this), "get", "value"); + return this._value; + } + set value(newVal) { + newVal = this._shallow ? newVal : toRaw2(newVal); + if (shared.hasChanged(newVal, this._rawValue)) { + this._rawValue = newVal; + this._value = this._shallow ? newVal : convert(newVal); + trigger2(toRaw2(this), "set", "value", newVal); + } + } + }; + function createRef(rawValue, shallow = false) { + if (isRef(rawValue)) { + return rawValue; + } + return new RefImpl(rawValue, shallow); + } + function triggerRef(ref2) { + trigger2(toRaw2(ref2), "set", "value", ref2.value); + } + function unref(ref2) { + return isRef(ref2) ? ref2.value : ref2; + } + var shallowUnwrapHandlers = { + get: (target, key, receiver) => unref(Reflect.get(target, key, receiver)), + set: (target, key, value, receiver) => { + const oldValue = target[key]; + if (isRef(oldValue) && !isRef(value)) { + oldValue.value = value; + return true; + } else { + return Reflect.set(target, key, value, receiver); + } + } + }; + function proxyRefs(objectWithRefs) { + return isReactive2(objectWithRefs) ? objectWithRefs : new Proxy(objectWithRefs, shallowUnwrapHandlers); + } + var CustomRefImpl = class { + constructor(factory) { + this.__v_isRef = true; + const { get: get3, set: set3 } = factory(() => track2(this, "get", "value"), () => trigger2(this, "set", "value")); + this._get = get3; + this._set = set3; + } + get value() { + return this._get(); + } + set value(newVal) { + this._set(newVal); + } + }; + function customRef(factory) { + return new CustomRefImpl(factory); + } + function toRefs(object) { + if (!isProxy(object)) { + console.warn(`toRefs() expects a reactive object but received a plain one.`); + } + const ret = shared.isArray(object) ? new Array(object.length) : {}; + for (const key in object) { + ret[key] = toRef(object, key); + } + return ret; + } + var ObjectRefImpl = class { + constructor(_object, _key) { + this._object = _object; + this._key = _key; + this.__v_isRef = true; + } + get value() { + return this._object[this._key]; + } + set value(newVal) { + this._object[this._key] = newVal; + } + }; + function toRef(object, key) { + return isRef(object[key]) ? object[key] : new ObjectRefImpl(object, key); + } + var ComputedRefImpl = class { + constructor(getter, _setter, isReadonly2) { + this._setter = _setter; + this._dirty = true; + this.__v_isRef = true; + this.effect = effect3(getter, { + lazy: true, + scheduler: () => { + if (!this._dirty) { + this._dirty = true; + trigger2(toRaw2(this), "set", "value"); + } + } + }); + this["__v_isReadonly"] = isReadonly2; + } + get value() { + const self2 = toRaw2(this); + if (self2._dirty) { + self2._value = this.effect(); + self2._dirty = false; + } + track2(self2, "get", "value"); + return self2._value; + } + set value(newValue) { + this._setter(newValue); + } + }; + function computed(getterOrOptions) { + let getter; + let setter; + if (shared.isFunction(getterOrOptions)) { + getter = getterOrOptions; + setter = () => { + console.warn("Write operation failed: computed value is readonly"); + }; + } else { + getter = getterOrOptions.get; + setter = getterOrOptions.set; + } + return new ComputedRefImpl(getter, setter, shared.isFunction(getterOrOptions) || !getterOrOptions.set); + } + exports2.ITERATE_KEY = ITERATE_KEY; + exports2.computed = computed; + exports2.customRef = customRef; + exports2.effect = effect3; + exports2.enableTracking = enableTracking; + exports2.isProxy = isProxy; + exports2.isReactive = isReactive2; + exports2.isReadonly = isReadonly; + exports2.isRef = isRef; + exports2.markRaw = markRaw; + exports2.pauseTracking = pauseTracking; + exports2.proxyRefs = proxyRefs; + exports2.reactive = reactive3; + exports2.readonly = readonly; + exports2.ref = ref; + exports2.resetTracking = resetTracking; + exports2.shallowReactive = shallowReactive; + exports2.shallowReadonly = shallowReadonly; + exports2.shallowRef = shallowRef; + exports2.stop = stop2; + exports2.toRaw = toRaw2; + exports2.toRef = toRef; + exports2.toRefs = toRefs; + exports2.track = track2; + exports2.trigger = trigger2; + exports2.triggerRef = triggerRef; + exports2.unref = unref; + } + }); + var require_reactivity = __commonJS2({ + "node_modules/@vue/reactivity/index.js"(exports2, module2) { + "use strict"; + if (false) { + module2.exports = null; + } else { + module2.exports = require_reactivity_cjs(); + } + } + }); + var module_exports = {}; + __export(module_exports, { + Alpine: () => src_default, + default: () => module_default + }); + module.exports = __toCommonJS(module_exports); + var flushPending = false; + var flushing = false; + var queue = []; + var lastFlushedIndex = -1; + function scheduler(callback) { + queueJob(callback); + } + function queueJob(job) { + if (!queue.includes(job)) + queue.push(job); + queueFlush(); + } + function dequeueJob(job) { + let index = queue.indexOf(job); + if (index !== -1 && index > lastFlushedIndex) + queue.splice(index, 1); + } + function queueFlush() { + if (!flushing && !flushPending) { + flushPending = true; + queueMicrotask(flushJobs); + } + } + function flushJobs() { + flushPending = false; + flushing = true; + for (let i = 0; i < queue.length; i++) { + queue[i](); + lastFlushedIndex = i; + } + queue.length = 0; + lastFlushedIndex = -1; + flushing = false; + } + var reactive; + var effect; + var release; + var raw; + var shouldSchedule = true; + function disableEffectScheduling(callback) { + shouldSchedule = false; + callback(); + shouldSchedule = true; + } + function setReactivityEngine(engine) { + reactive = engine.reactive; + release = engine.release; + effect = (callback) => engine.effect(callback, { scheduler: (task) => { + if (shouldSchedule) { + scheduler(task); + } else { + task(); + } + } }); + raw = engine.raw; + } + function overrideEffect(override) { + effect = override; + } + function elementBoundEffect(el) { + let cleanup = () => { + }; + let wrappedEffect = (callback) => { + let effectReference = effect(callback); + if (!el._x_effects) { + el._x_effects = /* @__PURE__ */ new Set(); + el._x_runEffects = () => { + el._x_effects.forEach((i) => i()); + }; + } + el._x_effects.add(effectReference); + cleanup = () => { + if (effectReference === void 0) + return; + el._x_effects.delete(effectReference); + release(effectReference); + }; + return effectReference; + }; + return [wrappedEffect, () => { + cleanup(); + }]; + } + function watch(getter, callback) { + let firstTime = true; + let oldValue; + let effectReference = effect(() => { + let value = getter(); + JSON.stringify(value); + if (!firstTime) { + queueMicrotask(() => { + callback(value, oldValue); + oldValue = value; + }); + } else { + oldValue = value; + } + firstTime = false; + }); + return () => release(effectReference); + } + var onAttributeAddeds = []; + var onElRemoveds = []; + var onElAddeds = []; + function onElAdded(callback) { + onElAddeds.push(callback); + } + function onElRemoved(el, callback) { + if (typeof callback === "function") { + if (!el._x_cleanups) + el._x_cleanups = []; + el._x_cleanups.push(callback); + } else { + callback = el; + onElRemoveds.push(callback); + } + } + function onAttributesAdded(callback) { + onAttributeAddeds.push(callback); + } + function onAttributeRemoved(el, name, callback) { + if (!el._x_attributeCleanups) + el._x_attributeCleanups = {}; + if (!el._x_attributeCleanups[name]) + el._x_attributeCleanups[name] = []; + el._x_attributeCleanups[name].push(callback); + } + function cleanupAttributes(el, names) { + if (!el._x_attributeCleanups) + return; + Object.entries(el._x_attributeCleanups).forEach(([name, value]) => { + if (names === void 0 || names.includes(name)) { + value.forEach((i) => i()); + delete el._x_attributeCleanups[name]; + } + }); + } + function cleanupElement(el) { + var _a, _b; + (_a = el._x_effects) == null ? void 0 : _a.forEach(dequeueJob); + while ((_b = el._x_cleanups) == null ? void 0 : _b.length) + el._x_cleanups.pop()(); + } + var observer = new MutationObserver(onMutate); + var currentlyObserving = false; + function startObservingMutations() { + observer.observe(document, { subtree: true, childList: true, attributes: true, attributeOldValue: true }); + currentlyObserving = true; + } + function stopObservingMutations() { + flushObserver(); + observer.disconnect(); + currentlyObserving = false; + } + var queuedMutations = []; + function flushObserver() { + let records = observer.takeRecords(); + queuedMutations.push(() => records.length > 0 && onMutate(records)); + let queueLengthWhenTriggered = queuedMutations.length; + queueMicrotask(() => { + if (queuedMutations.length === queueLengthWhenTriggered) { + while (queuedMutations.length > 0) + queuedMutations.shift()(); + } + }); + } + function mutateDom(callback) { + if (!currentlyObserving) + return callback(); + stopObservingMutations(); + let result = callback(); + startObservingMutations(); + return result; + } + var isCollecting = false; + var deferredMutations = []; + function deferMutations() { + isCollecting = true; + } + function flushAndStopDeferringMutations() { + isCollecting = false; + onMutate(deferredMutations); + deferredMutations = []; + } + function onMutate(mutations) { + if (isCollecting) { + deferredMutations = deferredMutations.concat(mutations); + return; + } + let addedNodes = []; + let removedNodes = /* @__PURE__ */ new Set(); + let addedAttributes = /* @__PURE__ */ new Map(); + let removedAttributes = /* @__PURE__ */ new Map(); + for (let i = 0; i < mutations.length; i++) { + if (mutations[i].target._x_ignoreMutationObserver) + continue; + if (mutations[i].type === "childList") { + mutations[i].removedNodes.forEach((node) => { + if (node.nodeType !== 1) + return; + if (!node._x_marker) + return; + removedNodes.add(node); + }); + mutations[i].addedNodes.forEach((node) => { + if (node.nodeType !== 1) + return; + if (removedNodes.has(node)) { + removedNodes.delete(node); + return; + } + if (node._x_marker) + return; + addedNodes.push(node); + }); + } + if (mutations[i].type === "attributes") { + let el = mutations[i].target; + let name = mutations[i].attributeName; + let oldValue = mutations[i].oldValue; + let add = () => { + if (!addedAttributes.has(el)) + addedAttributes.set(el, []); + addedAttributes.get(el).push({ name, value: el.getAttribute(name) }); + }; + let remove = () => { + if (!removedAttributes.has(el)) + removedAttributes.set(el, []); + removedAttributes.get(el).push(name); + }; + if (el.hasAttribute(name) && oldValue === null) { + add(); + } else if (el.hasAttribute(name)) { + remove(); + add(); + } else { + remove(); + } + } + } + removedAttributes.forEach((attrs, el) => { + cleanupAttributes(el, attrs); + }); + addedAttributes.forEach((attrs, el) => { + onAttributeAddeds.forEach((i) => i(el, attrs)); + }); + for (let node of removedNodes) { + if (addedNodes.some((i) => i.contains(node))) + continue; + onElRemoveds.forEach((i) => i(node)); + } + for (let node of addedNodes) { + if (!node.isConnected) + continue; + onElAddeds.forEach((i) => i(node)); + } + addedNodes = null; + removedNodes = null; + addedAttributes = null; + removedAttributes = null; + } + function scope(node) { + return mergeProxies(closestDataStack(node)); + } + function addScopeToNode(node, data2, referenceNode) { + node._x_dataStack = [data2, ...closestDataStack(referenceNode || node)]; + return () => { + node._x_dataStack = node._x_dataStack.filter((i) => i !== data2); + }; + } + function closestDataStack(node) { + if (node._x_dataStack) + return node._x_dataStack; + if (typeof ShadowRoot === "function" && node instanceof ShadowRoot) { + return closestDataStack(node.host); + } + if (!node.parentNode) { + return []; + } + return closestDataStack(node.parentNode); + } + function mergeProxies(objects) { + return new Proxy({ objects }, mergeProxyTrap); + } + var mergeProxyTrap = { + ownKeys({ objects }) { + return Array.from(new Set(objects.flatMap((i) => Object.keys(i)))); + }, + has({ objects }, name) { + if (name == Symbol.unscopables) + return false; + return objects.some((obj) => Object.prototype.hasOwnProperty.call(obj, name) || Reflect.has(obj, name)); + }, + get({ objects }, name, thisProxy) { + if (name == "toJSON") + return collapseProxies; + return Reflect.get(objects.find((obj) => Reflect.has(obj, name)) || {}, name, thisProxy); + }, + set({ objects }, name, value, thisProxy) { + const target = objects.find((obj) => Object.prototype.hasOwnProperty.call(obj, name)) || objects[objects.length - 1]; + const descriptor = Object.getOwnPropertyDescriptor(target, name); + if ((descriptor == null ? void 0 : descriptor.set) && (descriptor == null ? void 0 : descriptor.get)) + return descriptor.set.call(thisProxy, value) || true; + return Reflect.set(target, name, value); + } + }; + function collapseProxies() { + let keys = Reflect.ownKeys(this); + return keys.reduce((acc, key) => { + acc[key] = Reflect.get(this, key); + return acc; + }, {}); + } + function initInterceptors(data2) { + let isObject2 = (val) => typeof val === "object" && !Array.isArray(val) && val !== null; + let recurse = (obj, basePath = "") => { + Object.entries(Object.getOwnPropertyDescriptors(obj)).forEach(([key, { value, enumerable }]) => { + if (enumerable === false || value === void 0) + return; + if (typeof value === "object" && value !== null && value.__v_skip) + return; + let path = basePath === "" ? key : `${basePath}.${key}`; + if (typeof value === "object" && value !== null && value._x_interceptor) { + obj[key] = value.initialize(data2, path, key); + } else { + if (isObject2(value) && value !== obj && !(value instanceof Element)) { + recurse(value, path); + } + } + }); + }; + return recurse(data2); + } + function interceptor(callback, mutateObj = () => { + }) { + let obj = { + initialValue: void 0, + _x_interceptor: true, + initialize(data2, path, key) { + return callback(this.initialValue, () => get(data2, path), (value) => set(data2, path, value), path, key); + } + }; + mutateObj(obj); + return (initialValue) => { + if (typeof initialValue === "object" && initialValue !== null && initialValue._x_interceptor) { + let initialize = obj.initialize.bind(obj); + obj.initialize = (data2, path, key) => { + let innerValue = initialValue.initialize(data2, path, key); + obj.initialValue = innerValue; + return initialize(data2, path, key); + }; + } else { + obj.initialValue = initialValue; + } + return obj; + }; + } + function get(obj, path) { + return path.split(".").reduce((carry, segment) => carry[segment], obj); + } + function set(obj, path, value) { + if (typeof path === "string") + path = path.split("."); + if (path.length === 1) + obj[path[0]] = value; + else if (path.length === 0) + throw error; + else { + if (obj[path[0]]) + return set(obj[path[0]], path.slice(1), value); + else { + obj[path[0]] = {}; + return set(obj[path[0]], path.slice(1), value); + } + } + } + var magics = {}; + function magic(name, callback) { + magics[name] = callback; + } + function injectMagics(obj, el) { + let memoizedUtilities = getUtilities(el); + Object.entries(magics).forEach(([name, callback]) => { + Object.defineProperty(obj, `$${name}`, { + get() { + return callback(el, memoizedUtilities); + }, + enumerable: false + }); + }); + return obj; + } + function getUtilities(el) { + let [utilities, cleanup] = getElementBoundUtilities(el); + let utils = { interceptor, ...utilities }; + onElRemoved(el, cleanup); + return utils; + } + function tryCatch(el, expression, callback, ...args) { + try { + return callback(...args); + } catch (e) { + handleError(e, el, expression); + } + } + function handleError(error2, el, expression = void 0) { + error2 = Object.assign(error2 != null ? error2 : { message: "No error message given." }, { el, expression }); + console.warn(`Alpine Expression Error: ${error2.message} + +${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); + setTimeout(() => { + throw error2; + }, 0); + } + var shouldAutoEvaluateFunctions = true; + function dontAutoEvaluateFunctions(callback) { + let cache = shouldAutoEvaluateFunctions; + shouldAutoEvaluateFunctions = false; + let result = callback(); + shouldAutoEvaluateFunctions = cache; + return result; + } + function evaluate(el, expression, extras = {}) { + let result; + evaluateLater(el, expression)((value) => result = value, extras); + return result; + } + function evaluateLater(...args) { + return theEvaluatorFunction(...args); + } + var theEvaluatorFunction = normalEvaluator; + function setEvaluator(newEvaluator) { + theEvaluatorFunction = newEvaluator; + } + function normalEvaluator(el, expression) { + let overriddenMagics = {}; + injectMagics(overriddenMagics, el); + let dataStack = [overriddenMagics, ...closestDataStack(el)]; + let evaluator = typeof expression === "function" ? generateEvaluatorFromFunction(dataStack, expression) : generateEvaluatorFromString(dataStack, expression, el); + return tryCatch.bind(null, el, expression, evaluator); + } + function generateEvaluatorFromFunction(dataStack, func) { + return (receiver = () => { + }, { scope: scope2 = {}, params = [] } = {}) => { + let result = func.apply(mergeProxies([scope2, ...dataStack]), params); + runIfTypeOfFunction(receiver, result); + }; + } + var evaluatorMemo = {}; + function generateFunctionFromString(expression, el) { + if (evaluatorMemo[expression]) { + return evaluatorMemo[expression]; + } + let AsyncFunction = Object.getPrototypeOf(async function() { + }).constructor; + let rightSideSafeExpression = /^[\n\s]*if.*\(.*\)/.test(expression.trim()) || /^(let|const)\s/.test(expression.trim()) ? `(async()=>{ ${expression} })()` : expression; + const safeAsyncFunction = () => { + try { + let func2 = new AsyncFunction(["__self", "scope"], `with (scope) { __self.result = ${rightSideSafeExpression} }; __self.finished = true; return __self.result;`); + Object.defineProperty(func2, "name", { + value: `[Alpine] ${expression}` + }); + return func2; + } catch (error2) { + handleError(error2, el, expression); + return Promise.resolve(); + } + }; + let func = safeAsyncFunction(); + evaluatorMemo[expression] = func; + return func; + } + function generateEvaluatorFromString(dataStack, expression, el) { + let func = generateFunctionFromString(expression, el); + return (receiver = () => { + }, { scope: scope2 = {}, params = [] } = {}) => { + func.result = void 0; + func.finished = false; + let completeScope = mergeProxies([scope2, ...dataStack]); + if (typeof func === "function") { + let promise = func(func, completeScope).catch((error2) => handleError(error2, el, expression)); + if (func.finished) { + runIfTypeOfFunction(receiver, func.result, completeScope, params, el); + func.result = void 0; + } else { + promise.then((result) => { + runIfTypeOfFunction(receiver, result, completeScope, params, el); + }).catch((error2) => handleError(error2, el, expression)).finally(() => func.result = void 0); + } + } + }; + } + function runIfTypeOfFunction(receiver, value, scope2, params, el) { + if (shouldAutoEvaluateFunctions && typeof value === "function") { + let result = value.apply(scope2, params); + if (result instanceof Promise) { + result.then((i) => runIfTypeOfFunction(receiver, i, scope2, params)).catch((error2) => handleError(error2, el, value)); + } else { + receiver(result); + } + } else if (typeof value === "object" && value instanceof Promise) { + value.then((i) => receiver(i)); + } else { + receiver(value); + } + } + var prefixAsString = "x-"; + function prefix(subject = "") { + return prefixAsString + subject; + } + function setPrefix(newPrefix) { + prefixAsString = newPrefix; + } + var directiveHandlers = {}; + function directive2(name, callback) { + directiveHandlers[name] = callback; + return { + before(directive22) { + if (!directiveHandlers[directive22]) { + console.warn(String.raw`Cannot find directive \`${directive22}\`. \`${name}\` will use the default order of execution`); + return; + } + const pos = directiveOrder.indexOf(directive22); + directiveOrder.splice(pos >= 0 ? pos : directiveOrder.indexOf("DEFAULT"), 0, name); + } + }; + } + function directiveExists(name) { + return Object.keys(directiveHandlers).includes(name); + } + function directives(el, attributes, originalAttributeOverride) { + attributes = Array.from(attributes); + if (el._x_virtualDirectives) { + let vAttributes = Object.entries(el._x_virtualDirectives).map(([name, value]) => ({ name, value })); + let staticAttributes = attributesOnly(vAttributes); + vAttributes = vAttributes.map((attribute) => { + if (staticAttributes.find((attr) => attr.name === attribute.name)) { + return { + name: `x-bind:${attribute.name}`, + value: `"${attribute.value}"` + }; + } + return attribute; + }); + attributes = attributes.concat(vAttributes); + } + let transformedAttributeMap = {}; + let directives2 = attributes.map(toTransformedAttributes((newName, oldName) => transformedAttributeMap[newName] = oldName)).filter(outNonAlpineAttributes).map(toParsedDirectives(transformedAttributeMap, originalAttributeOverride)).sort(byPriority); + return directives2.map((directive22) => { + return getDirectiveHandler(el, directive22); + }); + } + function attributesOnly(attributes) { + return Array.from(attributes).map(toTransformedAttributes()).filter((attr) => !outNonAlpineAttributes(attr)); + } + var isDeferringHandlers = false; + var directiveHandlerStacks = /* @__PURE__ */ new Map(); + var currentHandlerStackKey = Symbol(); + function deferHandlingDirectives(callback) { + isDeferringHandlers = true; + let key = Symbol(); + currentHandlerStackKey = key; + directiveHandlerStacks.set(key, []); + let flushHandlers = () => { + while (directiveHandlerStacks.get(key).length) + directiveHandlerStacks.get(key).shift()(); + directiveHandlerStacks.delete(key); + }; + let stopDeferring = () => { + isDeferringHandlers = false; + flushHandlers(); + }; + callback(flushHandlers); + stopDeferring(); + } + function getElementBoundUtilities(el) { + let cleanups2 = []; + let cleanup = (callback) => cleanups2.push(callback); + let [effect3, cleanupEffect] = elementBoundEffect(el); + cleanups2.push(cleanupEffect); + let utilities = { + Alpine: alpine_default, + effect: effect3, + cleanup, + evaluateLater: evaluateLater.bind(evaluateLater, el), + evaluate: evaluate.bind(evaluate, el) + }; + let doCleanup = () => cleanups2.forEach((i) => i()); + return [utilities, doCleanup]; + } + function getDirectiveHandler(el, directive22) { + let noop = () => { + }; + let handler4 = directiveHandlers[directive22.type] || noop; + let [utilities, cleanup] = getElementBoundUtilities(el); + onAttributeRemoved(el, directive22.original, cleanup); + let fullHandler = () => { + if (el._x_ignore || el._x_ignoreSelf) + return; + handler4.inline && handler4.inline(el, directive22, utilities); + handler4 = handler4.bind(handler4, el, directive22, utilities); + isDeferringHandlers ? directiveHandlerStacks.get(currentHandlerStackKey).push(handler4) : handler4(); + }; + fullHandler.runCleanups = cleanup; + return fullHandler; + } + var startingWith = (subject, replacement) => ({ name, value }) => { + if (name.startsWith(subject)) + name = name.replace(subject, replacement); + return { name, value }; + }; + var into = (i) => i; + function toTransformedAttributes(callback = () => { + }) { + return ({ name, value }) => { + let { name: newName, value: newValue } = attributeTransformers.reduce((carry, transform) => { + return transform(carry); + }, { name, value }); + if (newName !== name) + callback(newName, name); + return { name: newName, value: newValue }; + }; + } + var attributeTransformers = []; + function mapAttributes(callback) { + attributeTransformers.push(callback); + } + function outNonAlpineAttributes({ name }) { + return alpineAttributeRegex().test(name); + } + var alpineAttributeRegex = () => new RegExp(`^${prefixAsString}([^:^.]+)\\b`); + function toParsedDirectives(transformedAttributeMap, originalAttributeOverride) { + return ({ name, value }) => { + let typeMatch = name.match(alpineAttributeRegex()); + let valueMatch = name.match(/:([a-zA-Z0-9\-_:]+)/); + let modifiers = name.match(/\.[^.\]]+(?=[^\]]*$)/g) || []; + let original = originalAttributeOverride || transformedAttributeMap[name] || name; + return { + type: typeMatch ? typeMatch[1] : null, + value: valueMatch ? valueMatch[1] : null, + modifiers: modifiers.map((i) => i.replace(".", "")), + expression: value, + original + }; + }; + } + var DEFAULT = "DEFAULT"; + var directiveOrder = [ + "ignore", + "ref", + "data", + "id", + "anchor", + "bind", + "init", + "for", + "model", + "modelable", + "transition", + "show", + "if", + DEFAULT, + "teleport" + ]; + function byPriority(a, b) { + let typeA = directiveOrder.indexOf(a.type) === -1 ? DEFAULT : a.type; + let typeB = directiveOrder.indexOf(b.type) === -1 ? DEFAULT : b.type; + return directiveOrder.indexOf(typeA) - directiveOrder.indexOf(typeB); + } + function dispatch3(el, name, detail = {}) { + el.dispatchEvent(new CustomEvent(name, { + detail, + bubbles: true, + composed: true, + cancelable: true + })); + } + function walk(el, callback) { + if (typeof ShadowRoot === "function" && el instanceof ShadowRoot) { + Array.from(el.children).forEach((el2) => walk(el2, callback)); + return; + } + let skip = false; + callback(el, () => skip = true); + if (skip) + return; + let node = el.firstElementChild; + while (node) { + walk(node, callback, false); + node = node.nextElementSibling; + } + } + function warn(message, ...args) { + console.warn(`Alpine Warning: ${message}`, ...args); + } + var started = false; + function start2() { + if (started) + warn("Alpine has already been initialized on this page. Calling Alpine.start() more than once can cause problems."); + started = true; + if (!document.body) + warn("Unable to initialize. Trying to load Alpine before `
` is available. Did you forget to add `defer` in Alpine's `